summaryrefslogtreecommitdiff
path: root/gst
diff options
context:
space:
mode:
authorWim Taymans <wim.taymans@collabora.co.uk>2012-09-13 13:49:33 +0200
committerWim Taymans <wim.taymans@collabora.co.uk>2012-09-13 13:49:33 +0200
commitc3b5d7e914b8972e6b824b7552adb15a0cd80c2a (patch)
treeea21e4b2fa05bf2503c52472a6e75b85969dd275 /gst
parentddd13808b324f89dd4ab8a978331cccff2f161f8 (diff)
rmdemux: use DTS and PTS
Video uses DTS as timestamps. Set the DTS on the buffers and leave the PTS undefined to make the decoder do the right thing. We can then remove the code that tries to guess the PTS from the DTS.
Diffstat (limited to 'gst')
-rw-r--r--gst/realmedia/rmdemux.c176
1 files changed, 29 insertions, 147 deletions
diff --git a/gst/realmedia/rmdemux.c b/gst/realmedia/rmdemux.c
index 10cb9f03..42529405 100644
--- a/gst/realmedia/rmdemux.c
+++ b/gst/realmedia/rmdemux.c
@@ -963,7 +963,11 @@ gst_rmdemux_chain (GstPad * pad, GstObject * parent, GstBuffer * buffer)
GstRMDemux *rmdemux = GST_RMDEMUX (parent);
if (rmdemux->base_ts == -1) {
- rmdemux->base_ts = GST_BUFFER_TIMESTAMP (buffer);
+ if (GST_BUFFER_DTS_IS_VALID (buffer))
+ rmdemux->base_ts = GST_BUFFER_DTS (buffer);
+ else
+ rmdemux->base_ts = GST_BUFFER_PTS (buffer);
+
GST_LOG_OBJECT (rmdemux, "base_ts %" GST_TIME_FORMAT,
GST_TIME_ARGS (rmdemux->base_ts));
}
@@ -1947,8 +1951,10 @@ gst_rmdemux_descramble_audio (GstRMDemux * rmdemux, GstRMDemuxStream * stream)
gst_buffer_map (b, &map, GST_MAP_READ);
- if (p == 0)
- GST_BUFFER_TIMESTAMP (outbuf) = GST_BUFFER_TIMESTAMP (b);
+ if (p == 0) {
+ GST_BUFFER_PTS (outbuf) = GST_BUFFER_PTS (b);
+ GST_BUFFER_DTS (outbuf) = GST_BUFFER_DTS (b);
+ }
for (x = 0; x < packet_size / leaf_size; ++x) {
guint idx;
@@ -1971,8 +1977,9 @@ gst_rmdemux_descramble_audio (GstRMDemux * rmdemux, GstRMDemuxStream * stream)
gst_buffer_copy_region (outbuf, GST_BUFFER_COPY_ALL, p * packet_size,
packet_size);
- GST_LOG_OBJECT (rmdemux, "pushing buffer timestamp %" GST_TIME_FORMAT,
- GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (subbuf)));
+ GST_LOG_OBJECT (rmdemux, "pushing buffer dts %" GST_TIME_FORMAT ", pts %"
+ GST_TIME_FORMAT, GST_TIME_ARGS (GST_BUFFER_DTS (subbuf)),
+ GST_TIME_ARGS (GST_BUFFER_PTS (subbuf)));
if (stream->discont) {
GST_BUFFER_FLAG_SET (subbuf, GST_BUFFER_FLAG_DISCONT);
@@ -2027,7 +2034,7 @@ gst_rmdemux_descramble_mp4a_audio (GstRMDemux * rmdemux,
g_ptr_array_set_size (stream->subpackets, 0);
gst_buffer_map (buf, &map, GST_MAP_READ);
- timestamp = GST_BUFFER_TIMESTAMP (buf);
+ timestamp = GST_BUFFER_PTS (buf);
frames = (map.data[1] & 0xf0) >> 4;
index = 2 * frames + 2;
@@ -2036,8 +2043,10 @@ gst_rmdemux_descramble_mp4a_audio (GstRMDemux * rmdemux,
guint len = (map.data[i * 2 + 2] << 8) | map.data[i * 2 + 3];
outbuf = gst_buffer_copy_region (buf, GST_BUFFER_COPY_ALL, index, len);
- if (i == 0)
- GST_BUFFER_TIMESTAMP (outbuf) = timestamp;
+ if (i == 0) {
+ GST_BUFFER_PTS (outbuf) = timestamp;
+ GST_BUFFER_DTS (outbuf) = timestamp;
+ }
index += len;
@@ -2076,15 +2085,18 @@ gst_rmdemux_descramble_sipr_audio (GstRMDemux * rmdemux,
for (p = 0; p < height; ++p) {
GstBuffer *b = g_ptr_array_index (stream->subpackets, p);
- if (p == 0)
- GST_BUFFER_TIMESTAMP (outbuf) = GST_BUFFER_TIMESTAMP (b);
+ if (p == 0) {
+ GST_BUFFER_DTS (outbuf) = GST_BUFFER_DTS (b);
+ GST_BUFFER_PTS (outbuf) = GST_BUFFER_PTS (b);
+ }
gst_buffer_extract (b, 0, outmap.data + packet_size * p, packet_size);
}
gst_buffer_unmap (outbuf, &outmap);
- GST_LOG_OBJECT (rmdemux, "pushing buffer timestamp %" GST_TIME_FORMAT,
- GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (outbuf)));
+ GST_LOG_OBJECT (rmdemux, "pushing buffer dts %" GST_TIME_FORMAT ", pts %"
+ GST_TIME_FORMAT, GST_TIME_ARGS (GST_BUFFER_DTS (outbuf)),
+ GST_TIME_ARGS (GST_BUFFER_PTS (outbuf)));
if (stream->discont) {
GST_BUFFER_FLAG_SET (outbuf, GST_BUFFER_FLAG_DISCONT);
@@ -2147,136 +2159,6 @@ gst_rmdemux_handle_scrambled_packet (GstRMDemux * rmdemux,
return ret;
}
-static GstClockTime
-gst_rmdemux_fix_timestamp (GstRMDemux * rmdemux, GstRMDemuxStream * stream,
- guint8 * data, GstClockTime timestamp)
-{
- guint8 frame_type;
- guint16 seq;
- GstClockTime ts = timestamp;
-
- if (timestamp == GST_CLOCK_TIME_NONE)
- goto done;
-
- /* only adjust when we have a stream with B frames */
- if (stream->format < 0x20200002)
- goto done;
-
- /* Fix timestamp. */
- switch (stream->fourcc) {
- case GST_RM_VDO_RV10:
- goto done;
- case GST_RM_VDO_RV20:
- {
- /*
- * Bit 1- 2: frame type
- * Bit 3- 9: ?
- * Bit 10-22: sequence number
- * Bit 23-32: ?
- */
- frame_type = (data[0] >> 6) & 0x03;
- seq = ((data[1] & 0x7f) << 6) + ((data[2] & 0xfc) >> 2);
- break;
- }
- case GST_RM_VDO_RV30:
- {
- /*
- * Bit 1- 2: ?
- * Bit 3: skip packet if 1
- * Bit 4- 5: frame type
- * Bit 6-12: ?
- * Bit 13-25: sequence number
- * Bit 26-32: ?
- */
- frame_type = (data[0] >> 3) & 0x03;
- seq = ((data[1] & 0x0f) << 9) + (data[2] << 1) + ((data[3] & 0x80) >> 7);
- break;
- }
- case GST_RM_VDO_RV40:
- {
- /*
- * Bit 1: skip packet if 1
- * Bit 2- 3: frame type
- * Bit 4-13: ?
- * Bit 14-26: sequence number
- * Bit 27-32: ?
- */
- frame_type = (data[0] >> 5) & 0x03;
- seq = ((data[1] & 0x07) << 10) + (data[2] << 2) + ((data[3] & 0xc0) >> 6);
- break;
- }
- default:
- goto unknown_version;
- }
-
- switch (frame_type) {
- case 0:
- case 1:
- {
- GST_LOG_OBJECT (rmdemux, "I frame %d", frame_type);
- /* I frame */
- if (stream->next_ts == -1)
- stream->next_ts = timestamp;
- else
- timestamp = stream->next_ts;
- stream->last_ts = stream->next_ts;
- stream->next_ts = ts;
- stream->last_seq = stream->next_seq;
- stream->next_seq = seq;
- break;
- }
- case 2:
- {
- GST_LOG_OBJECT (rmdemux, "P frame");
- /* P frame */
- timestamp = stream->last_ts = stream->next_ts;
- if (seq < stream->next_seq)
- stream->next_ts += (seq + 0x2000 - stream->next_seq) * GST_MSECOND;
- else
- stream->next_ts += (seq - stream->next_seq) * GST_MSECOND;
- stream->last_seq = stream->next_seq;
- stream->next_seq = seq;
- break;
- }
- case 3:
- {
- GST_LOG_OBJECT (rmdemux, "B frame");
- /* B frame */
- if (seq < stream->last_seq) {
- timestamp =
- (seq + 0x2000 - stream->last_seq) * GST_MSECOND + stream->last_ts;
- } else {
- timestamp = (seq - stream->last_seq) * GST_MSECOND + stream->last_ts;
- }
- break;
- }
- default:
- goto unknown_frame_type;
- }
-
-done:
- GST_LOG_OBJECT (rmdemux,
- "timestamp %" GST_TIME_FORMAT " -> %" GST_TIME_FORMAT, GST_TIME_ARGS (ts),
- GST_TIME_ARGS (timestamp));
-
- return timestamp;
-
- /* Errors */
-unknown_version:
- {
- GST_ELEMENT_ERROR (rmdemux, STREAM, DECODE,
- ("Unknown version: %i.", stream->version), (NULL));
- return GST_FLOW_ERROR;
- }
-
-unknown_frame_type:
- {
- GST_ELEMENT_ERROR (rmdemux, STREAM, DECODE, ("Unknown frame type %d.",
- frame_type), (NULL));
- return GST_FLOW_ERROR;
- }
-}
-
#define PARSE_NUMBER(data, size, number, label) \
G_STMT_START { \
if (size < 2) \
@@ -2459,12 +2341,11 @@ gst_rmdemux_parse_video_packet (GstRMDemux * rmdemux, GstRMDemuxStream * stream,
if (rmdemux->base_ts != -1)
timestamp += rmdemux->base_ts;
}
- timestamp =
- gst_rmdemux_fix_timestamp (rmdemux, stream, outdata, timestamp);
-
gst_buffer_unmap (out, &outmap);
- GST_BUFFER_TIMESTAMP (out) = timestamp;
+ /* video has DTS */
+ GST_BUFFER_DTS (out) = timestamp;
+ GST_BUFFER_PTS (out) = GST_CLOCK_TIME_NONE;
GST_LOG_OBJECT (rmdemux, "pushing timestamp %" GST_TIME_FORMAT,
GST_TIME_ARGS (timestamp));
@@ -2532,7 +2413,8 @@ gst_rmdemux_parse_audio_packet (GstRMDemux * rmdemux, GstRMDemuxStream * stream,
if (rmdemux->base_ts != -1)
timestamp += rmdemux->base_ts;
- GST_BUFFER_TIMESTAMP (buffer) = timestamp;
+ GST_BUFFER_PTS (buffer) = timestamp;
+ GST_BUFFER_DTS (buffer) = timestamp;
if (stream->needs_descrambling) {
GST_LOG_OBJECT (rmdemux, "descramble timestamp %" GST_TIME_FORMAT,