+2004-04-01 Jan Schmidt <thaytan@mad.scientist.com>
+
+ * ext/a52dec/gsta52dec.c: (gst_a52dec_get_type), (gst_a52dec_init),
+ (gst_a52dec_push), (gst_a52dec_handle_event),
+ (gst_a52dec_update_streaminfo), (gst_a52dec_loop),
+ (gst_a52dec_change_state):
+ * ext/a52dec/gsta52dec.h:
+ Use a debug category, Output timestamps correctly
+ Emit tag info, Handle events, tell liba52dec about cpu
+ capabilities so it can use MMX etc.
+ * ext/dv/gstdvdec.c: (gst_dvdec_loop), (gst_dvdec_change_state):
+ Fix a crasher accessing invalid memory
+ * ext/dvdnav/dvdnavsrc.c: (dvdnavsrc_init),
+ (dvdnavsrc_update_highlight), (dvdnavsrc_loop),
+ (dvdnavsrc_get_event_mask), (dvdnav_handle_navigation_event),
+ (dvdnavsrc_event), (dvdnavsrc_get_formats), (dvdnavsrc_convert),
+ (dvdnavsrc_query):
+ Some support for byte-format seeking.
+ Small fixes for still frames and menu button overlays
+ * ext/mpeg2dec/gstmpeg2dec.c: (gst_mpeg2dec_get_type),
+ (gst_mpeg2dec_alloc_buffer):
+ Use a debug category. Adjust the report level of several items to
+ LOG. Call mpeg2_custom_fbuf to mark our buffers as 'custom buffers'
+ so it doesn't lose the GstBuffer pointer
+ * gst/debug/Makefile.am:
+ * gst/debug/gstdebug.c: (plugin_init):
+ * gst/debug/gstnavseek.c: (gst_navseek_get_type),
+ (gst_navseek_base_init), (gst_navseek_class_init),
+ (gst_navseek_init), (gst_navseek_seek),
+ (gst_navseek_handle_src_event), (gst_navseek_set_property),
+ (gst_navseek_get_property), (gst_navseek_chain),
+ (gst_navseek_plugin_init):
+ * gst/debug/gstnavseek.h:
+ Add the navseek debug element for seeking back and forth in a
+ video stream using arrow keys.
+ * gst/mpeg2sub/gstmpeg2subt.c: (gst_mpeg2subt_get_type),
+ (gst_mpeg2subt_base_init), (gst_mpeg2subt_class_init),
+ (gst_mpeg2subt_init), (gst_mpeg2subt_finalize),
+ (gst_mpeg2subt_getcaps_video), (gst_mpeg2subt_link_video),
+ (gst_mpeg2subt_handle_video), (gst_mpeg2subt_src_event),
+ (gst_mpeg2subt_parse_header), (gst_get_nibble),
+ (gst_setup_palette), (gst_get_rle_code), (gst_draw_rle_line),
+ (gst_merge_uv_data), (gst_mpeg2subt_merge_title),
+ (gst_update_still_frame), (gst_mpeg2subt_handle_subtitle),
+ (gst_mpeg2subt_handle_dvd_event), (gst_mpeg2subt_loop):
+ * gst/mpeg2sub/gstmpeg2subt.h:
+ Pretty much a complete rewrite. Now a loopbased element. May still
+ require work to properly synchronise subtitle buffers.
+ * gst/mpegstream/gstdvddemux.c: (gst_dvd_demux_process_private),
+ (gst_dvd_demux_send_subbuffer):
+ * gst/mpegstream/gstmpegdemux.c: (gst_mpeg_demux_send_subbuffer):
+ Don't attempt to create subbuffers of size 0
+ Reduce a couple of error outputs to warnings.
+ * gst/y4m/gsty4mencode.c: (gst_y4mencode_sinkconnect),
+ (gst_y4mencode_chain):
+ Output the y4m frame header correctly.
+
2004-04-01 Thomas Vander Stichele <thomas at apestaart dot org>
* gst/adder/gstadder.c: (gst_adder_get_type), (gst_adder_loop):
"David I. Lehn <dlehn@users.sourceforge.net>",
};
+GST_DEBUG_CATEGORY_STATIC (a52dec_debug);
+#define GST_CAT_DEFAULT (a52dec_debug)
/* A52Dec signals and args */
enum
a52dec_type =
g_type_register_static (GST_TYPE_ELEMENT, "GstA52Dec", &a52dec_info, 0);
+
+ GST_DEBUG_CATEGORY_INIT (a52dec_debug, "a52dec", 0,
+ "AC3/A52 software decoder");
}
return a52dec_type;
}
gst_pad_use_explicit_caps (a52dec->srcpad);
gst_element_add_pad (GST_ELEMENT (a52dec), a52dec->srcpad);
+ GST_FLAG_SET (GST_ELEMENT (a52dec), GST_ELEMENT_EVENT_AWARE);
a52dec->dynamic_range_compression = FALSE;
}
static int
gst_a52dec_push (GstPad * srcpad, int flags, sample_t * _samples,
- gint64 timestamp)
+ GstClockTime timestamp)
{
GstBuffer *buf;
int chans;
return;
}
+ GST_LOG ("Handling event of type %d timestamp %llu", GST_EVENT_TYPE (event),
+ GST_EVENT_TIMESTAMP (event));
switch (GST_EVENT_TYPE (event)) {
case GST_EVENT_DISCONTINUOUS:
+ case GST_EVENT_FLUSH:
gst_bytestream_flush_fast (a52dec->bs, remaining);
+ break;
default:
- gst_pad_event_default (a52dec->sinkpad, event);
break;
}
+ gst_pad_event_default (a52dec->sinkpad, event);
}
-#if 0
static void
gst_a52dec_update_streaminfo (GstA52Dec * a52dec)
{
- GstProps *props;
- GstPropsEntry *entry;
-
- props = gst_props_empty_new ();
+ GstTagList *taglist;
- entry = gst_props_entry_new ("bitrate", GST_PROPS_INT (a52dec->bit_rate));
- gst_props_add_entry (props, (GstPropsEntry *) entry);
+ taglist = gst_tag_list_new ();
- gst_caps_unref (a52dec->streaminfo);
+ gst_tag_list_add (taglist, GST_TAG_MERGE_APPEND,
+ GST_TAG_BITRATE, (guint) a52dec->bit_rate, NULL);
- a52dec->streaminfo = gst_caps_new ("a52dec_streaminfo",
- "application/x-gst-streaminfo", props);
- g_object_notify (G_OBJECT (a52dec), "streaminfo");
+ gst_element_found_tags_for_pad (GST_ELEMENT (a52dec),
+ GST_PAD (a52dec->srcpad), a52dec->current_ts, taglist);
}
-#endif
static void
gst_a52dec_loop (GstElement * element)
GstBuffer *buf;
guint32 got_bytes;
gboolean need_reneg;
- GstClockTime timestamp;
+ GstClockTime timestamp = 0;
a52dec = GST_A52DEC (element);
/* find and read header */
- while (1) {
- got_bytes = gst_bytestream_peek_bytes (a52dec->bs, &data, 7);
- if (got_bytes < 7) {
- gst_a52dec_handle_event (a52dec);
- return;
+ do {
+ gint skipped_bytes = 0;
+
+ while (skipped_bytes < 3840) {
+ got_bytes = gst_bytestream_peek_bytes (a52dec->bs, &data, 7);
+ if (got_bytes < 7) {
+ gst_a52dec_handle_event (a52dec);
+ return;
+ }
+ length = a52_syncinfo (data, &flags, &sample_rate, &bit_rate);
+ if (length == 0) {
+ /* slide window to next 7 bytesa */
+ gst_bytestream_flush_fast (a52dec->bs, 1);
+ skipped_bytes++;
+ GST_LOG ("Skipped");
+ } else
+ break;
}
- length = a52_syncinfo (data, &flags, &sample_rate, &bit_rate);
- if (length == 0) {
- /* slide window to next 7 bytesa */
- gst_bytestream_flush_fast (a52dec->bs, 1);
- } else
- break;
-
- /* FIXME this can potentially be an infinite loop, we might
- * have to insert a yield operation here */
}
+ while (0);
need_reneg = FALSE;
if (bit_rate != a52dec->bit_rate) {
a52dec->bit_rate = bit_rate;
+ gst_a52dec_update_streaminfo (a52dec);
}
/* read the header + rest of frame */
}
data = GST_BUFFER_DATA (buf);
timestamp = gst_bytestream_get_timestamp (a52dec->bs);
- if (timestamp == a52dec->last_ts) {
- timestamp = a52dec->current_ts;
- } else {
- a52dec->last_ts = timestamp;
+ if (GST_CLOCK_TIME_IS_VALID (timestamp)) {
+ if (timestamp == a52dec->last_ts) {
+ timestamp = a52dec->current_ts;
+ } else {
+ a52dec->last_ts = timestamp;
+ }
}
/* process */
a52dec->level = 1;
if (a52_frame (a52dec->state, data, &flags, &a52dec->level, a52dec->bias)) {
- g_warning ("a52dec: a52_frame error\n");
+ GST_WARNING ("a52_frame error");
goto end;
}
for (i = 0; i < 6; i++) {
if (a52_block (a52dec->state)) {
- g_warning ("a52dec a52_block error %d\n", i);
+ GST_WARNING ("a52_block error %d", i);
continue;
}
/* push on */
+
if (gst_a52dec_push (a52dec->srcpad, a52dec->using_channels,
a52dec->samples, timestamp)) {
- g_warning ("a52dec push error\n");
+ GST_WARNING ("a52dec push error");
} else {
- timestamp += sizeof (int16_t) * 256 * GST_SECOND / a52dec->sample_rate;
+
+ if (i % 2)
+ timestamp += 256 * GST_SECOND / a52dec->sample_rate;
}
}
+
a52dec->current_ts = timestamp;
end:
gst_a52dec_change_state (GstElement * element)
{
GstA52Dec *a52dec = GST_A52DEC (element);
+ GstCPUFlags cpuflags;
+ uint32_t a52_cpuflags = 0;
switch (GST_STATE_TRANSITION (element)) {
case GST_STATE_NULL_TO_READY:
+ a52dec->bs = gst_bytestream_new (a52dec->sinkpad);
+ cpuflags = gst_cpu_get_flags ();
+ if (cpuflags & GST_CPU_FLAG_MMX)
+ a52_cpuflags |= MM_ACCEL_X86_MMX;
+ if (cpuflags & GST_CPU_FLAG_3DNOW)
+ a52_cpuflags |= MM_ACCEL_X86_3DNOW;
+ if (cpuflags & GST_CPU_FLAG_MMXEXT)
+ a52_cpuflags |= MM_ACCEL_X86_MMXEXT;
+
+ a52dec->state = a52_init (a52_cpuflags);
break;
case GST_STATE_READY_TO_PAUSED:
- a52dec->bs = gst_bytestream_new (a52dec->sinkpad);
- a52dec->state = a52_init (0); /* mm_accel()); */
a52dec->samples = a52_samples (a52dec->state);
a52dec->bit_rate = -1;
a52dec->sample_rate = -1;
a52dec->using_channels = A52_CHANNEL;
a52dec->level = 1;
a52dec->bias = 384;
- a52dec->last_ts = -1;
+ a52dec->last_ts = 0;
a52dec->current_ts = 0;
+ a52dec->last_timestamp = 0;
+ a52dec->last_diff = 0;
+
break;
case GST_STATE_PAUSED_TO_PLAYING:
break;
gst_bytestream_destroy (a52dec->bs);
a52dec->bs = NULL;
a52dec->samples = NULL;
- a52_free (a52dec->state);
- a52dec->state = NULL;
break;
case GST_STATE_READY_TO_NULL:
+ a52_free (a52dec->state);
+ a52dec->state = NULL;
break;
default:
break;
GstClockTime last_ts;
GstClockTime current_ts;
+
+ GstClockTime last_timestamp;
+ GstClockTimeDiff last_diff;
};
struct _GstA52DecClass {
GST_DEBUG_CATEGORY_STATIC (dvdnavsrc_debug);
#define GST_CAT_DEFAULT (dvdnavsrc_debug)
+/* Size of a DVD sector, used for sector-byte format conversions */
+#define DVD_SECTOR_SIZE 2048
#define CLOCK_BASE 9LL
#define CLOCK_FREQ CLOCK_BASE * 10000
DVDNavSrcPauseMode;
/* Interval of time to sleep during pauses. */
-#define DVDNAVSRC_PAUSE_INTERVAL (GST_SECOND / 5)
+#define DVDNAVSRC_PAUSE_INTERVAL (GST_SECOND / 20)
/* The DVD domain types. */
typedef enum
static gboolean dvdnavsrc_query (GstPad * pad,
GstQueryType type, GstFormat * format, gint64 * value);
static const GstQueryType *dvdnavsrc_get_query_types (GstPad * pad);
+static gboolean dvdnavsrc_convert (GstPad * pad,
+ GstFormat src_format, gint64 src_value,
+ GstFormat * dest_format, gint64 * dest_value);
static gboolean dvdnavsrc_close (DVDNavSrc * src);
static gboolean dvdnavsrc_open (DVDNavSrc * src);
gst_pad_set_event_function (src->srcpad, dvdnavsrc_event);
gst_pad_set_event_mask_function (src->srcpad, dvdnavsrc_get_event_mask);
- /*gst_pad_set_convert_function (src->srcpad, dvdnavsrc_convert); */
+ gst_pad_set_convert_function (src->srcpad, dvdnavsrc_convert);
gst_pad_set_query_function (src->srcpad, dvdnavsrc_query);
gst_pad_set_query_type_function (src->srcpad, dvdnavsrc_get_query_types);
gst_pad_set_formats_function (src->srcpad, dvdnavsrc_get_formats);
static void
dvdnavsrc_update_highlight (DVDNavSrc * src)
{
- int button;
+ int button = 0;
pci_t *pci;
dvdnav_highlight_area_t area;
GstEvent *event;
DVDNAV_CALL (dvdnav_get_current_highlight, (src->dvdnav, &button), src);
pci = dvdnav_get_current_nav_pci (src->dvdnav);
- if (button > pci->hli.hl_gi.btn_ns) {
+ if ((button > pci->hli.hl_gi.btn_ns) || (button < 0)) {
/* button is out of the range of possible buttons. */
button = 0;
}
+ if (!pci->hli.hl_gi.hli_ss) {
+ /* Not in menu */
+ button = 0;
+ }
+
if (button == 0) {
if (src->button != 0) {
src->button = 0;
src->button = button;
+ GST_DEBUG ("Sending dvd-spu-highlight for button %d", button);
gst_pad_push (src->srcpad, GST_DATA (event));
}
}
/* We just saw a still frame. Start a pause now. */
if (info->length == 0xff) {
- GST_INFO_OBJECT (src, "starting unlimed pause");
+ GST_INFO_OBJECT (src, "starting unlimited pause");
src->pause_mode = DVDNAVSRC_PAUSE_UNLIMITED;
} else {
- GST_INFO_OBJECT (src, "starting limited pause: %d seconds",
- info->length);
src->pause_mode = DVDNAVSRC_PAUSE_LIMITED;
src->pause_end = current_time + info->length * GST_SECOND;
+ GST_INFO_OBJECT (src,
+ "starting limited pause: %d seconds at %llu until %llu",
+ info->length, current_time, src->pause_end);
}
/* For the moment, send the first empty event to let
if (src->pause_mode == DVDNAVSRC_PAUSE_UNLIMITED ||
current_time < src->pause_end) {
+ GstEvent *event;
+
/* We are in pause mode. Make this element sleep for a
fraction of a second. */
if (current_time + DVDNAVSRC_PAUSE_INTERVAL > src->pause_end) {
gst_element_wait (GST_ELEMENT (src),
current_time + DVDNAVSRC_PAUSE_INTERVAL);
}
-
/* Send an empty event to keep the pipeline going. */
/* FIXME: Use an interrupt/filler event here. */
- send_data = GST_DATA (gst_event_new (GST_EVENT_EMPTY));
+ event = gst_event_new (GST_EVENT_EMPTY);
+ send_data = GST_DATA (event);
+ GST_EVENT_TIMESTAMP (event) =
+ gst_element_get_time (GST_ELEMENT (src));
+
break;
} else {
/* We reached the end of the pause. */
static const GstEventMask masks[] = {
{GST_EVENT_SEEK, GST_SEEK_METHOD_SET |
GST_SEEK_METHOD_CUR | GST_SEEK_METHOD_END | GST_SEEK_FLAG_FLUSH},
- /*
- {GST_EVENT_SEEK_SEGMENT, GST_SEEK_METHOD_SET |
- GST_SEEK_METHOD_CUR |
- GST_SEEK_METHOD_END |
- GST_SEEK_FLAG_FLUSH },
- */
+ {GST_EVENT_FLUSH, 0},
{GST_EVENT_NAVIGATION, GST_EVENT_FLAG_NONE},
{0,}
};
dvdnav_mouse_select (src->dvdnav,
dvdnav_get_current_nav_pci (src->dvdnav), (int) x, (int) y);
+
+ dvdnavsrc_update_highlight (src);
} else if (strcmp (event_type, "mouse-button-release") == 0) {
double x, y;
offset = GST_EVENT_SEEK_OFFSET (event);
switch (format) {
+ case GST_FORMAT_BYTES:
+ switch (GST_EVENT_SEEK_METHOD (event)) {
+ case GST_SEEK_METHOD_SET:
+ origin = SEEK_SET;
+ break;
+ case GST_SEEK_METHOD_CUR:
+ origin = SEEK_CUR;
+ break;
+ case GST_SEEK_METHOD_END:
+ origin = SEEK_END;
+ break;
+ default:
+ goto error;
+ }
+ if (dvdnav_sector_search (src->dvdnav, (offset / DVD_SECTOR_SIZE),
+ origin) != DVDNAV_STATUS_OK) {
+ goto error;
+ }
default:
if (format == sector_format) {
switch (GST_EVENT_SEEK_METHOD (event)) {
}
case GST_EVENT_NAVIGATION:
res = dvdnav_handle_navigation_event (src, event);
+ break;
case GST_EVENT_FLUSH:
src->need_flush = TRUE;
break;
{
int i;
static GstFormat formats[] = {
+ GST_FORMAT_BYTES,
/*
GST_FORMAT_TIME,
- GST_FORMAT_BYTES,
GST_FORMAT_DEFAULT,
*/
0, /* filled later */
return formats;
}
-#if 0
static gboolean
dvdnavsrc_convert (GstPad * pad,
GstFormat src_format, gint64 src_value,
return FALSE;
switch (src_format) {
- case GST_FORMAT_TIME:
- switch (*dest_format) {
- case GST_FORMAT_BYTES:
- src_value <<= 2; /* 4 bytes per sample */
- case GST_FORMAT_DEFAULT:
- *dest_value = src_value * 44100 / GST_SECOND;
- break;
- default:
- if (*dest_format == track_format || *dest_format == sector_format) {
- gint sector =
- (src_value * 44100) / ((CD_FRAMESIZE_RAW >> 2) * GST_SECOND);
-
- if (*dest_format == sector_format) {
- *dest_value = sector;
- } else {
- *dest_value = cdda_sector_gettrack (src->d, sector) - 1;
- }
- } else
- return FALSE;
- break;
- }
- break;
case GST_FORMAT_BYTES:
- src_value >>= 2;
- case GST_FORMAT_DEFAULT:
- switch (*dest_format) {
- case GST_FORMAT_BYTES:
- *dest_value = src_value * 4;
- break;
- case GST_FORMAT_TIME:
- *dest_value = src_value * GST_SECOND / 44100;
- break;
- default:
- if (*dest_format == track_format || *dest_format == sector_format) {
- gint sector = src_value / (CD_FRAMESIZE_RAW >> 2);
-
- if (*dest_format == track_format) {
- *dest_value = cdda_sector_gettrack (src->d, sector) - 1;
- } else {
- *dest_value = sector;
- }
- } else
- return FALSE;
- break;
- }
- break;
+ if (*dest_format == sector_format) {
+ *dest_value = src_value / DVD_SECTOR_SIZE;
+ } else
+ return FALSE;
default:
- {
- gint sector;
-
- if (src_format == track_format) {
- /* some sanity checks */
- if (src_value < 0 || src_value > src->d->tracks)
- return FALSE;
-
- sector = cdda_track_firstsector (src->d, src_value + 1);
- } else if (src_format == sector_format) {
- sector = src_value;
+ if ((src_format == sector_format) && (*dest_format == GST_FORMAT_BYTES)) {
+ *dest_value = src_value * DVD_SECTOR_SIZE;
} else
return FALSE;
-
- switch (*dest_format) {
- case GST_FORMAT_TIME:
- *dest_value = ((CD_FRAMESIZE_RAW >> 2) * sector * GST_SECOND) / 44100;
- break;
- case GST_FORMAT_BYTES:
- sector <<= 2;
- case GST_FORMAT_DEFAULT:
- *dest_value = (CD_FRAMESIZE_RAW >> 2) * sector;
- break;
- default:
- if (*dest_format == sector_format) {
- *dest_value = sector;
- } else if (*dest_format == track_format) {
- /* if we go past the last sector, make sure to report the
- last track */
- if (sector > src->last_sector)
- *dest_value = cdda_sector_gettrack (src->d, src->last_sector);
- else
- *dest_value = cdda_sector_gettrack (src->d, sector) - 1;
- } else
- return FALSE;
- break;
- }
- break;
- }
}
return TRUE;
}
-#endif
static const GstQueryType *
dvdnavsrc_get_query_types (GstPad * pad)
res = FALSE;
}
*value = len;
+ } else if (*format == GST_FORMAT_BYTES) {
+ if (dvdnav_get_position (src->dvdnav, &pos, &len) != DVDNAV_STATUS_OK) {
+ res = FALSE;
+ }
+ *value = len * DVD_SECTOR_SIZE;
} else if (*format == title_format) {
if (dvdnav_get_number_of_titles (src->dvdnav, &titles)
!= DVDNAV_STATUS_OK) {
#endif
GST_DEBUG_CATEGORY_EXTERN (GST_CAT_SEEK);
+GST_DEBUG_CATEGORY_STATIC (mpeg2dec_debug);
+#define GST_CAT_DEFAULT (mpeg2dec_debug)
/* elementfactory information */
static GstElementDetails gst_mpeg2dec_details = {
g_type_register_static (GST_TYPE_ELEMENT, "GstMpeg2dec", &mpeg2dec_info,
0);
}
+
+ GST_DEBUG_CATEGORY_INIT (mpeg2dec_debug, "mpeg2dec", 0,
+ "MPEG2 decoder element");
+
return mpeg2dec_type;
}
}
gst_buffer_ref (outbuf);
+
+ mpeg2_custom_fbuf (mpeg2dec->decoder, 1);
mpeg2_set_buf (mpeg2dec->decoder, buf, outbuf);
picture = info->current_picture;
gst_index_commit (mpeg2dec->index, mpeg2dec->index_id);
}
default:
+ GST_DEBUG ("Got event of type %d on sink pad", GST_EVENT_TYPE (event));
gst_pad_event_default (pad, event);
return;
}
mpeg2_pts (mpeg2dec->decoder, mpeg_pts);
#endif
} else {
- GST_DEBUG ("no pts");
+ GST_LOG ("no pts");
}
- GST_DEBUG ("calling _buffer");
+ GST_LOG ("calling mpeg2_buffer");
mpeg2_buffer (mpeg2dec->decoder, data, end);
- GST_DEBUG ("calling _buffer done");
+ GST_LOG ("calling mpeg2_buffer done");
while (!done) {
gboolean slice = FALSE;
- GST_DEBUG ("calling parse");
+ GST_LOG ("calling parse");
state = mpeg2_parse (mpeg2dec->decoder);
GST_DEBUG ("parse state %d", state);
switch (state) {
mpeg2dec->next_time +=
(mpeg2dec->frame_period * picture->nb_fields) >> 1;
-
GST_DEBUG ("picture: %s %s fields:%d off:%" G_GINT64_FORMAT " ts:%"
G_GINT64_FORMAT,
(picture->flags & PIC_FLAG_TOP_FIELD_FIRST ? "tff " : " "),
GST_FORMAT_TIME, GST_BUFFER_TIMESTAMP (outbuf), 0);
}
-
if (picture->flags & PIC_FLAG_SKIP ||
!GST_PAD_IS_USABLE (mpeg2dec->srcpad) ||
mpeg2dec->discont_state != MPEG2DEC_DISC_NONE ||
GST_BUFFER_DURATION (outbuf) = mpeg2dec->frame_period;
gst_pad_push (mpeg2dec->srcpad, GST_DATA (outbuf));
}
+ } else if (info->display_fbuf && !info->display_fbuf->id) {
+ GST_WARNING ("Got a frame from libmpeg2, but it has no buffer");
}
+
if (info->discard_fbuf && info->discard_fbuf->id) {
gst_buffer_unref ((GstBuffer *) info->discard_fbuf->id);
}
headerlen += 1;
datalen -= 1;
} else {
- GST_ERROR_OBJECT (dvd_demux,
+ GST_WARNING_OBJECT (dvd_demux,
"unknown DVD (private 1) id 0x%02x", ps_id_code);
}
break;
break;
default:
- GST_ERROR_OBJECT (dvd_demux,
- "unknown DVD (private 1) id 0x%02x", ps_id_code);
+ GST_WARNING_OBJECT (dvd_demux,
+ "unknown DVD (private 2) id 0x%02x", ps_id_code);
break;
}
break;
break;
}
- if (outpad != NULL && cur_nr == outstream->number) {
+ if (outpad != NULL && cur_nr == outstream->number && (size > 0)) {
GstBuffer *outbuf;
/* We have a packet of the current stream. Send it to the
GST_BUFFER_OFFSET (buffer), GST_FORMAT_TIME, timestamp, 0);
}
- if (!GST_PAD_IS_USABLE (outstream->pad)) {
+ if (!GST_PAD_IS_USABLE (outstream->pad) || (size == 0)) {
return;
}