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
This commit is contained in:
Jan Schmidt 2004-04-01 11:48:27 +00:00
parent ddd5093ee6
commit d71a398ff6
7 changed files with 212 additions and 154 deletions

View File

@ -1,3 +1,60 @@
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> 2004-04-01 Thomas Vander Stichele <thomas at apestaart dot org>
* gst/adder/gstadder.c: (gst_adder_get_type), (gst_adder_loop): * gst/adder/gstadder.c: (gst_adder_get_type), (gst_adder_loop):

View File

@ -39,6 +39,8 @@ static GstElementDetails gst_a52dec_details = {
"David I. Lehn <dlehn@users.sourceforge.net>", "David I. Lehn <dlehn@users.sourceforge.net>",
}; };
GST_DEBUG_CATEGORY_STATIC (a52dec_debug);
#define GST_CAT_DEFAULT (a52dec_debug)
/* A52Dec signals and args */ /* A52Dec signals and args */
enum enum
@ -109,6 +111,9 @@ gst_a52dec_get_type (void)
a52dec_type = a52dec_type =
g_type_register_static (GST_TYPE_ELEMENT, "GstA52Dec", &a52dec_info, 0); 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; return a52dec_type;
} }
@ -161,6 +166,7 @@ gst_a52dec_init (GstA52Dec * a52dec)
gst_pad_use_explicit_caps (a52dec->srcpad); gst_pad_use_explicit_caps (a52dec->srcpad);
gst_element_add_pad (GST_ELEMENT (a52dec), 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; a52dec->dynamic_range_compression = FALSE;
} }
@ -307,7 +313,7 @@ gst_a52dec_channels (int flags)
static int static int
gst_a52dec_push (GstPad * srcpad, int flags, sample_t * _samples, gst_a52dec_push (GstPad * srcpad, int flags, sample_t * _samples,
gint64 timestamp) GstClockTime timestamp)
{ {
GstBuffer *buf; GstBuffer *buf;
int chans; int chans;
@ -369,34 +375,32 @@ gst_a52dec_handle_event (GstA52Dec * a52dec)
return; return;
} }
GST_LOG ("Handling event of type %d timestamp %llu", GST_EVENT_TYPE (event),
GST_EVENT_TIMESTAMP (event));
switch (GST_EVENT_TYPE (event)) { switch (GST_EVENT_TYPE (event)) {
case GST_EVENT_DISCONTINUOUS: case GST_EVENT_DISCONTINUOUS:
case GST_EVENT_FLUSH:
gst_bytestream_flush_fast (a52dec->bs, remaining); gst_bytestream_flush_fast (a52dec->bs, remaining);
break;
default: default:
gst_pad_event_default (a52dec->sinkpad, event);
break; break;
} }
gst_pad_event_default (a52dec->sinkpad, event);
} }
#if 0
static void static void
gst_a52dec_update_streaminfo (GstA52Dec * a52dec) gst_a52dec_update_streaminfo (GstA52Dec * a52dec)
{ {
GstProps *props; GstTagList *taglist;
GstPropsEntry *entry;
props = gst_props_empty_new (); taglist = gst_tag_list_new ();
entry = gst_props_entry_new ("bitrate", GST_PROPS_INT (a52dec->bit_rate)); gst_tag_list_add (taglist, GST_TAG_MERGE_APPEND,
gst_props_add_entry (props, (GstPropsEntry *) entry); GST_TAG_BITRATE, (guint) a52dec->bit_rate, NULL);
gst_caps_unref (a52dec->streaminfo); gst_element_found_tags_for_pad (GST_ELEMENT (a52dec),
GST_PAD (a52dec->srcpad), a52dec->current_ts, taglist);
a52dec->streaminfo = gst_caps_new ("a52dec_streaminfo",
"application/x-gst-streaminfo", props);
g_object_notify (G_OBJECT (a52dec), "streaminfo");
} }
#endif
static void static void
gst_a52dec_loop (GstElement * element) gst_a52dec_loop (GstElement * element)
@ -408,27 +412,31 @@ gst_a52dec_loop (GstElement * element)
GstBuffer *buf; GstBuffer *buf;
guint32 got_bytes; guint32 got_bytes;
gboolean need_reneg; gboolean need_reneg;
GstClockTime timestamp; GstClockTime timestamp = 0;
a52dec = GST_A52DEC (element); a52dec = GST_A52DEC (element);
/* find and read header */ /* find and read header */
while (1) { do {
got_bytes = gst_bytestream_peek_bytes (a52dec->bs, &data, 7); gint skipped_bytes = 0;
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;
/* FIXME this can potentially be an infinite loop, we might while (skipped_bytes < 3840) {
* have to insert a yield operation here */ 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; need_reneg = FALSE;
@ -441,6 +449,7 @@ gst_a52dec_loop (GstElement * element)
if (bit_rate != a52dec->bit_rate) { if (bit_rate != a52dec->bit_rate) {
a52dec->bit_rate = bit_rate; a52dec->bit_rate = bit_rate;
gst_a52dec_update_streaminfo (a52dec);
} }
/* read the header + rest of frame */ /* read the header + rest of frame */
@ -451,10 +460,12 @@ gst_a52dec_loop (GstElement * element)
} }
data = GST_BUFFER_DATA (buf); data = GST_BUFFER_DATA (buf);
timestamp = gst_bytestream_get_timestamp (a52dec->bs); timestamp = gst_bytestream_get_timestamp (a52dec->bs);
if (timestamp == a52dec->last_ts) { if (GST_CLOCK_TIME_IS_VALID (timestamp)) {
timestamp = a52dec->current_ts; if (timestamp == a52dec->last_ts) {
} else { timestamp = a52dec->current_ts;
a52dec->last_ts = timestamp; } else {
a52dec->last_ts = timestamp;
}
} }
/* process */ /* process */
@ -462,7 +473,7 @@ gst_a52dec_loop (GstElement * element)
a52dec->level = 1; a52dec->level = 1;
if (a52_frame (a52dec->state, data, &flags, &a52dec->level, a52dec->bias)) { 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; goto end;
} }
@ -486,17 +497,21 @@ gst_a52dec_loop (GstElement * element)
for (i = 0; i < 6; i++) { for (i = 0; i < 6; i++) {
if (a52_block (a52dec->state)) { if (a52_block (a52dec->state)) {
g_warning ("a52dec a52_block error %d\n", i); GST_WARNING ("a52_block error %d", i);
continue; continue;
} }
/* push on */ /* push on */
if (gst_a52dec_push (a52dec->srcpad, a52dec->using_channels, if (gst_a52dec_push (a52dec->srcpad, a52dec->using_channels,
a52dec->samples, timestamp)) { a52dec->samples, timestamp)) {
g_warning ("a52dec push error\n"); GST_WARNING ("a52dec push error");
} else { } 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; a52dec->current_ts = timestamp;
end: end:
@ -507,13 +522,23 @@ static GstElementStateReturn
gst_a52dec_change_state (GstElement * element) gst_a52dec_change_state (GstElement * element)
{ {
GstA52Dec *a52dec = GST_A52DEC (element); GstA52Dec *a52dec = GST_A52DEC (element);
GstCPUFlags cpuflags;
uint32_t a52_cpuflags = 0;
switch (GST_STATE_TRANSITION (element)) { switch (GST_STATE_TRANSITION (element)) {
case GST_STATE_NULL_TO_READY: 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; break;
case GST_STATE_READY_TO_PAUSED: 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->samples = a52_samples (a52dec->state);
a52dec->bit_rate = -1; a52dec->bit_rate = -1;
a52dec->sample_rate = -1; a52dec->sample_rate = -1;
@ -523,8 +548,11 @@ gst_a52dec_change_state (GstElement * element)
a52dec->using_channels = A52_CHANNEL; a52dec->using_channels = A52_CHANNEL;
a52dec->level = 1; a52dec->level = 1;
a52dec->bias = 384; a52dec->bias = 384;
a52dec->last_ts = -1; a52dec->last_ts = 0;
a52dec->current_ts = 0; a52dec->current_ts = 0;
a52dec->last_timestamp = 0;
a52dec->last_diff = 0;
break; break;
case GST_STATE_PAUSED_TO_PLAYING: case GST_STATE_PAUSED_TO_PLAYING:
break; break;
@ -534,10 +562,10 @@ gst_a52dec_change_state (GstElement * element)
gst_bytestream_destroy (a52dec->bs); gst_bytestream_destroy (a52dec->bs);
a52dec->bs = NULL; a52dec->bs = NULL;
a52dec->samples = NULL; a52dec->samples = NULL;
a52_free (a52dec->state);
a52dec->state = NULL;
break; break;
case GST_STATE_READY_TO_NULL: case GST_STATE_READY_TO_NULL:
a52_free (a52dec->state);
a52dec->state = NULL;
break; break;
default: default:
break; break;

View File

@ -62,6 +62,9 @@ struct _GstA52Dec {
GstClockTime last_ts; GstClockTime last_ts;
GstClockTime current_ts; GstClockTime current_ts;
GstClockTime last_timestamp;
GstClockTimeDiff last_diff;
}; };
struct _GstA52DecClass { struct _GstA52DecClass {

View File

@ -39,6 +39,8 @@
GST_DEBUG_CATEGORY_STATIC (dvdnavsrc_debug); GST_DEBUG_CATEGORY_STATIC (dvdnavsrc_debug);
#define GST_CAT_DEFAULT (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_BASE 9LL
#define CLOCK_FREQ CLOCK_BASE * 10000 #define CLOCK_FREQ CLOCK_BASE * 10000
@ -96,7 +98,7 @@ typedef enum
DVDNavSrcPauseMode; DVDNavSrcPauseMode;
/* Interval of time to sleep during pauses. */ /* 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. */ /* The DVD domain types. */
typedef enum typedef enum
@ -229,6 +231,9 @@ static const GstFormat *dvdnavsrc_get_formats (GstPad * pad);
static gboolean dvdnavsrc_query (GstPad * pad, static gboolean dvdnavsrc_query (GstPad * pad,
GstQueryType type, GstFormat * format, gint64 * value); GstQueryType type, GstFormat * format, gint64 * value);
static const GstQueryType *dvdnavsrc_get_query_types (GstPad * pad); 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_close (DVDNavSrc * src);
static gboolean dvdnavsrc_open (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_function (src->srcpad, dvdnavsrc_event);
gst_pad_set_event_mask_function (src->srcpad, dvdnavsrc_get_event_mask); 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_function (src->srcpad, dvdnavsrc_query);
gst_pad_set_query_type_function (src->srcpad, dvdnavsrc_get_query_types); gst_pad_set_query_type_function (src->srcpad, dvdnavsrc_get_query_types);
gst_pad_set_formats_function (src->srcpad, dvdnavsrc_get_formats); gst_pad_set_formats_function (src->srcpad, dvdnavsrc_get_formats);
@ -809,7 +814,7 @@ dvdnavsrc_set_domain (DVDNavSrc * src)
static void static void
dvdnavsrc_update_highlight (DVDNavSrc * src) dvdnavsrc_update_highlight (DVDNavSrc * src)
{ {
int button; int button = 0;
pci_t *pci; pci_t *pci;
dvdnav_highlight_area_t area; dvdnav_highlight_area_t area;
GstEvent *event; GstEvent *event;
@ -817,11 +822,16 @@ dvdnavsrc_update_highlight (DVDNavSrc * src)
DVDNAV_CALL (dvdnav_get_current_highlight, (src->dvdnav, &button), src); DVDNAV_CALL (dvdnav_get_current_highlight, (src->dvdnav, &button), src);
pci = dvdnav_get_current_nav_pci (src->dvdnav); 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 is out of the range of possible buttons. */
button = 0; button = 0;
} }
if (!pci->hli.hl_gi.hli_ss) {
/* Not in menu */
button = 0;
}
if (button == 0) { if (button == 0) {
if (src->button != 0) { if (src->button != 0) {
src->button = 0; src->button = 0;
@ -856,6 +866,7 @@ dvdnavsrc_update_highlight (DVDNavSrc * src)
src->button = button; src->button = button;
GST_DEBUG ("Sending dvd-spu-highlight for button %d", button);
gst_pad_push (src->srcpad, GST_DATA (event)); 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. */ /* We just saw a still frame. Start a pause now. */
if (info->length == 0xff) { if (info->length == 0xff) {
GST_INFO_OBJECT (src, "starting unlimed pause"); GST_INFO_OBJECT (src, "starting unlimited pause");
src->pause_mode = DVDNAVSRC_PAUSE_UNLIMITED; src->pause_mode = DVDNAVSRC_PAUSE_UNLIMITED;
} else { } else {
GST_INFO_OBJECT (src, "starting limited pause: %d seconds",
info->length);
src->pause_mode = DVDNAVSRC_PAUSE_LIMITED; src->pause_mode = DVDNAVSRC_PAUSE_LIMITED;
src->pause_end = current_time + info->length * GST_SECOND; 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 /* 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 || if (src->pause_mode == DVDNAVSRC_PAUSE_UNLIMITED ||
current_time < src->pause_end) { current_time < src->pause_end) {
GstEvent *event;
/* We are in pause mode. Make this element sleep for a /* We are in pause mode. Make this element sleep for a
fraction of a second. */ fraction of a second. */
if (current_time + DVDNAVSRC_PAUSE_INTERVAL > src->pause_end) { if (current_time + DVDNAVSRC_PAUSE_INTERVAL > src->pause_end) {
@ -1336,10 +1350,13 @@ dvdnavsrc_loop (GstElement * element)
gst_element_wait (GST_ELEMENT (src), gst_element_wait (GST_ELEMENT (src),
current_time + DVDNAVSRC_PAUSE_INTERVAL); current_time + DVDNAVSRC_PAUSE_INTERVAL);
} }
/* Send an empty event to keep the pipeline going. */ /* Send an empty event to keep the pipeline going. */
/* FIXME: Use an interrupt/filler event here. */ /* 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; break;
} else { } else {
/* We reached the end of the pause. */ /* We reached the end of the pause. */
@ -1595,12 +1612,7 @@ dvdnavsrc_get_event_mask (GstPad * pad)
static const GstEventMask masks[] = { static const GstEventMask masks[] = {
{GST_EVENT_SEEK, GST_SEEK_METHOD_SET | {GST_EVENT_SEEK, GST_SEEK_METHOD_SET |
GST_SEEK_METHOD_CUR | GST_SEEK_METHOD_END | GST_SEEK_FLAG_FLUSH}, GST_SEEK_METHOD_CUR | GST_SEEK_METHOD_END | GST_SEEK_FLAG_FLUSH},
/* {GST_EVENT_FLUSH, 0},
{GST_EVENT_SEEK_SEGMENT, GST_SEEK_METHOD_SET |
GST_SEEK_METHOD_CUR |
GST_SEEK_METHOD_END |
GST_SEEK_FLAG_FLUSH },
*/
{GST_EVENT_NAVIGATION, GST_EVENT_FLAG_NONE}, {GST_EVENT_NAVIGATION, GST_EVENT_FLAG_NONE},
{0,} {0,}
}; };
@ -1629,6 +1641,8 @@ dvdnav_handle_navigation_event (DVDNavSrc * src, GstEvent * event)
dvdnav_mouse_select (src->dvdnav, dvdnav_mouse_select (src->dvdnav,
dvdnav_get_current_nav_pci (src->dvdnav), (int) x, (int) y); dvdnav_get_current_nav_pci (src->dvdnav), (int) x, (int) y);
dvdnavsrc_update_highlight (src);
} else if (strcmp (event_type, "mouse-button-release") == 0) { } else if (strcmp (event_type, "mouse-button-release") == 0) {
double x, y; double x, y;
@ -1667,6 +1681,24 @@ dvdnavsrc_event (GstPad * pad, GstEvent * event)
offset = GST_EVENT_SEEK_OFFSET (event); offset = GST_EVENT_SEEK_OFFSET (event);
switch (format) { 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: default:
if (format == sector_format) { if (format == sector_format) {
switch (GST_EVENT_SEEK_METHOD (event)) { switch (GST_EVENT_SEEK_METHOD (event)) {
@ -1770,6 +1802,7 @@ dvdnavsrc_event (GstPad * pad, GstEvent * event)
} }
case GST_EVENT_NAVIGATION: case GST_EVENT_NAVIGATION:
res = dvdnav_handle_navigation_event (src, event); res = dvdnav_handle_navigation_event (src, event);
break;
case GST_EVENT_FLUSH: case GST_EVENT_FLUSH:
src->need_flush = TRUE; src->need_flush = TRUE;
break; break;
@ -1791,9 +1824,9 @@ dvdnavsrc_get_formats (GstPad * pad)
{ {
int i; int i;
static GstFormat formats[] = { static GstFormat formats[] = {
GST_FORMAT_BYTES,
/* /*
GST_FORMAT_TIME, GST_FORMAT_TIME,
GST_FORMAT_BYTES,
GST_FORMAT_DEFAULT, GST_FORMAT_DEFAULT,
*/ */
0, /* filled later */ 0, /* filled later */
@ -1817,7 +1850,6 @@ dvdnavsrc_get_formats (GstPad * pad)
return formats; return formats;
} }
#if 0
static gboolean static gboolean
dvdnavsrc_convert (GstPad * pad, dvdnavsrc_convert (GstPad * pad,
GstFormat src_format, gint64 src_value, GstFormat src_format, gint64 src_value,
@ -1831,97 +1863,20 @@ dvdnavsrc_convert (GstPad * pad,
return FALSE; return FALSE;
switch (src_format) { 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: case GST_FORMAT_BYTES:
src_value >>= 2; if (*dest_format == sector_format) {
case GST_FORMAT_DEFAULT: *dest_value = src_value / DVD_SECTOR_SIZE;
switch (*dest_format) { } else
case GST_FORMAT_BYTES: return FALSE;
*dest_value = src_value * 4; default:
break; if ((src_format == sector_format) && (*dest_format == GST_FORMAT_BYTES)) {
case GST_FORMAT_TIME: *dest_value = src_value * DVD_SECTOR_SIZE;
*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;
} else } else
return FALSE; 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; return TRUE;
} }
#endif
static const GstQueryType * static const GstQueryType *
dvdnavsrc_get_query_types (GstPad * pad) dvdnavsrc_get_query_types (GstPad * pad)
@ -1959,6 +1914,11 @@ dvdnavsrc_query (GstPad * pad, GstQueryType type,
res = FALSE; res = FALSE;
} }
*value = len; *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) { } else if (*format == title_format) {
if (dvdnav_get_number_of_titles (src->dvdnav, &titles) if (dvdnav_get_number_of_titles (src->dvdnav, &titles)
!= DVDNAV_STATUS_OK) { != DVDNAV_STATUS_OK) {

View File

@ -40,6 +40,8 @@ typedef gint mpeg2_state_t;
#endif #endif
GST_DEBUG_CATEGORY_EXTERN (GST_CAT_SEEK); GST_DEBUG_CATEGORY_EXTERN (GST_CAT_SEEK);
GST_DEBUG_CATEGORY_STATIC (mpeg2dec_debug);
#define GST_CAT_DEFAULT (mpeg2dec_debug)
/* elementfactory information */ /* elementfactory information */
static GstElementDetails gst_mpeg2dec_details = { static GstElementDetails gst_mpeg2dec_details = {
@ -148,6 +150,10 @@ gst_mpeg2dec_get_type (void)
g_type_register_static (GST_TYPE_ELEMENT, "GstMpeg2dec", &mpeg2dec_info, g_type_register_static (GST_TYPE_ELEMENT, "GstMpeg2dec", &mpeg2dec_info,
0); 0);
} }
GST_DEBUG_CATEGORY_INIT (mpeg2dec_debug, "mpeg2dec", 0,
"MPEG2 decoder element");
return mpeg2dec_type; return mpeg2dec_type;
} }
@ -318,6 +324,8 @@ gst_mpeg2dec_alloc_buffer (GstMpeg2dec * mpeg2dec, const mpeg2_info_t * info,
} }
gst_buffer_ref (outbuf); gst_buffer_ref (outbuf);
mpeg2_custom_fbuf (mpeg2dec->decoder, 1);
mpeg2_set_buf (mpeg2dec->decoder, buf, outbuf); mpeg2_set_buf (mpeg2dec->decoder, buf, outbuf);
picture = info->current_picture; picture = info->current_picture;
@ -471,6 +479,7 @@ gst_mpeg2dec_chain (GstPad * pad, GstData * _data)
gst_index_commit (mpeg2dec->index, mpeg2dec->index_id); gst_index_commit (mpeg2dec->index, mpeg2dec->index_id);
} }
default: default:
GST_DEBUG ("Got event of type %d on sink pad", GST_EVENT_TYPE (event));
gst_pad_event_default (pad, event); gst_pad_event_default (pad, event);
return; return;
} }
@ -496,17 +505,17 @@ gst_mpeg2dec_chain (GstPad * pad, GstData * _data)
mpeg2_pts (mpeg2dec->decoder, mpeg_pts); mpeg2_pts (mpeg2dec->decoder, mpeg_pts);
#endif #endif
} else { } else {
GST_DEBUG ("no pts"); GST_LOG ("no pts");
} }
GST_DEBUG ("calling _buffer"); GST_LOG ("calling mpeg2_buffer");
mpeg2_buffer (mpeg2dec->decoder, data, end); mpeg2_buffer (mpeg2dec->decoder, data, end);
GST_DEBUG ("calling _buffer done"); GST_LOG ("calling mpeg2_buffer done");
while (!done) { while (!done) {
gboolean slice = FALSE; gboolean slice = FALSE;
GST_DEBUG ("calling parse"); GST_LOG ("calling parse");
state = mpeg2_parse (mpeg2dec->decoder); state = mpeg2_parse (mpeg2dec->decoder);
GST_DEBUG ("parse state %d", state); GST_DEBUG ("parse state %d", state);
switch (state) { switch (state) {
@ -644,7 +653,6 @@ gst_mpeg2dec_chain (GstPad * pad, GstData * _data)
mpeg2dec->next_time += mpeg2dec->next_time +=
(mpeg2dec->frame_period * picture->nb_fields) >> 1; (mpeg2dec->frame_period * picture->nb_fields) >> 1;
GST_DEBUG ("picture: %s %s fields:%d off:%" G_GINT64_FORMAT " ts:%" GST_DEBUG ("picture: %s %s fields:%d off:%" G_GINT64_FORMAT " ts:%"
G_GINT64_FORMAT, G_GINT64_FORMAT,
(picture->flags & PIC_FLAG_TOP_FIELD_FIRST ? "tff " : " "), (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); GST_FORMAT_TIME, GST_BUFFER_TIMESTAMP (outbuf), 0);
} }
if (picture->flags & PIC_FLAG_SKIP || if (picture->flags & PIC_FLAG_SKIP ||
!GST_PAD_IS_USABLE (mpeg2dec->srcpad) || !GST_PAD_IS_USABLE (mpeg2dec->srcpad) ||
mpeg2dec->discont_state != MPEG2DEC_DISC_NONE || 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_BUFFER_DURATION (outbuf) = mpeg2dec->frame_period;
gst_pad_push (mpeg2dec->srcpad, GST_DATA (outbuf)); 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) { if (info->discard_fbuf && info->discard_fbuf->id) {
gst_buffer_unref ((GstBuffer *) info->discard_fbuf->id); gst_buffer_unref ((GstBuffer *) info->discard_fbuf->id);
} }

View File

@ -672,7 +672,7 @@ gst_dvd_demux_process_private (GstMPEGDemux * mpeg_demux,
headerlen += 1; headerlen += 1;
datalen -= 1; datalen -= 1;
} else { } else {
GST_ERROR_OBJECT (dvd_demux, GST_WARNING_OBJECT (dvd_demux,
"unknown DVD (private 1) id 0x%02x", ps_id_code); "unknown DVD (private 1) id 0x%02x", ps_id_code);
} }
break; break;
@ -696,8 +696,8 @@ gst_dvd_demux_process_private (GstMPEGDemux * mpeg_demux,
break; break;
default: default:
GST_ERROR_OBJECT (dvd_demux, GST_WARNING_OBJECT (dvd_demux,
"unknown DVD (private 1) id 0x%02x", ps_id_code); "unknown DVD (private 2) id 0x%02x", ps_id_code);
break; break;
} }
break; break;
@ -780,7 +780,7 @@ gst_dvd_demux_send_subbuffer (GstMPEGDemux * mpeg_demux,
break; break;
} }
if (outpad != NULL && cur_nr == outstream->number) { if (outpad != NULL && cur_nr == outstream->number && (size > 0)) {
GstBuffer *outbuf; GstBuffer *outbuf;
/* We have a packet of the current stream. Send it to the /* We have a packet of the current stream. Send it to the

View File

@ -902,7 +902,7 @@ gst_mpeg_demux_send_subbuffer (GstMPEGDemux * mpeg_demux,
GST_BUFFER_OFFSET (buffer), GST_FORMAT_TIME, timestamp, 0); 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; return;
} }