packet->granulepos);
GST_DEBUG_OBJECT (ogg, "new granule %" G_GUINT64_FORMAT,
pad->current_granule);
- } else if (ogg->segment.rate > 0.0 && pad->current_granule != -1) {
+ } else if (pad->current_granule != -1) {
pad->current_granule += duration;
if (!delta_unit) {
pad->keyframe_granule = pad->current_granule;
GST_DEBUG_OBJECT (ogg, "interpolating granule %" G_GUINT64_FORMAT,
pad->current_granule);
}
- if (ogg->segment.rate < 0.0 && packet->granulepos == -1) {
- /* negative rates, only set timestamp on the packets with a granulepos */
+
+ if (ogg->segment.rate < 0.0 && pad->current_granule == -1) {
+ /* negative rates, allow output of packets with no timestamp, let downstream reconstruct */
out_timestamp = -1;
out_duration = -1;
out_offset = -1;
out_offset_end = -1;
+ pad->prev_granule = -1;
} else {
/* we only push buffers after we have a valid granule. This is done so that
* we nicely skip packets without a timestamp after a seek. This is ok
- * because we base or seek on the packet after the page with the smaller
+ * because we base our seek on the packet after the page with the smaller
* timestamp. */
- if (pad->current_granule == -1)
+ if (pad->current_granule == -1) {
+ pad->prev_granule = -1;
goto no_timestamp;
+ }
if (pad->map.is_ogm) {
out_timestamp = gst_ogg_stream_granule_to_time (&pad->map,
/* Mark discont on the buffer */
if (pad->discont) {
GST_BUFFER_FLAG_SET (buf, GST_BUFFER_FLAG_DISCONT);
- if GST_BUFFER_TIMESTAMP_IS_VALID
- (buf)
- pad->discont = FALSE;
+ if (ogg->segment.rate < 0.0 || GST_BUFFER_TIMESTAMP_IS_VALID (buf))
+ pad->discont = FALSE;
}
/* don't push the header packets when we are asked to skip them */
static void
gst_ogg_pad_mark_discont (GstOggPad * pad)
{
+ GST_LOG_OBJECT (pad, "Marking discont on pad");
pad->discont = TRUE;
pad->map.last_size = 0;
}
granule_time = gst_ogg_stream_get_end_time_for_granulepos (&pad->map,
granulepos);
+ /* Convert to stream time */
+ granule_time -= pad->start_time;
+ granule_time += chain->begin_time;
+
GST_LOG_OBJECT (ogg,
- "looking at page with ts %" GST_TIME_FORMAT ", target %"
+ "looking at page with time %" GST_TIME_FORMAT ", target %"
GST_TIME_FORMAT, GST_TIME_ARGS (granule_time),
GST_TIME_ARGS (target));
if (granule_time < target)
}
static GstFlowReturn
-gst_ogg_demux_handle_page (GstOggDemux * ogg, ogg_page * page)
+gst_ogg_demux_handle_page (GstOggDemux * ogg, ogg_page * page, gboolean discont)
{
GstOggPad *pad;
gint64 granule;
pad = gst_ogg_demux_find_pad (ogg, serialno);
}
if (pad) {
+ /* Reset granule interpolation if chaining in reverse (discont = TRUE) */
+ if (discont)
+ pad->current_granule = -1;
+
result = gst_ogg_pad_submit_page (pad, page);
} else {
GST_PUSH_LOCK (ogg);
/* discontinuity in the pages */
GST_DEBUG_OBJECT (ogg, "discont in page found, continuing");
} else {
- result = gst_ogg_demux_handle_page (ogg, &page);
+ result = gst_ogg_demux_handle_page (ogg, &page, FALSE);
if (result < 0) {
GST_DEBUG_OBJECT (ogg, "gst_ogg_demux_handle_page returned %d", result);
}
ogg->newsegment = NULL;
}
- ret = gst_ogg_demux_handle_page (ogg, &page);
+ GST_LOG_OBJECT (ogg, "Handling page at offset %" G_GINT64_FORMAT,
+ ogg->offset);
+ ret = gst_ogg_demux_handle_page (ogg, &page, TRUE);
done:
return ret;