mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-01-26 09:08:14 +00:00
ext/a52dec/gsta52dec.c: Add some debug output. Check that a discont has a valid time associated.
Original commit message from CVS: * ext/a52dec/gsta52dec.c: (gst_a52dec_push), (gst_a52dec_handle_event), (gst_a52dec_chain): Add some debug output. Check that a discont has a valid time associated. * ext/alsa/gstalsasink.c: (gst_alsa_sink_check_event), (gst_alsa_sink_loop): Ignore TAG events. A little extra debug for broken timestamps. * ext/dvdnav/dvdnavsrc.c: (dvdnavsrc_init), (dvdnavsrc_loop), (dvdnavsrc_change_state): Ensure we send a discont to engage the link before we send any other events. * ext/dvdread/dvdreadsrc.c: (dvdreadsrc_init), (dvdreadsrc_finalize), (_close), (_open), (_seek_title), (_seek_chapter), (seek_sector), (dvdreadsrc_get), (dvdreadsrc_uri_get_uri), (dvdreadsrc_uri_set_uri): Handle URI of the form dvd://title[,chapter[,angle]]. Currently only dvd://title works in totem because typefinding sends a seek that ends up going back to chapter 1 regardless. * ext/mpeg2dec/gstmpeg2dec.c: * ext/mpeg2dec/gstmpeg2dec.h: Output correct timestamps and handle disconts. * ext/ogg/gstoggdemux.c: (get_relative): Small guard against a null dereference. * ext/pango/gsttextoverlay.c: (gst_textoverlay_finalize), (gst_textoverlay_set_property): Free memory when done. Don't call gst_event_filler_get_duration on EOS events. Use GST_LOG and GST_WARNING instead of g_message and g_warning. * ext/smoothwave/gstsmoothwave.c: (gst_smoothwave_init), (draw_line), (gst_smoothwave_dispose), (gst_sw_sinklink), (gst_sw_srclink), (gst_smoothwave_chain): Draw solid lines, prettier colours. * gst/mpeg2sub/gstmpeg2subt.c: (gst_mpeg2subt_init): Add a default palette that'll work for some movies. * gst/mpegstream/gstdvddemux.c: (gst_dvd_demux_init), (gst_dvd_demux_handle_dvd_event), (gst_dvd_demux_send_discont), (gst_dvd_demux_send_subbuffer), (gst_dvd_demux_reset): * gst/mpegstream/gstdvddemux.h: * gst/mpegstream/gstmpegdemux.c: (gst_mpeg_demux_send_discont), (gst_mpeg_demux_parse_syshead), (gst_mpeg_demux_parse_pes): * gst/mpegstream/gstmpegparse.c: (gst_mpeg_parse_init), (gst_mpeg_parse_handle_discont), (gst_mpeg_parse_parse_packhead): * gst/mpegstream/gstmpegparse.h: Use PTM/NAV events when for timestamp adjustment when connected to dvdnavsrc. Don't use many discont events where one suffices. * gst/playback/gstplaybasebin.c: (group_destroy), (gen_preroll_element), (gst_play_base_bin_add_element): * gst/playback/gstplaybasebin.h: Make sure we remove subtitles from the same bin we put them in. * gst/subparse/gstsubparse.c: (convert_encoding), (parse_subrip), (gst_subparse_buffer_format_autodetect), (gst_subparse_change_state): Fix some memleaks and invalid accesses. * gst/typefind/gsttypefindfunctions.c: (ogganx_type_find), (oggskel_type_find), (cmml_type_find), (plugin_init): Some typefind functions for Annodex v3.0 files * gst/wavparse/gstwavparse.h: GstRiffReadClass is the correct parent class.
This commit is contained in:
parent
06862c4645
commit
f8d863517a
11 changed files with 322 additions and 117 deletions
60
ChangeLog
60
ChangeLog
|
@ -1,3 +1,63 @@
|
|||
2005-01-26 Jan Schmidt <thaytan@mad.scientist.com>
|
||||
* ext/a52dec/gsta52dec.c: (gst_a52dec_push),
|
||||
(gst_a52dec_handle_event), (gst_a52dec_chain):
|
||||
Add some debug output. Check that a discont has a valid
|
||||
time associated.
|
||||
* ext/alsa/gstalsasink.c: (gst_alsa_sink_check_event),
|
||||
(gst_alsa_sink_loop):
|
||||
Ignore TAG events. A little extra debug for broken timestamps.
|
||||
* ext/dvdnav/dvdnavsrc.c: (dvdnavsrc_init), (dvdnavsrc_loop),
|
||||
(dvdnavsrc_change_state):
|
||||
Ensure we send a discont to engage the link before we send any
|
||||
other events.
|
||||
* ext/dvdread/dvdreadsrc.c: (dvdreadsrc_init),
|
||||
(dvdreadsrc_finalize), (_close), (_open), (_seek_title),
|
||||
(_seek_chapter), (seek_sector), (dvdreadsrc_get),
|
||||
(dvdreadsrc_uri_get_uri), (dvdreadsrc_uri_set_uri):
|
||||
Handle URI of the form dvd://title[,chapter[,angle]]. Currently only
|
||||
dvd://title works in totem because typefinding sends a seek that ends
|
||||
up going back to chapter 1 regardless.
|
||||
* ext/mpeg2dec/gstmpeg2dec.c:
|
||||
* ext/mpeg2dec/gstmpeg2dec.h:
|
||||
Output correct timestamps and handle disconts.
|
||||
* ext/ogg/gstoggdemux.c: (get_relative):
|
||||
Small guard against a null dereference.
|
||||
* ext/pango/gsttextoverlay.c: (gst_textoverlay_finalize),
|
||||
(gst_textoverlay_set_property):
|
||||
Free memory when done. Don't call gst_event_filler_get_duration on
|
||||
EOS events. Use GST_LOG and GST_WARNING instead of g_message and
|
||||
g_warning.
|
||||
* ext/smoothwave/gstsmoothwave.c: (gst_smoothwave_init),
|
||||
(draw_line), (gst_smoothwave_dispose), (gst_sw_sinklink),
|
||||
(gst_sw_srclink), (gst_smoothwave_chain):
|
||||
Draw solid lines, prettier colours.
|
||||
* gst/mpeg2sub/gstmpeg2subt.c: (gst_mpeg2subt_init):
|
||||
Add a default palette that'll work for some movies.
|
||||
* gst/mpegstream/gstdvddemux.c: (gst_dvd_demux_init),
|
||||
(gst_dvd_demux_handle_dvd_event), (gst_dvd_demux_send_discont),
|
||||
(gst_dvd_demux_send_subbuffer), (gst_dvd_demux_reset):
|
||||
* gst/mpegstream/gstdvddemux.h:
|
||||
* gst/mpegstream/gstmpegdemux.c: (gst_mpeg_demux_send_discont),
|
||||
(gst_mpeg_demux_parse_syshead), (gst_mpeg_demux_parse_pes):
|
||||
* gst/mpegstream/gstmpegparse.c: (gst_mpeg_parse_init),
|
||||
(gst_mpeg_parse_handle_discont), (gst_mpeg_parse_parse_packhead):
|
||||
* gst/mpegstream/gstmpegparse.h:
|
||||
Use PTM/NAV events when for timestamp adjustment when connected to
|
||||
dvdnavsrc. Don't use many discont events where one suffices.
|
||||
* gst/playback/gstplaybasebin.c: (group_destroy),
|
||||
(gen_preroll_element), (gst_play_base_bin_add_element):
|
||||
* gst/playback/gstplaybasebin.h:
|
||||
Make sure we remove subtitles from the same bin we put them in.
|
||||
* gst/subparse/gstsubparse.c: (convert_encoding), (parse_subrip),
|
||||
(gst_subparse_buffer_format_autodetect),
|
||||
(gst_subparse_change_state):
|
||||
Fix some memleaks and invalid accesses.
|
||||
* gst/typefind/gsttypefindfunctions.c: (ogganx_type_find),
|
||||
(oggskel_type_find), (cmml_type_find), (plugin_init):
|
||||
Some typefind functions for Annodex v3.0 files
|
||||
* gst/wavparse/gstwavparse.h:
|
||||
GstRiffReadClass is the correct parent class.
|
||||
|
||||
2005-01-25 Ronald S. Bultje <rbultje@ronald.bitfreak.net>
|
||||
|
||||
* gst-libs/gst/riff/riff-media.c:
|
||||
|
|
|
@ -283,6 +283,11 @@ gst_a52dec_push (GstA52Dec * a52dec,
|
|||
GST_BUFFER_TIMESTAMP (buf) = timestamp;
|
||||
GST_BUFFER_DURATION (buf) = 256 * GST_SECOND / a52dec->sample_rate;
|
||||
|
||||
GST_DEBUG_OBJECT (a52dec,
|
||||
"Pushing buffer with ts %" GST_TIME_FORMAT " duration %" GST_TIME_FORMAT,
|
||||
GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (buf)),
|
||||
GST_TIME_ARGS (GST_BUFFER_DURATION (buf)));
|
||||
|
||||
gst_pad_push (srcpad, GST_DATA (buf));
|
||||
|
||||
return 0;
|
||||
|
@ -324,7 +329,8 @@ gst_a52dec_handle_event (GstA52Dec * a52dec, GstEvent * event)
|
|||
case GST_EVENT_DISCONTINUOUS:{
|
||||
gint64 val;
|
||||
|
||||
if (!gst_event_discont_get_value (event, GST_FORMAT_TIME, &val)) {
|
||||
if (!gst_event_discont_get_value (event, GST_FORMAT_TIME, &val)
|
||||
|| !GST_CLOCK_TIME_IS_VALID (val)) {
|
||||
GST_WARNING ("No time discont value in event %p", event);
|
||||
} else {
|
||||
a52dec->time = val;
|
||||
|
@ -442,7 +448,12 @@ gst_a52dec_chain (GstPad * pad, GstData * _data)
|
|||
buf = GST_BUFFER (_data);
|
||||
if (GST_BUFFER_TIMESTAMP_IS_VALID (buf)) {
|
||||
a52dec->time = GST_BUFFER_TIMESTAMP (buf);
|
||||
GST_DEBUG_OBJECT (a52dec,
|
||||
"Received buffer with ts %" GST_TIME_FORMAT " duration %"
|
||||
GST_TIME_FORMAT, GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (buf)),
|
||||
GST_TIME_ARGS (GST_BUFFER_DURATION (buf)));
|
||||
}
|
||||
|
||||
if (a52dec->cache) {
|
||||
buf = gst_buffer_join (a52dec->cache, buf);
|
||||
a52dec->cache = NULL;
|
||||
|
|
|
@ -124,7 +124,7 @@ struct _DVDNavSrc
|
|||
|
||||
gboolean did_seek;
|
||||
gboolean need_flush;
|
||||
gboolean need_discont;
|
||||
gboolean need_newmedia;
|
||||
|
||||
/* Timing */
|
||||
GstClock *clock; /* The clock for this element. */
|
||||
|
@ -395,6 +395,7 @@ dvdnavsrc_init (DVDNavSrc * src)
|
|||
|
||||
src->did_seek = FALSE;
|
||||
src->need_flush = FALSE;
|
||||
src->need_newmedia = TRUE;
|
||||
|
||||
/* Pause mode is initially inactive. */
|
||||
src->pause_mode = DVDNAVSRC_PAUSE_OFF;
|
||||
|
@ -1278,13 +1279,16 @@ dvdnavsrc_loop (GstElement * element)
|
|||
|
||||
g_return_if_fail (dvdnavsrc_is_open (src));
|
||||
|
||||
if (src->did_seek) {
|
||||
if (src->did_seek || src->need_newmedia) {
|
||||
GstEvent *event;
|
||||
|
||||
src->did_seek = FALSE;
|
||||
GST_INFO_OBJECT (src, "sending discont");
|
||||
event = gst_event_new_discontinuous (FALSE, 0);
|
||||
|
||||
event = gst_event_new_discontinuous (src->need_newmedia, 0);
|
||||
|
||||
src->need_flush = FALSE;
|
||||
src->need_newmedia = FALSE;
|
||||
gst_pad_push (src->srcpad, GST_DATA (event));
|
||||
return;
|
||||
}
|
||||
|
@ -1595,6 +1599,7 @@ dvdnavsrc_change_state (GstElement * element)
|
|||
}
|
||||
}
|
||||
src->streaminfo = NULL;
|
||||
src->need_newmedia = TRUE;
|
||||
break;
|
||||
case GST_STATE_PAUSED_TO_PLAYING:
|
||||
break;
|
||||
|
|
|
@ -53,6 +53,7 @@ struct _DVDReadSrcPrivate
|
|||
|
||||
/* location */
|
||||
gchar *location;
|
||||
gchar *last_uri;
|
||||
|
||||
gboolean new_seek;
|
||||
|
||||
|
@ -235,7 +236,13 @@ dvdreadsrc_init (DVDReadSrc * dvdreadsrc)
|
|||
dvdreadsrc_get_formats);
|
||||
gst_element_add_pad (GST_ELEMENT (dvdreadsrc), dvdreadsrc->priv->srcpad);
|
||||
|
||||
dvdreadsrc->priv->dvd = NULL;
|
||||
dvdreadsrc->priv->vts_file = NULL;
|
||||
dvdreadsrc->priv->vmg_file = NULL;
|
||||
dvdreadsrc->priv->dvd_title = NULL;
|
||||
|
||||
dvdreadsrc->priv->location = g_strdup ("/dev/dvd");
|
||||
dvdreadsrc->priv->last_uri = NULL;
|
||||
dvdreadsrc->priv->new_seek = TRUE;
|
||||
dvdreadsrc->priv->new_cell = TRUE;
|
||||
dvdreadsrc->priv->title = 0;
|
||||
|
@ -254,6 +261,7 @@ dvdreadsrc_finalize (GObject * object)
|
|||
|
||||
if (dvdreadsrc->priv) {
|
||||
g_free (dvdreadsrc->priv->location);
|
||||
g_free (dvdreadsrc->priv->last_uri);
|
||||
g_free (dvdreadsrc->priv);
|
||||
dvdreadsrc->priv = NULL;
|
||||
}
|
||||
|
@ -549,6 +557,24 @@ is_nav_pack (unsigned char *buffer)
|
|||
return (buffer[41] == 0xbf && buffer[1027] == 0xbf);
|
||||
}
|
||||
|
||||
static int
|
||||
_close (DVDReadSrcPrivate * priv)
|
||||
{
|
||||
ifoClose (priv->vts_file);
|
||||
priv->vts_file = NULL;
|
||||
|
||||
ifoClose (priv->vmg_file);
|
||||
priv->vmg_file = NULL;
|
||||
|
||||
DVDCloseFile (priv->dvd_title);
|
||||
priv->dvd_title = NULL;
|
||||
|
||||
DVDClose (priv->dvd);
|
||||
priv->dvd = NULL;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
_open (DVDReadSrcPrivate * priv, const gchar * location)
|
||||
{
|
||||
|
@ -572,7 +598,6 @@ _open (DVDReadSrcPrivate * priv, const gchar * location)
|
|||
priv->vmg_file = ifoOpen (priv->dvd, 0);
|
||||
if (!priv->vmg_file) {
|
||||
GST_ERROR ("Can't open VMG info");
|
||||
DVDClose (priv->dvd);
|
||||
return -1;
|
||||
}
|
||||
priv->tt_srpt = priv->vmg_file->tt_srpt;
|
||||
|
@ -580,16 +605,6 @@ _open (DVDReadSrcPrivate * priv, const gchar * location)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
_close (DVDReadSrcPrivate * priv)
|
||||
{
|
||||
ifoClose (priv->vts_file);
|
||||
ifoClose (priv->vmg_file);
|
||||
DVDCloseFile (priv->dvd_title);
|
||||
DVDClose (priv->dvd);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
_seek_title (DVDReadSrcPrivate * priv, int title, int angle)
|
||||
{
|
||||
|
@ -600,11 +615,13 @@ _seek_title (DVDReadSrcPrivate * priv, int title, int angle)
|
|||
*/
|
||||
GST_LOG ("There are %d titles on this DVD", priv->tt_srpt->nr_of_srpts);
|
||||
if (title < 0 || title >= priv->tt_srpt->nr_of_srpts) {
|
||||
GST_ERROR ("Invalid title %d (only %d available)",
|
||||
GST_WARNING ("Invalid title %d (only %d available)",
|
||||
title, priv->tt_srpt->nr_of_srpts);
|
||||
ifoClose (priv->vmg_file);
|
||||
DVDClose (priv->dvd);
|
||||
return -1;
|
||||
|
||||
if (title < 0)
|
||||
title = 0;
|
||||
else
|
||||
title = priv->tt_srpt->nr_of_srpts - 1;
|
||||
}
|
||||
|
||||
GST_LOG ("There are %d chapters in this title",
|
||||
|
@ -617,14 +634,14 @@ _seek_title (DVDReadSrcPrivate * priv, int title, int angle)
|
|||
priv->tt_srpt->title[title].nr_of_angles);
|
||||
|
||||
if (angle < 0 || angle >= priv->tt_srpt->title[title].nr_of_angles) {
|
||||
GST_ERROR ("Invalid angle %d (only %d available)",
|
||||
GST_WARNING ("Invalid angle %d (only %d available)",
|
||||
angle, priv->tt_srpt->title[title].nr_of_angles);
|
||||
ifoClose (priv->vmg_file);
|
||||
DVDClose (priv->dvd);
|
||||
return -1;
|
||||
if (angle < 0)
|
||||
angle = 0;
|
||||
else
|
||||
angle = priv->tt_srpt->title[title].nr_of_angles - 1;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Load the VTS information for the title set our title is in.
|
||||
*/
|
||||
|
@ -633,8 +650,7 @@ _seek_title (DVDReadSrcPrivate * priv, int title, int angle)
|
|||
if (!priv->vts_file) {
|
||||
GST_ERROR ("Can't open the info file of title %d",
|
||||
priv->tt_srpt->title[title].title_set_nr);
|
||||
ifoClose (priv->vmg_file);
|
||||
DVDClose (priv->dvd);
|
||||
_close (priv);
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
@ -650,9 +666,7 @@ _seek_title (DVDReadSrcPrivate * priv, int title, int angle)
|
|||
if (!priv->dvd_title) {
|
||||
GST_ERROR ("Can't open title VOBS (VTS_%02d_1.VOB)",
|
||||
priv->tt_srpt->title[title].title_set_nr);
|
||||
ifoClose (priv->vts_file);
|
||||
ifoClose (priv->vmg_file);
|
||||
DVDClose (priv->dvd);
|
||||
_close (priv);
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
@ -665,6 +679,8 @@ _seek_title (DVDReadSrcPrivate * priv, int title, int angle)
|
|||
g_hash_table_destroy (languagelist);
|
||||
|
||||
GST_LOG ("Opened title %d, angle %d", title, angle);
|
||||
priv->title = title;
|
||||
priv->angle = angle;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -678,11 +694,11 @@ _seek_chapter (DVDReadSrcPrivate * priv, int chapter)
|
|||
* Make sure the chapter number is valid for this title.
|
||||
*/
|
||||
if (chapter < 0 || chapter >= priv->tt_srpt->title[priv->title].nr_of_ptts) {
|
||||
GST_ERROR ("Invalid chapter %d (only %d available)",
|
||||
GST_WARNING ("Invalid chapter %d (only %d available)",
|
||||
chapter, priv->tt_srpt->title[priv->title].nr_of_ptts);
|
||||
ifoClose (priv->vmg_file);
|
||||
DVDClose (priv->dvd);
|
||||
return -1;
|
||||
if (chapter < 0)
|
||||
chapter = 0;
|
||||
chapter = priv->tt_srpt->title[priv->title].nr_of_ptts - 1;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -730,6 +746,7 @@ _seek_chapter (DVDReadSrcPrivate * priv, int chapter)
|
|||
priv->new_cell = TRUE;
|
||||
priv->next_cell = priv->start_cell;
|
||||
|
||||
priv->chapter = chapter;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -907,7 +924,8 @@ again:
|
|||
static gboolean
|
||||
seek_sector (DVDReadSrcPrivate * priv, int angle)
|
||||
{
|
||||
gint seek_to = priv->cur_pack, chapter, sectors, next, cur, i;
|
||||
gint seek_to = priv->cur_pack;
|
||||
gint chapter, sectors, next, cur, i;
|
||||
|
||||
/* retrieve position */
|
||||
priv->cur_pack = 0;
|
||||
|
@ -992,6 +1010,7 @@ dvdreadsrc_get (GstPad * pad)
|
|||
priv->seek_pend_fmt = GST_FORMAT_UNDEFINED;
|
||||
} else {
|
||||
if (!seek_sector (priv, priv->angle)) {
|
||||
gst_element_set_eos (GST_ELEMENT (dvdreadsrc));
|
||||
return GST_DATA (gst_event_new (GST_EVENT_EOS));
|
||||
}
|
||||
}
|
||||
|
@ -1122,17 +1141,76 @@ dvdreadsrc_uri_get_protocols (void)
|
|||
static const gchar *
|
||||
dvdreadsrc_uri_get_uri (GstURIHandler * handler)
|
||||
{
|
||||
return "dvd://";
|
||||
DVDReadSrc *dvdreadsrc = DVDREADSRC (handler);
|
||||
|
||||
g_free (dvdreadsrc->priv->last_uri);
|
||||
dvdreadsrc->priv->last_uri =
|
||||
g_strdup_printf ("dvd://%d,%d,%d", dvdreadsrc->priv->title,
|
||||
dvdreadsrc->priv->chapter, dvdreadsrc->priv->angle);
|
||||
|
||||
return dvdreadsrc->priv->last_uri;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
dvdreadsrc_uri_set_uri (GstURIHandler * handler, const gchar * uri)
|
||||
{
|
||||
DVDReadSrc *dvdreadsrc = DVDREADSRC (handler);
|
||||
gboolean ret;
|
||||
gchar *protocol = gst_uri_get_protocol (uri);
|
||||
|
||||
ret = (protocol && !strcmp (protocol, "dvd")) ? TRUE : FALSE;
|
||||
g_free (protocol);
|
||||
protocol = NULL;
|
||||
|
||||
if (!ret)
|
||||
return ret;
|
||||
|
||||
/*
|
||||
* Parse out the new t/c/a and seek to them
|
||||
*/
|
||||
{
|
||||
gchar *location = NULL;
|
||||
gchar **strs;
|
||||
gchar **strcur;
|
||||
gint pos = 0;
|
||||
|
||||
location = gst_uri_get_location (uri);
|
||||
|
||||
if (!location)
|
||||
return ret;
|
||||
|
||||
strcur = strs = g_strsplit (location, ",", 0);
|
||||
while (strcur && *strcur) {
|
||||
gint val;
|
||||
|
||||
if (!sscanf (*strcur, "%d", &val))
|
||||
break;
|
||||
|
||||
switch (pos) {
|
||||
case 0:
|
||||
if (val != dvdreadsrc->priv->title) {
|
||||
dvdreadsrc->priv->title = val;
|
||||
dvdreadsrc->priv->new_seek = TRUE;
|
||||
}
|
||||
break;
|
||||
case 1:
|
||||
if (val != dvdreadsrc->priv->chapter) {
|
||||
dvdreadsrc->priv->chapter = val;
|
||||
dvdreadsrc->priv->new_seek = TRUE;
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
dvdreadsrc->priv->angle = val;
|
||||
break;
|
||||
}
|
||||
|
||||
strcur++;
|
||||
pos++;
|
||||
}
|
||||
|
||||
g_strfreev (strs);
|
||||
g_free (location);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
|
|
@ -585,7 +585,7 @@ gst_mpeg2dec_chain (GstPad * pad, GstData * _data)
|
|||
GstMpeg2dec *mpeg2dec = GST_MPEG2DEC (gst_pad_get_parent (pad));
|
||||
guint32 size;
|
||||
guint8 *data, *end;
|
||||
gint64 pts;
|
||||
GstClockTime pts;
|
||||
const mpeg2_info_t *info;
|
||||
mpeg2_state_t state;
|
||||
gboolean done = FALSE;
|
||||
|
@ -596,8 +596,20 @@ gst_mpeg2dec_chain (GstPad * pad, GstData * _data)
|
|||
switch (GST_EVENT_TYPE (event)) {
|
||||
case GST_EVENT_DISCONTINUOUS:
|
||||
{
|
||||
GST_DEBUG_OBJECT (mpeg2dec, "discont, resetting next_time to 0");
|
||||
mpeg2dec->next_time = 0;
|
||||
GstClockTime time;
|
||||
|
||||
if (!gst_event_discont_get_value (event, GST_FORMAT_TIME, &time)
|
||||
|| !GST_CLOCK_TIME_IS_VALID (time)) {
|
||||
GST_WARNING_OBJECT (mpeg2dec,
|
||||
"No new time offset in discont event %p", event);
|
||||
} else {
|
||||
mpeg2dec->next_time = time;
|
||||
GST_DEBUG_OBJECT (mpeg2dec,
|
||||
"discont, reset next_time to %" G_GUINT64_FORMAT " (%"
|
||||
GST_TIME_FORMAT ")", mpeg2dec->next_time,
|
||||
GST_TIME_ARGS (mpeg2dec->next_time));
|
||||
}
|
||||
|
||||
mpeg2dec->discont_state = MPEG2DEC_DISC_NEW_PICTURE;
|
||||
gst_mpeg2dec_flush_decoder (mpeg2dec);
|
||||
gst_pad_event_default (pad, event);
|
||||
|
@ -626,7 +638,7 @@ gst_mpeg2dec_chain (GstPad * pad, GstData * _data)
|
|||
info = mpeg2_info (mpeg2dec->decoder);
|
||||
end = data + size;
|
||||
|
||||
if (pts != -1) {
|
||||
if (pts != GST_CLOCK_TIME_NONE) {
|
||||
gint64 mpeg_pts = GST_TIME_TO_MPEG_TIME (pts);
|
||||
|
||||
GST_DEBUG_OBJECT (mpeg2dec,
|
||||
|
@ -643,14 +655,14 @@ gst_mpeg2dec_chain (GstPad * pad, GstData * _data)
|
|||
GST_LOG ("no pts");
|
||||
}
|
||||
|
||||
GST_LOG ("calling mpeg2_buffer");
|
||||
GST_LOG_OBJECT (mpeg2dec, "calling mpeg2_buffer");
|
||||
mpeg2_buffer (mpeg2dec->decoder, data, end);
|
||||
GST_LOG ("calling mpeg2_buffer done");
|
||||
GST_LOG_OBJECT (mpeg2dec, "calling mpeg2_buffer done");
|
||||
|
||||
while (!done) {
|
||||
gboolean slice = FALSE;
|
||||
|
||||
GST_LOG ("calling parse");
|
||||
GST_LOG_OBJECT (mpeg2dec, "calling parse");
|
||||
state = mpeg2_parse (mpeg2dec->decoder);
|
||||
GST_DEBUG_OBJECT (mpeg2dec, "parse state %d", state);
|
||||
switch (state) {
|
||||
|
@ -676,8 +688,9 @@ gst_mpeg2dec_chain (GstPad * pad, GstData * _data)
|
|||
info->sequence->frame_period * GST_USECOND / 27;
|
||||
|
||||
GST_DEBUG_OBJECT (mpeg2dec,
|
||||
"sequence flags: %d, frame period: %d, frame rate: %d",
|
||||
"sequence flags: %d, frame period: %d (%g), frame rate: %g",
|
||||
info->sequence->flags, info->sequence->frame_period,
|
||||
(double) (mpeg2dec->frame_period) / GST_SECOND,
|
||||
mpeg2dec->frame_rate);
|
||||
GST_DEBUG_OBJECT (mpeg2dec, "profile: %02x, colour_primaries: %d",
|
||||
info->sequence->profile_level_id, info->sequence->colour_primaries);
|
||||
|
@ -741,10 +754,11 @@ gst_mpeg2dec_chain (GstPad * pad, GstData * _data)
|
|||
break;
|
||||
}
|
||||
case STATE_SLICE_1ST:
|
||||
GST_DEBUG_OBJECT (mpeg2dec, "slice 1st");
|
||||
GST_LOG_OBJECT (mpeg2dec, "1st slice of frame encountered");
|
||||
break;
|
||||
case STATE_PICTURE_2ND:
|
||||
GST_DEBUG_OBJECT (mpeg2dec, "picture second");
|
||||
GST_LOG_OBJECT (mpeg2dec,
|
||||
"Second picture header encountered. Decoding 2nd field");
|
||||
break;
|
||||
case STATE_SLICE:
|
||||
slice = TRUE;
|
||||
|
@ -788,22 +802,31 @@ gst_mpeg2dec_chain (GstPad * pad, GstData * _data)
|
|||
#else
|
||||
if (picture->flags & PIC_FLAG_TAGS) {
|
||||
GstClockTime time =
|
||||
MPEG_TIME_TO_GST_TIME ((guint64) picture->tag2 << 32 | picture->
|
||||
tag);
|
||||
MPEG_TIME_TO_GST_TIME ((GstClockTime) (picture->
|
||||
tag2) << 32 | picture->tag);
|
||||
#endif
|
||||
|
||||
GST_DEBUG_OBJECT (mpeg2dec, "picture had pts %" GST_TIME_FORMAT,
|
||||
GST_TIME_ARGS (time));
|
||||
GST_DEBUG_OBJECT (mpeg2dec,
|
||||
"picture had pts %" GST_TIME_FORMAT ", we had %"
|
||||
GST_TIME_FORMAT, GST_TIME_ARGS (time),
|
||||
GST_TIME_ARGS (mpeg2dec->next_time));
|
||||
GST_BUFFER_TIMESTAMP (outbuf) = mpeg2dec->next_time = time;
|
||||
} else {
|
||||
GST_DEBUG_OBJECT (mpeg2dec,
|
||||
"picture didn't have pts using %" GST_TIME_FORMAT,
|
||||
"picture didn't have pts. Using %" GST_TIME_FORMAT,
|
||||
GST_TIME_ARGS (mpeg2dec->next_time));
|
||||
GST_BUFFER_TIMESTAMP (outbuf) = mpeg2dec->next_time;
|
||||
}
|
||||
|
||||
mpeg2dec->next_time +=
|
||||
(mpeg2dec->frame_period * picture->nb_fields) >> 1;
|
||||
/* TODO set correct offset here based on frame number */
|
||||
if (info->display_picture_2nd) {
|
||||
GST_BUFFER_DURATION (outbuf) = (picture->nb_fields +
|
||||
info->display_picture_2nd->nb_fields) * mpeg2dec->frame_period /
|
||||
2;
|
||||
} else {
|
||||
GST_BUFFER_DURATION (outbuf) =
|
||||
picture->nb_fields * mpeg2dec->frame_period / 2;
|
||||
}
|
||||
mpeg2dec->next_time += GST_BUFFER_DURATION (outbuf);
|
||||
|
||||
GST_DEBUG_OBJECT (mpeg2dec,
|
||||
"picture: %s %s fields:%d off:%" G_GINT64_FORMAT " ts:%"
|
||||
|
@ -840,8 +863,6 @@ gst_mpeg2dec_chain (GstPad * pad, GstData * _data)
|
|||
GST_DEBUG_OBJECT (mpeg2dec, "dropping buffer, asked to skip");
|
||||
gst_buffer_unref (outbuf);
|
||||
} else {
|
||||
/* TODO set correct offset here based on frame number */
|
||||
GST_BUFFER_DURATION (outbuf) = mpeg2dec->frame_period;
|
||||
GST_LOG_OBJECT (mpeg2dec, "pushing buffer, timestamp %"
|
||||
GST_TIME_FORMAT ", duration %" GST_TIME_FORMAT,
|
||||
GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (outbuf)),
|
||||
|
@ -869,14 +890,13 @@ gst_mpeg2dec_chain (GstPad * pad, GstData * _data)
|
|||
break;
|
||||
/* error */
|
||||
case STATE_INVALID:
|
||||
g_warning ("mpeg2dec: decoding error");
|
||||
GST_WARNING_OBJECT (mpeg2dec, "Decoding error");
|
||||
/* it looks like setting a new frame in libmpeg2 avoids a crash */
|
||||
/* FIXME figure out how this screws up sync and buffer leakage */
|
||||
gst_mpeg2dec_alloc_buffer (mpeg2dec, info, GST_BUFFER_OFFSET (buf));
|
||||
break;
|
||||
default:
|
||||
g_warning ("%s: unhandled state %d, FIXME",
|
||||
gst_element_get_name (GST_ELEMENT (mpeg2dec)), state);
|
||||
GST_ERROR_OBJECT (mpeg2dec, "Unknown libmpeg2 state %d, FIXME", state);
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -1306,6 +1326,7 @@ gst_mpeg2dec_change_state (GstElement * element)
|
|||
case GST_STATE_PLAYING_TO_PAUSED:
|
||||
break;
|
||||
case GST_STATE_PAUSED_TO_READY:
|
||||
gst_mpeg2dec_flush_decoder (mpeg2dec);
|
||||
gst_mpeg2dec_close_decoder (mpeg2dec);
|
||||
break;
|
||||
case GST_STATE_READY_TO_NULL:
|
||||
|
|
|
@ -71,9 +71,10 @@ struct _GstMpeg2dec {
|
|||
gboolean closed;
|
||||
gboolean have_fbuf;
|
||||
|
||||
/* the timestamp of the next frame */
|
||||
DiscontState discont_state;
|
||||
gint64 next_time;
|
||||
|
||||
/* the timestamp of the next frame */
|
||||
GstClockTime next_time;
|
||||
gint64 segment_start;
|
||||
gint64 segment_end;
|
||||
|
||||
|
|
|
@ -26,6 +26,11 @@
|
|||
|
||||
#include "gstdvddemux.h"
|
||||
|
||||
/*
|
||||
* Start the timestamp sequence at 2 seconds to allow for strange audio
|
||||
* timestamps when audio crosses a VOBU
|
||||
*/
|
||||
#define INITIAL_END_PTM (2 * GST_SECOND)
|
||||
|
||||
GST_DEBUG_CATEGORY_STATIC (gstdvddemux_debug);
|
||||
#define GST_CAT_DEFAULT (gstdvddemux_debug)
|
||||
|
@ -290,28 +295,7 @@ gst_dvd_demux_init (GstDVDDemux * dvd_demux)
|
|||
dvd_demux->cur_audio_nr = 0;
|
||||
dvd_demux->cur_subpicture_nr = 0;
|
||||
|
||||
/* Start the timestamp sequence in 0. */
|
||||
dvd_demux->last_end_ptm = 0;
|
||||
|
||||
/* (Ronald) so, this was disabled. I'm enabling (default) it again.
|
||||
* Timestamp adjustment is fairly evil, we would ideally use discont
|
||||
* events instead. However, our current clocking has a pretty serious
|
||||
* race condition: imagine that $pipeline is at time 30sec and $audio
|
||||
* receives a discont to 0sec. Video processes its last buffer and
|
||||
* calls _wait() on $timestamp, which is 30s - so we wait (hang) 30sec.
|
||||
* This is unacceptable, obviously, and timestamp adjustment, no matter
|
||||
* how evil, solves this.
|
||||
* Before disabling this again, tripple check that al .vob files on our
|
||||
* websites /media/ directory work fine, especially bullet.vob and
|
||||
* barrage.vob.
|
||||
*/
|
||||
#if 0
|
||||
/* Try to prevent the mpegparse infrastructure from doing timestamp
|
||||
adjustment. */
|
||||
mpeg_parse->do_adjust = FALSE;
|
||||
mpeg_parse->adjust = 0;
|
||||
#endif
|
||||
|
||||
dvd_demux->last_end_ptm = INITIAL_END_PTM;
|
||||
dvd_demux->just_flushed = FALSE;
|
||||
dvd_demux->discont_time = GST_CLOCK_TIME_NONE;
|
||||
|
||||
|
@ -416,6 +400,26 @@ gst_dvd_demux_handle_dvd_event (GstDVDDemux * dvd_demux, GstEvent * event)
|
|||
(double) dvd_demux->last_end_ptm / GST_SECOND,
|
||||
(double) start_ptm / GST_SECOND,
|
||||
(double) mpeg_demux->adjust / GST_SECOND);
|
||||
|
||||
/* Disable mpeg_parse's timestamp adjustment in favour of the info
|
||||
* from DVD nav packets.
|
||||
* Timestamp adjustment is fairly evil, we would ideally use discont
|
||||
* events instead. However, our current clocking has a pretty serious
|
||||
* race condition: imagine that $pipeline is at time 30sec and $audio
|
||||
* receives a discont to 0sec. Video processes its last buffer and
|
||||
* calls _wait() on $timestamp, which is 30s - so we wait (hang) 30sec.
|
||||
* This is unacceptable, obviously, and timestamp adjustment, no matter
|
||||
* how evil, solves this.
|
||||
* Before disabling this again, tripple check that al .vob files on our
|
||||
* websites /media/ directory work fine, especially bullet.vob and
|
||||
* barrage.vob.
|
||||
*/
|
||||
#if 1
|
||||
/* Try to prevent the mpegparse infrastructure from doing timestamp
|
||||
adjustment. */
|
||||
mpeg_parse->use_adjust = FALSE;
|
||||
mpeg_parse->adjust = 0;
|
||||
#endif
|
||||
}
|
||||
dvd_demux->last_end_ptm = end_ptm;
|
||||
|
||||
|
@ -425,6 +429,9 @@ gst_dvd_demux_handle_dvd_event (GstDVDDemux * dvd_demux, GstEvent * event)
|
|||
time gap between the discontinuity and the subsequent data
|
||||
blocks. */
|
||||
dvd_demux->discont_time = start_ptm + mpeg_demux->adjust;
|
||||
GST_DEBUG_OBJECT (dvd_demux, "Set discont time to %" G_GINT64_FORMAT,
|
||||
start_ptm + mpeg_demux->adjust);
|
||||
|
||||
dvd_demux->just_flushed = FALSE;
|
||||
}
|
||||
|
||||
|
@ -454,34 +461,39 @@ gst_dvd_demux_send_discont (GstMPEGParse * mpeg_parse, GstClockTime time)
|
|||
|
||||
GST_MPEG_PARSE_CLASS (parent_class)->send_discont (mpeg_parse, time);
|
||||
|
||||
discont = gst_event_new_discontinuous (FALSE, GST_FORMAT_TIME, time, NULL);
|
||||
if (!discont) {
|
||||
GST_ELEMENT_ERROR (GST_ELEMENT (dvd_demux),
|
||||
RESOURCE, FAILED, (NULL), ("Allocation failed"));
|
||||
return;
|
||||
}
|
||||
|
||||
for (i = 0; i < GST_DVD_DEMUX_NUM_SUBPICTURE_STREAMS; i++) {
|
||||
if (dvd_demux->subpicture_stream[i] &&
|
||||
GST_PAD_IS_USABLE (dvd_demux->subpicture_stream[i]->pad)) {
|
||||
discont = gst_event_new_discontinuous (FALSE, GST_FORMAT_TIME,
|
||||
time, NULL);
|
||||
|
||||
gst_event_ref (discont);
|
||||
gst_pad_push (dvd_demux->subpicture_stream[i]->pad, GST_DATA (discont));
|
||||
}
|
||||
}
|
||||
|
||||
/* Distribute the event to the "current" pads. */
|
||||
if (GST_PAD_IS_USABLE (dvd_demux->cur_video)) {
|
||||
discont = gst_event_new_discontinuous (FALSE, GST_FORMAT_TIME, time, NULL);
|
||||
|
||||
gst_event_ref (discont);
|
||||
gst_pad_push (dvd_demux->cur_video, GST_DATA (discont));
|
||||
}
|
||||
|
||||
if (GST_PAD_IS_USABLE (dvd_demux->cur_audio)) {
|
||||
discont = gst_event_new_discontinuous (FALSE, GST_FORMAT_TIME, time, NULL);
|
||||
|
||||
gst_event_ref (discont);
|
||||
gst_pad_push (dvd_demux->cur_audio, GST_DATA (discont));
|
||||
}
|
||||
|
||||
if (GST_PAD_IS_USABLE (dvd_demux->cur_subpicture)) {
|
||||
discont = gst_event_new_discontinuous (FALSE, GST_FORMAT_TIME, time, NULL);
|
||||
|
||||
gst_event_ref (discont);
|
||||
gst_pad_push (dvd_demux->cur_subpicture, GST_DATA (discont));
|
||||
}
|
||||
|
||||
gst_event_unref (discont);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -857,8 +869,12 @@ gst_dvd_demux_send_subbuffer (GstMPEGDemux * mpeg_demux,
|
|||
minimize the time interval between the discontinuity and the data
|
||||
buffers following it. */
|
||||
if (dvd_demux->discont_time != GST_CLOCK_TIME_NONE) {
|
||||
if ((gint64) (dvd_demux->discont_time) < 0) {
|
||||
GST_ERROR ("DVD Discont < 0! % " G_GINT64_FORMAT,
|
||||
(gint64) dvd_demux->discont_time);
|
||||
}
|
||||
PARSE_CLASS (mpeg_demux)->send_discont (mpeg_parse,
|
||||
dvd_demux->discont_time - 200 * GST_MSECOND);
|
||||
dvd_demux->discont_time);
|
||||
dvd_demux->discont_time = GST_CLOCK_TIME_NONE;
|
||||
}
|
||||
|
||||
|
@ -991,7 +1007,7 @@ gst_dvd_demux_reset (GstDVDDemux * dvd_demux)
|
|||
dvd_demux->cur_audio_nr = 0;
|
||||
dvd_demux->cur_subpicture_nr = 0;
|
||||
dvd_demux->mpeg_version = 0;
|
||||
dvd_demux->last_end_ptm = 0;
|
||||
dvd_demux->last_end_ptm = INITIAL_END_PTM;
|
||||
|
||||
dvd_demux->just_flushed = FALSE;
|
||||
dvd_demux->discont_time = GST_CLOCK_TIME_NONE;
|
||||
|
|
|
@ -107,7 +107,7 @@ struct _GstDVDDemux {
|
|||
gboolean just_flushed; /* The element just received a flush event. */
|
||||
GstClockTime discont_time; /* If different from GST_CLOCK_TIME_NONE, a
|
||||
discontinuous event should be sent with the
|
||||
given time, before sending the next dara
|
||||
given time, before sending the next data
|
||||
block.. */
|
||||
|
||||
gint mpeg_version; /* Version of the MPEG video stream */
|
||||
|
|
|
@ -275,13 +275,18 @@ gst_mpeg_demux_send_discont (GstMPEGParse * mpeg_parse, GstClockTime time)
|
|||
gint i;
|
||||
|
||||
GST_DEBUG_OBJECT (mpeg_demux, "discont %" G_GUINT64_FORMAT, time);
|
||||
discont = gst_event_new_discontinuous (FALSE, GST_FORMAT_TIME, time, NULL);
|
||||
|
||||
if (!discont) {
|
||||
GST_ELEMENT_ERROR (GST_ELEMENT (mpeg_demux),
|
||||
RESOURCE, FAILED, (NULL), ("Allocation failed"));
|
||||
return;
|
||||
}
|
||||
|
||||
for (i = 0; i < GST_MPEG_DEMUX_NUM_VIDEO_STREAMS; i++) {
|
||||
if (mpeg_demux->video_stream[i] &&
|
||||
GST_PAD_IS_USABLE (mpeg_demux->video_stream[i]->pad)) {
|
||||
discont = gst_event_new_discontinuous (FALSE, GST_FORMAT_TIME,
|
||||
time, NULL);
|
||||
|
||||
gst_event_ref (discont);
|
||||
gst_pad_push (mpeg_demux->video_stream[i]->pad, GST_DATA (discont));
|
||||
}
|
||||
}
|
||||
|
@ -289,9 +294,7 @@ gst_mpeg_demux_send_discont (GstMPEGParse * mpeg_parse, GstClockTime time)
|
|||
for (i = 0; i < GST_MPEG_DEMUX_NUM_AUDIO_STREAMS; i++) {
|
||||
if (mpeg_demux->audio_stream[i] &&
|
||||
GST_PAD_IS_USABLE (mpeg_demux->audio_stream[i]->pad)) {
|
||||
discont = gst_event_new_discontinuous (FALSE, GST_FORMAT_TIME,
|
||||
time, NULL);
|
||||
|
||||
gst_event_ref (discont);
|
||||
gst_pad_push (mpeg_demux->audio_stream[i]->pad, GST_DATA (discont));
|
||||
}
|
||||
}
|
||||
|
@ -299,12 +302,12 @@ gst_mpeg_demux_send_discont (GstMPEGParse * mpeg_parse, GstClockTime time)
|
|||
for (i = 0; i < GST_MPEG_DEMUX_NUM_PRIVATE_STREAMS; i++) {
|
||||
if (mpeg_demux->private_stream[i] &&
|
||||
GST_PAD_IS_USABLE (mpeg_demux->private_stream[i]->pad)) {
|
||||
discont = gst_event_new_discontinuous (FALSE, GST_FORMAT_TIME,
|
||||
time, NULL);
|
||||
|
||||
gst_event_ref (discont);
|
||||
gst_pad_push (mpeg_demux->private_stream[i]->pad, GST_DATA (discont));
|
||||
}
|
||||
}
|
||||
|
||||
gst_event_unref (discont);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -618,13 +621,13 @@ gst_mpeg_demux_parse_syshead (GstMPEGParse * mpeg_parse, GstBuffer * buffer)
|
|||
|
||||
if (GST_PAD_IS_USABLE (outstream->pad)) {
|
||||
GstEvent *event;
|
||||
gint64 time;
|
||||
GstClockTime time;
|
||||
|
||||
time = MPEGTIME_TO_GSTTIME (mpeg_parse->current_scr
|
||||
+ mpeg_parse->adjust) + mpeg_demux->adjust;
|
||||
|
||||
event = gst_event_new_discontinuous (FALSE, GST_FORMAT_TIME,
|
||||
MPEGTIME_TO_GSTTIME (time), NULL);
|
||||
time, NULL);
|
||||
|
||||
gst_pad_push (outstream->pad, GST_DATA (event));
|
||||
}
|
||||
|
@ -839,11 +842,14 @@ gst_mpeg_demux_parse_pes (GstMPEGParse * mpeg_parse, GstBuffer * buffer)
|
|||
pts |= ((guint64) * buf++) << 7;
|
||||
pts |= ((guint64) (*buf++ & 0xFE)) >> 1;
|
||||
|
||||
GST_DEBUG_OBJECT (mpeg_demux, "0x%02x (%lld) PTS = %" G_GUINT64_FORMAT,
|
||||
id, pts, MPEGTIME_TO_GSTTIME (pts));
|
||||
timestamp =
|
||||
MPEGTIME_TO_GSTTIME (pts + mpeg_parse->adjust) + mpeg_demux->adjust;
|
||||
|
||||
pts += mpeg_parse->adjust;
|
||||
timestamp = MPEGTIME_TO_GSTTIME (pts) + mpeg_demux->adjust;
|
||||
GST_DEBUG_OBJECT (mpeg_demux,
|
||||
"0x%02x (% " G_GINT64_FORMAT ") PTS = %" G_GUINT64_FORMAT
|
||||
" (adjusted = %" G_GINT64_FORMAT ")", id, pts,
|
||||
MPEGTIME_TO_GSTTIME (pts),
|
||||
MPEGTIME_TO_GSTTIME (pts + mpeg_parse->adjust) + mpeg_demux->adjust);
|
||||
} else {
|
||||
timestamp = GST_CLOCK_TIME_NONE;
|
||||
}
|
||||
|
|
|
@ -238,6 +238,7 @@ gst_mpeg_parse_init (GstMPEGParse * mpeg_parse)
|
|||
mpeg_parse->max_discont = DEFAULT_MAX_DISCONT;
|
||||
|
||||
mpeg_parse->do_adjust = TRUE;
|
||||
mpeg_parse->use_adjust = TRUE;
|
||||
|
||||
GST_FLAG_SET (mpeg_parse, GST_ELEMENT_EVENT_AWARE);
|
||||
}
|
||||
|
@ -283,9 +284,10 @@ gst_mpeg_parse_handle_discont (GstMPEGParse * mpeg_parse, GstEvent * event)
|
|||
|
||||
g_return_if_fail (GST_EVENT_TYPE (event) == GST_EVENT_DISCONTINUOUS);
|
||||
|
||||
if (gst_event_discont_get_value (event, GST_FORMAT_TIME, &time)) {
|
||||
GST_DEBUG_OBJECT (mpeg_parse,
|
||||
"forwarding discontinuity, time: %0.3fs", (double) time / GST_SECOND);
|
||||
if (gst_event_discont_get_value (event, GST_FORMAT_TIME, &time)
|
||||
&& (GST_CLOCK_TIME_IS_VALID (time))) {
|
||||
GST_DEBUG_OBJECT (mpeg_parse, "forwarding discontinuity, time: %0.3fs",
|
||||
(double) time / GST_SECOND);
|
||||
|
||||
if (CLASS (mpeg_parse)->send_discont)
|
||||
CLASS (mpeg_parse)->send_discont (mpeg_parse, time);
|
||||
|
@ -452,10 +454,11 @@ gst_mpeg_parse_parse_packhead (GstMPEGParse * mpeg_parse, GstBuffer * buffer)
|
|||
mpeg_parse->current_scr, mpeg_parse->adjust);
|
||||
|
||||
if (mpeg_parse->do_adjust) {
|
||||
mpeg_parse->adjust +=
|
||||
(gint64) mpeg_parse->next_scr - (gint64) mpeg_parse->current_scr;
|
||||
|
||||
GST_DEBUG ("new adjust: %" G_GINT64_FORMAT, mpeg_parse->adjust);
|
||||
if (mpeg_parse->use_adjust) {
|
||||
mpeg_parse->adjust +=
|
||||
(gint64) mpeg_parse->next_scr - (gint64) mpeg_parse->current_scr;
|
||||
GST_DEBUG ("new adjust: %" G_GINT64_FORMAT, mpeg_parse->adjust);
|
||||
}
|
||||
} else {
|
||||
mpeg_parse->discont_pending = TRUE;
|
||||
}
|
||||
|
|
|
@ -65,8 +65,12 @@ struct _GstMPEGParse {
|
|||
guint64 next_scr; /* Expected next SCR. */
|
||||
guint64 bytes_since_scr;
|
||||
|
||||
gboolean do_adjust; /* Adjust timestamps to smooth
|
||||
discontinuities. */
|
||||
gboolean do_adjust; /* If false, send discont events on SCR
|
||||
* jumps
|
||||
*/
|
||||
gboolean use_adjust; /* Collect SCR jumps into 'adjust' in
|
||||
* order to adjust timestamps to smooth
|
||||
* discontinuities. */
|
||||
gint64 adjust; /* Current timestamp adjust value. */
|
||||
|
||||
gboolean discont_pending;
|
||||
|
|
Loading…
Reference in a new issue