ext/dvdread/dvdreadsrc.c: Allow and implement non-flushing and/or segment seek (mainly in TIME and chapter format).

Original commit message from CVS:
* ext/dvdread/dvdreadsrc.c: (gst_dvd_read_src_read),
(gst_dvd_read_src_create), (gst_dvd_read_src_handle_seek_event):
Allow and implement non-flushing and/or segment seek
(mainly in TIME and chapter format).
* gst/mpegstream/gstdvddemux.c: (gst_dvd_demux_process_event),
(gst_dvd_demux_get_subpicture_stream),
(gst_dvd_demux_synchronise_pads),
(gst_dvd_demux_sync_stream_to_time):
* gst/mpegstream/gstmpegdemux.c: (gst_mpeg_demux_process_event),
(gst_mpeg_demux_send_subbuffer),
(gst_mpeg_demux_sync_stream_to_time),
(gst_mpeg_streams_reset_cur_ts):
* gst/mpegstream/gstmpegdemux.h:
* gst/mpegstream/gstmpegparse.c: (gst_mpeg_parse_process_event),
(gst_mpeg_parse_pad_added), (gst_mpeg_parse_handle_src_query):
Delegate a query to upstream if it can't be handled.
Make segment stop aware.
Fix (subtitle) stream synchronization.
Add some debug statements.
This commit is contained in:
Mark Nauwelaerts 2008-06-27 12:58:35 +00:00
parent 8c0a922780
commit a977cd5ac6
6 changed files with 127 additions and 33 deletions

View file

@ -1,3 +1,25 @@
2008-06-27 Mark Nauwelaerts <mark.nauwelaerts@collabora.co.uk>
* ext/dvdread/dvdreadsrc.c: (gst_dvd_read_src_read),
(gst_dvd_read_src_create), (gst_dvd_read_src_handle_seek_event):
Allow and implement non-flushing and/or segment seek
(mainly in TIME and chapter format).
* gst/mpegstream/gstdvddemux.c: (gst_dvd_demux_process_event),
(gst_dvd_demux_get_subpicture_stream),
(gst_dvd_demux_synchronise_pads),
(gst_dvd_demux_sync_stream_to_time):
* gst/mpegstream/gstmpegdemux.c: (gst_mpeg_demux_process_event),
(gst_mpeg_demux_send_subbuffer),
(gst_mpeg_demux_sync_stream_to_time),
(gst_mpeg_streams_reset_cur_ts):
* gst/mpegstream/gstmpegdemux.h:
* gst/mpegstream/gstmpegparse.c: (gst_mpeg_parse_process_event),
(gst_mpeg_parse_pad_added), (gst_mpeg_parse_handle_src_query):
Delegate a query to upstream if it can't be handled.
Make segment stop aware.
Fix (subtitle) stream synchronization.
Add some debug statements.
2008-06-26 Edward Hervey <edward.hervey@collabora.co.uk>
* gst/mpegaudioparse/gstmpegaudioparse.c: (head_check):

View file

@ -724,11 +724,15 @@ gst_dvd_read_src_read (GstDvdReadSrc * src, gint angle, gint new_seek,
GstBuffer ** p_buf)
{
GstBuffer *buf;
GstSegment *seg;
guint8 oneblock[DVD_VIDEO_LB_LEN];
dsi_t dsi_pack;
guint next_vobu, next_ilvu_start, cur_output_size;
gint len;
gint retries;
gint64 next_time;
seg = &(GST_BASE_SRC (src)->segment);
/* playback by cell in this pgc, starting at the cell for our chapter */
if (new_seek)
@ -738,8 +742,12 @@ again:
if (src->cur_cell >= src->last_cell) {
/* advance to next chapter */
if (src->chapter == (src->num_chapters - 1))
if (src->chapter == (src->num_chapters - 1) ||
(seg->format == chapter_format && seg->stop != -1 &&
src->chapter == (seg->stop - 1))) {
GST_DEBUG_OBJECT (src, "end of chapter segment");
goto eos;
}
GST_INFO_OBJECT (src, "end of chapter %d, switch to next",
src->chapter + 1);
@ -847,16 +855,24 @@ nav_retry:
*p_buf = buf;
GST_LOG_OBJECT (src, "Read %u sectors", cur_output_size);
src->cur_pack = next_vobu;
GST_LOG_OBJECT (src, "Read %u sectors", cur_output_size);
next_time = GST_BUFFER_TIMESTAMP (buf);
if (GST_CLOCK_TIME_IS_VALID (next_time) && seg->format == GST_FORMAT_TIME &&
GST_CLOCK_TIME_IS_VALID (seg->stop) &&
next_time > seg->stop + 5 * GST_SECOND) {
GST_DEBUG_OBJECT (src, "end of TIME segment");
goto eos;
}
return GST_DVD_READ_OK;
/* ERRORS */
eos:
{
GST_INFO_OBJECT (src, "last chapter done - EOS");
GST_INFO_OBJECT (src, "Reached end-of-segment/stream - EOS");
return GST_DVD_READ_EOS;
}
read_error:
@ -920,7 +936,6 @@ gst_dvd_read_src_create (GstPushSrc * pushsrc, GstBuffer ** p_buf)
return GST_FLOW_ERROR;
}
case GST_DVD_READ_EOS:{
GST_INFO_OBJECT (src, "Reached EOS");
return GST_FLOW_UNEXPECTED;
}
case GST_DVD_READ_OK:{
@ -1060,19 +1075,12 @@ gst_dvd_read_src_handle_seek_event (GstDvdReadSrc * src, GstEvent * event)
return FALSE;
}
if ((flags & GST_SEEK_FLAG_SEGMENT) != 0) {
GST_DEBUG_OBJECT (src, "segment seek not supported");
return FALSE;
}
if ((flags & GST_SEEK_FLAG_FLUSH) == 0) {
GST_DEBUG_OBJECT (src, "can only do flushing seeks at the moment");
return FALSE;
}
if (end_type != GST_SEEK_TYPE_NONE) {
GST_DEBUG_OBJECT (src, "end seek type not supported");
return FALSE;
if ((format != chapter_format && format != GST_FORMAT_TIME) ||
end_type != GST_SEEK_TYPE_SET) {
GST_DEBUG_OBJECT (src, "end seek type not supported");
return FALSE;
}
}
if (cur_type != GST_SEEK_TYPE_SET) {

View file

@ -309,6 +309,10 @@ gst_dvd_demux_process_event (GstMPEGParse * mpeg_parse, GstEvent * event)
may mean that we find some audio blocks lying outside the
segment. Filter them. */
dvd_demux->segment_filter = TRUE;
/* reset stream synchronization; parent handles other streams */
gst_mpeg_streams_reset_cur_ts (dvd_demux->subpicture_stream,
GST_DVD_DEMUX_NUM_SUBPICTURE_STREAMS, 0);
}
ret = GST_MPEG_PARSE_CLASS (parent_class)->process_event (mpeg_parse,
@ -733,9 +737,6 @@ gst_dvd_demux_get_subpicture_stream (GstMPEGDemux * mpeg_demux,
}
if (add_pad) {
gst_pad_set_active (str->pad, TRUE);
gst_element_add_pad (GST_ELEMENT (mpeg_demux), str->pad);
if (dvd_demux->langcodes) {
gchar *t;
@ -744,15 +745,21 @@ gst_dvd_demux_get_subpicture_stream (GstMPEGDemux * mpeg_demux,
gst_structure_get_string (gst_event_get_structure (dvd_demux->
langcodes), t);
g_free (t);
}
if (lang_code) {
GstTagList *list = gst_tag_list_new ();
GST_DEBUG_OBJECT (mpeg_demux, "adding pad %s with language = %s",
GST_PAD_NAME (str->pad), (lang_code) ? lang_code : "(unknown)");
gst_tag_list_add (list, GST_TAG_MERGE_REPLACE,
GST_TAG_LANGUAGE_CODE, lang_code, NULL);
gst_element_found_tags_for_pad (GST_ELEMENT (mpeg_demux),
str->pad, list);
}
gst_pad_set_active (str->pad, TRUE);
gst_element_add_pad (GST_ELEMENT (mpeg_demux), str->pad);
if (lang_code) {
GstTagList *list = gst_tag_list_new ();
gst_tag_list_add (list, GST_TAG_MERGE_REPLACE,
GST_TAG_LANGUAGE_CODE, lang_code, NULL);
gst_element_found_tags_for_pad (GST_ELEMENT (mpeg_demux),
str->pad, list);
}
}
str->type = GST_DVD_DEMUX_SUBP_DVD;
@ -1155,6 +1162,14 @@ gst_dvd_demux_synchronise_pads (GstMPEGDemux * mpeg_demux,
parent_class->synchronise_pads (mpeg_demux, threshold, new_ts);
for (i = 0; i < GST_DVD_DEMUX_NUM_SUBPICTURE_STREAMS; i++) {
#ifndef GST_DISABLE_DEBUG
if (dvd_demux->subpicture_stream[i]) {
GST_LOG_OBJECT (mpeg_demux, "stream: %d, current: %" GST_TIME_FORMAT
", threshold %" GST_TIME_FORMAT, i,
GST_TIME_ARGS (dvd_demux->subpicture_stream[i]->cur_ts),
GST_TIME_ARGS (threshold));
}
#endif
if (dvd_demux->subpicture_stream[i]
&& (dvd_demux->subpicture_stream[i]->cur_ts < threshold)) {
DEMUX_CLASS (mpeg_demux)->sync_stream_to_time (mpeg_demux,
@ -1193,9 +1208,13 @@ gst_dvd_demux_sync_stream_to_time (GstMPEGDemux * mpeg_demux,
}
if (outpad && (cur_nr == stream->number)) {
guint64 update_time;
update_time =
MIN ((guint64) last_ts, (guint64) mpeg_parse->current_segment.stop);
gst_pad_push_event (outpad, gst_event_new_new_segment (TRUE,
mpeg_parse->current_segment.rate, GST_FORMAT_TIME,
last_ts, -1, last_ts));
update_time, mpeg_parse->current_segment.stop, update_time));
}
}

View file

@ -252,6 +252,15 @@ gst_mpeg_demux_process_event (GstMPEGParse * mpeg_parse, GstEvent * event)
gst_mpeg_streams_reset_last_flow (demux->private_stream,
GST_MPEG_DEMUX_NUM_PRIVATE_STREAMS);
break;
case GST_EVENT_NEWSEGMENT:
/* reset stream synchronization */
gst_mpeg_streams_reset_cur_ts (demux->video_stream,
GST_MPEG_DEMUX_NUM_VIDEO_STREAMS, 0);
gst_mpeg_streams_reset_cur_ts (demux->audio_stream,
GST_MPEG_DEMUX_NUM_AUDIO_STREAMS, 0);
gst_mpeg_streams_reset_cur_ts (demux->private_stream,
GST_MPEG_DEMUX_NUM_PRIVATE_STREAMS, 0);
/* fallthrough */
default:
ret = GST_MPEG_PARSE_CLASS (parent_class)->process_event (mpeg_parse,
event);
@ -1011,7 +1020,7 @@ gst_mpeg_demux_send_subbuffer (GstMPEGDemux * mpeg_demux,
GST_FORMAT_BYTES,
GST_BUFFER_OFFSET (buffer), GST_FORMAT_TIME, timestamp, 0);
}
} else
} else if (mpeg_parse->current_ts != GST_CLOCK_TIME_NONE)
outstream->cur_ts = mpeg_parse->current_ts + outstream->scr_offs;
if (size == 0)
@ -1036,6 +1045,11 @@ gst_mpeg_demux_send_subbuffer (GstMPEGDemux * mpeg_demux,
GST_LOG_OBJECT (outstream->pad, "flow: %s", gst_flow_get_name (ret));
++outstream->buffers_sent;
GST_LOG_OBJECT (mpeg_demux, "current: %" GST_TIME_FORMAT
", gap %" GST_TIME_FORMAT ", tol: %" GST_TIME_FORMAT,
GST_TIME_ARGS (mpeg_parse->current_ts),
GST_TIME_ARGS (mpeg_demux->max_gap),
GST_TIME_ARGS (mpeg_demux->max_gap_tolerance));
if (GST_CLOCK_TIME_IS_VALID (mpeg_demux->max_gap) &&
GST_CLOCK_TIME_IS_VALID (mpeg_parse->current_ts) &&
(mpeg_parse->current_ts > mpeg_demux->max_gap)) {
@ -1114,12 +1128,15 @@ gst_mpeg_demux_sync_stream_to_time (GstMPEGDemux * mpeg_demux,
GstMPEGStream * stream, GstClockTime last_ts)
{
GstMPEGParse *mpeg_parse = GST_MPEG_PARSE (mpeg_demux);
guint64 update_time;
update_time =
MIN ((guint64) last_ts, (guint64) mpeg_parse->current_segment.stop);
gst_pad_push_event (stream->pad, gst_event_new_new_segment (TRUE,
mpeg_parse->current_segment.rate, GST_FORMAT_TIME,
last_ts, -1, last_ts));
update_time, mpeg_parse->current_segment.stop, update_time));
mpeg_parse->current_segment.start = last_ts;
mpeg_parse->current_segment.last_stop = update_time;
}
#if 0
@ -1367,6 +1384,18 @@ gst_mpeg_streams_reset_last_flow (GstMPEGStream * streams[], guint num)
}
}
void
gst_mpeg_streams_reset_cur_ts (GstMPEGStream * streams[], guint num,
GstClockTime cur_ts)
{
guint i;
for (i = 0; i < num; ++i) {
if (streams[i] != NULL)
streams[i]->cur_ts = cur_ts;
}
}
gboolean
gst_mpeg_demux_plugin_init (GstPlugin * plugin)
{

View file

@ -206,6 +206,9 @@ struct _GstMPEGDemuxClass {
void gst_mpeg_streams_reset_last_flow (GstMPEGStream *streams[],
guint num);
void gst_mpeg_streams_reset_cur_ts (GstMPEGStream *streams[],
guint num,
GstClockTime cur_ts);
GType gst_mpeg_demux_get_type (void);

View file

@ -383,9 +383,16 @@ gst_mpeg_parse_process_event (GstMPEGParse * mpeg_parse, GstEvent * event)
if (CLASS (mpeg_parse)->send_event) {
CLASS (mpeg_parse)->send_event (mpeg_parse,
gst_event_new_new_segment (FALSE, rate, GST_FORMAT_TIME,
start, -1, time));
start, stop, time));
mpeg_parse->pending_newsegment = FALSE;
}
}
} else if (format != GST_FORMAT_TIME && !update) {
GST_DEBUG_OBJECT (mpeg_parse,
"Received non-time newsegment from stream");
mpeg_parse->do_adjust = TRUE;
mpeg_parse->adjust = 0;
mpeg_parse->pending_newsegment = TRUE;
}
mpeg_parse->packetize->resync = TRUE;
@ -488,7 +495,7 @@ gst_mpeg_parse_pad_added (GstElement * element, GstPad * pad)
event = gst_event_new_new_segment (FALSE,
mpeg_parse->current_segment.rate,
GST_FORMAT_TIME, mpeg_parse->current_segment.start,
-1, mpeg_parse->current_segment.start);
mpeg_parse->current_segment.stop, mpeg_parse->current_segment.start);
gst_pad_push_event (pad, event);
}
@ -1038,6 +1045,8 @@ gst_mpeg_parse_handle_src_query (GstPad * pad, GstQuery * query)
/* Convert the value to the desired format. */
if ((res = gst_mpeg_parse_convert (mpeg_parse, src_format, src_value,
&format, &value)) ||
(res = gst_pad_query_peer_duration (mpeg_parse->sinkpad,
&format, &value))) {
gst_query_set_duration (query, format, value);
}
@ -1067,6 +1076,8 @@ gst_mpeg_parse_handle_src_query (GstPad * pad, GstQuery * query)
/* Convert the value to the desired format. */
if ((res = gst_mpeg_parse_convert (mpeg_parse, src_format, src_value,
&format, &value)) ||
(res = gst_pad_query_peer_position (mpeg_parse->sinkpad,
&format, &value))) {
gst_query_set_position (query, format, value);
}
@ -1076,7 +1087,9 @@ gst_mpeg_parse_handle_src_query (GstPad * pad, GstQuery * query)
gst_query_parse_convert (query, &src_format, &src_value, &format, NULL);
if ((res = gst_mpeg_parse_convert (mpeg_parse, src_format, src_value,
&format, &value))) {
&format, &value)) ||
(res = gst_pad_query_peer_convert (mpeg_parse->sinkpad,
src_format, src_value, &format, &value))) {
gst_query_set_convert (query, src_format, src_value, format, value);
}
break;