/* Adjust buffer timestamps */
offset = reader->start_offset + part_pad->segment.base;
offset -= part_pad->initial_ts_offset;
+ /* We don't add the ts_offset here, because we
+ * want to measure the logical length of the stream,
+ * not to generate output timestamps */
/* Update the stored max duration on the pad,
* always preferring making DTS contiguous
ts = GST_BUFFER_PTS (buf) + offset;
GST_DEBUG_OBJECT (reader, "Pad %" GST_PTR_FORMAT
- " incoming PTS %" GST_TIME_FORMAT
- " DTS %" GST_TIME_FORMAT " offset by %" GST_STIME_FORMAT
+ " incoming DTS %" GST_TIME_FORMAT
+ " PTS %" GST_TIME_FORMAT " offset by %" GST_STIME_FORMAT
" to %" GST_STIME_FORMAT, part_pad,
GST_TIME_ARGS (GST_BUFFER_DTS (buf)),
GST_TIME_ARGS (GST_BUFFER_PTS (buf)),
/* Adjust buffer timestamps */
offset = reader->start_offset + part_pad->segment.base;
offset -= part_pad->initial_ts_offset;
+ offset += reader->ts_offset;
if (GST_BUFFER_PTS_IS_VALID (buf))
GST_BUFFER_PTS (buf) += offset;
goto wrong_segment;
/* Adjust segment */
- /* Adjust start/stop so the overall file is 0 + start_offset based */
+ /* Adjust start/stop so the overall file is 0 + start_offset based,
+ * adding a fixed offset so that DTS is never negative */
if (seg->stop != -1) {
seg->stop -= seg->start;
- seg->stop += seg->time + reader->start_offset;
+ seg->stop += seg->time + reader->start_offset + reader->ts_offset;
}
- seg->start = seg->time + reader->start_offset;
+ seg->start = seg->time + reader->start_offset + reader->ts_offset;
seg->time += reader->start_offset;
seg->position += reader->start_offset;
- GST_LOG_OBJECT (pad, "Adjusted segment now %" GST_PTR_FORMAT, event);
-
/* Replace event */
gst_event_unref (event);
event = gst_event_new_segment (seg);
+ GST_LOG_OBJECT (pad, "Adjusted segment now %" GST_PTR_FORMAT, event);
+
if (reader->prep_state != PART_STATE_PREPARING_COLLECT_STREAMS
&& reader->prep_state != PART_STATE_PREPARING_MEASURE_STREAMS)
break; /* Only do further stuff with segments during initial measuring */
void
gst_splitmux_part_reader_set_start_offset (GstSplitMuxPartReader * reader,
- GstClockTime offset)
+ GstClockTime time_offset, GstClockTime ts_offset)
{
SPLITMUX_PART_LOCK (reader);
- reader->start_offset = offset;
- GST_INFO_OBJECT (reader, "TS offset now %" GST_TIME_FORMAT,
- GST_TIME_ARGS (offset));
+ reader->start_offset = time_offset;
+ reader->ts_offset = ts_offset;
+ GST_INFO_OBJECT (reader, "Time offset now %" GST_TIME_FORMAT,
+ GST_TIME_ARGS (time_offset));
SPLITMUX_PART_UNLOCK (reader);
}
GstClockTime duration;
GstClockTime start_offset;
+ GstClockTime ts_offset;
GList *pads;
gboolean gst_splitmux_part_reader_is_active (GstSplitMuxPartReader *part);
gboolean gst_splitmux_part_reader_src_query (GstSplitMuxPartReader *part, GstPad *src_pad, GstQuery * query);
-void gst_splitmux_part_reader_set_start_offset (GstSplitMuxPartReader *part, GstClockTime offset);
+void gst_splitmux_part_reader_set_start_offset (GstSplitMuxPartReader *part, GstClockTime time_offset, GstClockTime ts_offset);
GstClockTime gst_splitmux_part_reader_get_start_offset (GstSplitMuxPartReader *part);
GstClockTime gst_splitmux_part_reader_get_end_offset (GstSplitMuxPartReader *part);
GstClockTime gst_splitmux_part_reader_get_duration (GstSplitMuxPartReader * reader);
GST_DEBUG_CATEGORY (splitmux_debug);
#define GST_CAT_DEFAULT splitmux_debug
+#define FIXED_TS_OFFSET (1000*GST_SECOND)
+
enum
{
PROP_0,
* seg or play_segment */
if (splitmux->play_segment.rate > 0.0) {
if (splitmux->play_segment.stop != -1)
- seg.stop = splitmux->play_segment.stop;
+ seg.stop = splitmux->play_segment.stop + FIXED_TS_OFFSET;
else
seg.stop = splitpad->segment.stop;
} else {
/* Reverse playback from stop time to start time */
/* See if an end point was requested in the seek */
if (splitmux->play_segment.start != -1) {
- seg.start = splitmux->play_segment.start;
+ seg.start = splitmux->play_segment.start + FIXED_TS_OFFSET;
seg.time = splitmux->play_segment.time;
} else {
seg.start = splitpad->segment.start;
splitmux->parts[idx]->path, idx);
gst_splitmux_part_reader_set_start_offset (splitmux->parts[idx],
- splitmux->end_offset);
+ splitmux->end_offset, FIXED_TS_OFFSET);
if (!gst_splitmux_part_reader_prepare (splitmux->parts[idx])) {
GST_WARNING_OBJECT (splitmux,
"Failed to prepare file part %s. Cannot play past there.",
current_rate = rate;
};
-static void
-receive_handoff (GstElement * object G_GNUC_UNUSED, GstBuffer * buf,
- GstPad * arg1 G_GNUC_UNUSED, gpointer user_data G_GNUC_UNUSED)
+static GstFlowReturn
+receive_sample (GstAppSink * appsink, gpointer user_data G_GNUC_UNUSED)
{
- GstClockTime start = GST_BUFFER_TIMESTAMP (buf);
- GstClockTime end = start;
+ GstSample *sample;
+ GstSegment *seg;
+ GstBuffer *buf;
+ GstClockTime start;
+ GstClockTime end;
+
+ g_signal_emit_by_name (appsink, "pull-sample", &sample);
+ fail_unless (sample != NULL);
+
+ seg = gst_sample_get_segment (sample);
+ fail_unless (seg != NULL);
+
+ buf = gst_sample_get_buffer (sample);
+ fail_unless (buf != NULL);
+
+ GST_LOG ("Got buffer %" GST_PTR_FORMAT, buf);
+
+ start = GST_BUFFER_PTS (buf);
+ end = start;
- if (GST_BUFFER_DURATION_IS_VALID (buf))
- end += GST_BUFFER_DURATION (buf);
+ if (GST_CLOCK_TIME_IS_VALID (start))
+ start = gst_segment_to_stream_time (seg, GST_FORMAT_TIME, start);
- GST_LOG ("Got buffer %" GST_TIME_FORMAT " to %" GST_TIME_FORMAT,
+ if (GST_CLOCK_TIME_IS_VALID (end)) {
+ if (GST_BUFFER_DURATION_IS_VALID (buf))
+ end += GST_BUFFER_DURATION (buf);
+
+ end = gst_segment_to_stream_time (seg, GST_FORMAT_TIME, end);
+ }
+
+ GST_DEBUG ("Got buffer stream time %" GST_TIME_FORMAT " to %" GST_TIME_FORMAT,
GST_TIME_ARGS (start), GST_TIME_ARGS (end));
/* Check time is moving in the right direction */
first_ts = start;
if (!GST_CLOCK_TIME_IS_VALID (last_ts) || end > last_ts)
last_ts = end;
+
+ gst_sample_unref (sample);
+
+ return GST_FLOW_OK;
}
static void
{
GstMessage *msg;
GstElement *pipeline;
- GstElement *fakesink;
+ GstElement *appsink;
GstElement *fakesink2;
+ GstAppSinkCallbacks callbacks = { NULL };
gchar *uri;
+ GST_DEBUG ("Playing back files matching %s", in_pattern);
+
pipeline = gst_element_factory_make ("playbin", NULL);
fail_if (pipeline == NULL);
- fakesink = gst_element_factory_make ("fakesink", NULL);
- fail_if (fakesink == NULL);
- g_object_set (G_OBJECT (pipeline), "video-sink", fakesink, NULL);
+ appsink = gst_element_factory_make ("appsink", NULL);
+ fail_if (appsink == NULL);
+ g_object_set (G_OBJECT (pipeline), "video-sink", appsink, NULL);
fakesink2 = gst_element_factory_make ("fakesink", NULL);
fail_if (fakesink2 == NULL);
g_object_set (G_OBJECT (pipeline), "audio-sink", fakesink2, NULL);
g_object_set (G_OBJECT (pipeline), "uri", uri, NULL);
g_free (uri);
- g_signal_connect (fakesink, "handoff", (GCallback) receive_handoff, NULL);
- g_object_set (G_OBJECT (fakesink), "signal-handoffs", TRUE, NULL);
+ callbacks.new_sample = receive_sample;
+ gst_app_sink_set_callbacks (GST_APP_SINK (appsink), &callbacks, NULL, NULL);
/* test forwards */
seek_pipeline (pipeline, 1.0, 0, -1);
/* Check we saw the entire range of values */
fail_unless (first_ts == exp_first_time,
- "Expected start of playback range 0, got %" GST_TIME_FORMAT,
+ "Expected start of playback range %" GST_TIME_FORMAT ", got %"
+ GST_TIME_FORMAT, GST_TIME_ARGS (exp_first_time),
GST_TIME_ARGS (first_ts));
fail_unless (last_ts == exp_last_time,
- "Expected end of playback range 3s, got %" GST_TIME_FORMAT,
- GST_TIME_ARGS (last_ts));
+ "Expected end of playback range %" GST_TIME_FORMAT ", got %"
+ GST_TIME_FORMAT, GST_TIME_ARGS (exp_last_time), GST_TIME_ARGS (last_ts));
if (test_reverse) {
/* Test backwards */