From d71a398ff66c8c56533c99d9a5a80dc3f0e10915 Mon Sep 17 00:00:00 2001 From: Jan Schmidt Date: Thu, 1 Apr 2004 11:48:27 +0000 Subject: [PATCH] a52dec: Use a debug category, Output timestamps correctly Original commit message from CVS: a52dec: Use a debug category, Output timestamps correctly Emit tag info, Handle events, tell liba52dec about cpu capabilities so it can use MMX etc. dvdec: Fix a crasher accessing invalid memory dvdnavsrc:Some support for byte-format seeking. Small fixes for still frames and menu button overlays mpeg2dec: 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 navseek: Add the navseek debug element for seeking back and forth in a video stream using arrow keys. mpeg2subt:Pretty much a complete rewrite. Now a loopbased element. May still require work to properly synchronise subtitle buffers. mpegdemux: dvddemux: Don't attempt to create subbuffers of size 0 Reduce a couple of error outputs to warnings. y4mencode:Output the y4m frame header correctly --- ChangeLog | 57 ++++++++++++ ext/a52dec/gsta52dec.c | 112 ++++++++++++++--------- ext/a52dec/gsta52dec.h | 3 + ext/dvdnav/dvdnavsrc.c | 162 +++++++++++++--------------------- ext/mpeg2dec/gstmpeg2dec.c | 22 +++-- gst/mpegstream/gstdvddemux.c | 8 +- gst/mpegstream/gstmpegdemux.c | 2 +- 7 files changed, 212 insertions(+), 154 deletions(-) diff --git a/ChangeLog b/ChangeLog index 53ff97d5a5..7621d47fd6 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,60 @@ +2004-04-01 Jan Schmidt + + * 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 * gst/adder/gstadder.c: (gst_adder_get_type), (gst_adder_loop): diff --git a/ext/a52dec/gsta52dec.c b/ext/a52dec/gsta52dec.c index 7db4ac2960..9c626b083b 100644 --- a/ext/a52dec/gsta52dec.c +++ b/ext/a52dec/gsta52dec.c @@ -39,6 +39,8 @@ static GstElementDetails gst_a52dec_details = { "David I. Lehn ", }; +GST_DEBUG_CATEGORY_STATIC (a52dec_debug); +#define GST_CAT_DEFAULT (a52dec_debug) /* A52Dec signals and args */ enum @@ -109,6 +111,9 @@ gst_a52dec_get_type (void) 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; } @@ -161,6 +166,7 @@ gst_a52dec_init (GstA52Dec * a52dec) 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; } @@ -307,7 +313,7 @@ gst_a52dec_channels (int flags) static int gst_a52dec_push (GstPad * srcpad, int flags, sample_t * _samples, - gint64 timestamp) + GstClockTime timestamp) { GstBuffer *buf; int chans; @@ -369,34 +375,32 @@ gst_a52dec_handle_event (GstA52Dec * a52dec) 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; + GstTagList *taglist; - props = gst_props_empty_new (); + taglist = gst_tag_list_new (); - entry = gst_props_entry_new ("bitrate", GST_PROPS_INT (a52dec->bit_rate)); - gst_props_add_entry (props, (GstPropsEntry *) entry); + gst_tag_list_add (taglist, GST_TAG_MERGE_APPEND, + GST_TAG_BITRATE, (guint) a52dec->bit_rate, NULL); - gst_caps_unref (a52dec->streaminfo); - - 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) @@ -408,27 +412,31 @@ 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; - } - 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; + do { + gint skipped_bytes = 0; - /* FIXME this can potentially be an infinite loop, we might - * have to insert a yield operation here */ + 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; + } } + while (0); need_reneg = FALSE; @@ -441,6 +449,7 @@ gst_a52dec_loop (GstElement * element) if (bit_rate != a52dec->bit_rate) { a52dec->bit_rate = bit_rate; + gst_a52dec_update_streaminfo (a52dec); } /* read the header + rest of frame */ @@ -451,10 +460,12 @@ gst_a52dec_loop (GstElement * element) } 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 */ @@ -462,7 +473,7 @@ gst_a52dec_loop (GstElement * element) 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; } @@ -486,17 +497,21 @@ gst_a52dec_loop (GstElement * element) 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: @@ -507,13 +522,23 @@ static GstElementStateReturn 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; @@ -523,8 +548,11 @@ gst_a52dec_change_state (GstElement * element) 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; @@ -534,10 +562,10 @@ gst_a52dec_change_state (GstElement * element) 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; diff --git a/ext/a52dec/gsta52dec.h b/ext/a52dec/gsta52dec.h index 1796965f4e..eecbed5320 100644 --- a/ext/a52dec/gsta52dec.h +++ b/ext/a52dec/gsta52dec.h @@ -62,6 +62,9 @@ struct _GstA52Dec { GstClockTime last_ts; GstClockTime current_ts; + + GstClockTime last_timestamp; + GstClockTimeDiff last_diff; }; struct _GstA52DecClass { diff --git a/ext/dvdnav/dvdnavsrc.c b/ext/dvdnav/dvdnavsrc.c index 5b508cbdbc..f45b6bc5d7 100644 --- a/ext/dvdnav/dvdnavsrc.c +++ b/ext/dvdnav/dvdnavsrc.c @@ -39,6 +39,8 @@ 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 @@ -96,7 +98,7 @@ typedef enum 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 @@ -229,6 +231,9 @@ static const GstFormat *dvdnavsrc_get_formats (GstPad * pad); 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); @@ -361,7 +366,7 @@ dvdnavsrc_init (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); @@ -809,7 +814,7 @@ dvdnavsrc_set_domain (DVDNavSrc * src) static void dvdnavsrc_update_highlight (DVDNavSrc * src) { - int button; + int button = 0; pci_t *pci; dvdnav_highlight_area_t area; GstEvent *event; @@ -817,11 +822,16 @@ dvdnavsrc_update_highlight (DVDNavSrc * src) 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; @@ -856,6 +866,7 @@ dvdnavsrc_update_highlight (DVDNavSrc * src) src->button = button; + GST_DEBUG ("Sending dvd-spu-highlight for button %d", button); gst_pad_push (src->srcpad, GST_DATA (event)); } } @@ -1307,13 +1318,14 @@ dvdnavsrc_loop (GstElement * element) /* 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 @@ -1328,6 +1340,8 @@ dvdnavsrc_loop (GstElement * element) 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) { @@ -1336,10 +1350,13 @@ dvdnavsrc_loop (GstElement * element) 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. */ @@ -1595,12 +1612,7 @@ dvdnavsrc_get_event_mask (GstPad * pad) 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,} }; @@ -1629,6 +1641,8 @@ dvdnav_handle_navigation_event (DVDNavSrc * src, GstEvent * event) 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; @@ -1667,6 +1681,24 @@ dvdnavsrc_event (GstPad * pad, GstEvent * event) 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)) { @@ -1770,6 +1802,7 @@ dvdnavsrc_event (GstPad * pad, GstEvent * event) } case GST_EVENT_NAVIGATION: res = dvdnav_handle_navigation_event (src, event); + break; case GST_EVENT_FLUSH: src->need_flush = TRUE; break; @@ -1791,9 +1824,9 @@ dvdnavsrc_get_formats (GstPad * pad) { int i; static GstFormat formats[] = { + GST_FORMAT_BYTES, /* GST_FORMAT_TIME, - GST_FORMAT_BYTES, GST_FORMAT_DEFAULT, */ 0, /* filled later */ @@ -1817,7 +1850,6 @@ dvdnavsrc_get_formats (GstPad * pad) return formats; } -#if 0 static gboolean dvdnavsrc_convert (GstPad * pad, GstFormat src_format, gint64 src_value, @@ -1831,97 +1863,20 @@ dvdnavsrc_convert (GstPad * pad, 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; - 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 (*dest_format == sector_format) { + *dest_value = src_value / DVD_SECTOR_SIZE; + } else + return FALSE; + default: + 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) @@ -1959,6 +1914,11 @@ dvdnavsrc_query (GstPad * pad, GstQueryType type, 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) { diff --git a/ext/mpeg2dec/gstmpeg2dec.c b/ext/mpeg2dec/gstmpeg2dec.c index baa60fdc9e..a8f6ac98c5 100644 --- a/ext/mpeg2dec/gstmpeg2dec.c +++ b/ext/mpeg2dec/gstmpeg2dec.c @@ -40,6 +40,8 @@ typedef gint mpeg2_state_t; #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 = { @@ -148,6 +150,10 @@ gst_mpeg2dec_get_type (void) 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; } @@ -318,6 +324,8 @@ gst_mpeg2dec_alloc_buffer (GstMpeg2dec * mpeg2dec, const mpeg2_info_t * info, } gst_buffer_ref (outbuf); + + mpeg2_custom_fbuf (mpeg2dec->decoder, 1); mpeg2_set_buf (mpeg2dec->decoder, buf, outbuf); picture = info->current_picture; @@ -471,6 +479,7 @@ gst_mpeg2dec_chain (GstPad * pad, GstData * _data) 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; } @@ -496,17 +505,17 @@ gst_mpeg2dec_chain (GstPad * pad, GstData * _data) 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) { @@ -644,7 +653,6 @@ gst_mpeg2dec_chain (GstPad * pad, GstData * _data) 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 " : " "), @@ -659,7 +667,6 @@ gst_mpeg2dec_chain (GstPad * pad, GstData * _data) 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 || @@ -670,7 +677,10 @@ gst_mpeg2dec_chain (GstPad * pad, GstData * _data) 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); } diff --git a/gst/mpegstream/gstdvddemux.c b/gst/mpegstream/gstdvddemux.c index 98926e3951..daf86439ff 100644 --- a/gst/mpegstream/gstdvddemux.c +++ b/gst/mpegstream/gstdvddemux.c @@ -672,7 +672,7 @@ gst_dvd_demux_process_private (GstMPEGDemux * mpeg_demux, 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; @@ -696,8 +696,8 @@ gst_dvd_demux_process_private (GstMPEGDemux * mpeg_demux, 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; @@ -780,7 +780,7 @@ gst_dvd_demux_send_subbuffer (GstMPEGDemux * mpeg_demux, 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 diff --git a/gst/mpegstream/gstmpegdemux.c b/gst/mpegstream/gstmpegdemux.c index b63d7cd89a..b364040230 100644 --- a/gst/mpegstream/gstmpegdemux.c +++ b/gst/mpegstream/gstmpegdemux.c @@ -902,7 +902,7 @@ gst_mpeg_demux_send_subbuffer (GstMPEGDemux * mpeg_demux, 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; }