On Thu, 8 Jul 2010, Ronald S. Bultje wrote:

> On Thu, Jul 8, 2010 at 4:02 AM, Martin Storsjö <[email protected]> wrote:
> > On Wed, 7 Jul 2010, Josh Allmann wrote:
> >> +    if (qdm->timestamp != (uint32_t) -1) {
> >> +        pkt->pts       = qdm->timestamp;
> >> +        qdm->timestamp = -1;
> >> +    } else
> >> +        pkt->pts       = AV_NOPTS_VALUE;
> >
> > This isn't right. (Now I see that something similar slipped through in the
> > svq3 patch, too, but with less impact.)
> >
> > pkt->pts is set (in this case, overwritten) by finalize_packet in
> > rtpdec.c, where it calculates a proper timestamp using RTCP sync and all
> > that.
> >
> > If we want to base that calculation on another RTP timestamp, we need to
> > return the timestamp we want via *timestamp qdm2_parse_packet, so that
> > timestamp is used in the RTP timestamp -> realtime timestamp calculation
> > in finalize_packet.
> >
> > Also, for the follow-up cases, where no data is provided to
> > qdm2_parse_packet but we return some already buffered data, lines 411-415
> > in rtpdec.c, we don't know the RTP timestamp, so it is left at 0 unless
> > the depacketizer overwrites it.
> >
> > The problematic case is if we explicitly want to set pkt->pts to
> > AV_NOPTS_VALUE, since the timestamp pointer/value is an uint32_t, and we
> > can't pass an AV_NOPTS_VALUE there. We could introduce an (uint32_t)-1,
> > which would be interpreted as "don't set pkt->pts".
> 
> I think I wrote this to ensure timestamps are increasing (rather than
> staying the same) when a single RTP packet contains multiple QDM2
> frames. Feel free to solve this in any way you think is best, this is
> admittedly a hack.
> 
> I haven't looked at the SVQ3 code to see what's up there, but I think
> we shouldn't have to do anything unless you can have multiple SVQ3
> frames in one RTP packet. Timestamp code there can likely be removed
> with no side-effects...

Yes, it shouldn't really be necessary at all there, but setting it (in a 
corrected way) may be more correct in some scenarios with dropped packets.

The attached patches allows depacketizers to specify that they want 
AV_NOPTS_VALUE by returning RTP_NOTS_VALUE in *timestamp, and fix up the 
svq3 depacketizers to handle timestamps correctly.

Josh, when/if we apply this, you should be able to change the code that 
does

if (foo)
   pkt->pts = qdm->timestamp;
else
   pkt->pts = AV_NOPTS_VALUE;

into

if (foo)
   *timestamp = qdm->timestamp;
else
   *timestamp = RTP_NOTS_VALUE;

// Martin
From 61f741a8e9c24b4e9926326f701cedad5218816f Mon Sep 17 00:00:00 2001
From: Martin Storsjo <[email protected]>
Date: Thu, 8 Jul 2010 22:13:08 +0300
Subject: [PATCH 1/2] Allow depacketizers to specify that pkt->pts should be left as AV_NOPTS_VALUE

---
 libavformat/rtpdec.c |    6 ++++--
 libavformat/rtpdec.h |    2 ++
 2 files changed, 6 insertions(+), 2 deletions(-)

diff --git a/libavformat/rtpdec.c b/libavformat/rtpdec.c
index ca06bff..4922ce3 100644
--- a/libavformat/rtpdec.c
+++ b/libavformat/rtpdec.c
@@ -375,7 +375,7 @@ rtp_parse_set_dynamic_protocol(RTPDemuxContext *s, PayloadContext *ctx,
  */
 static void finalize_packet(RTPDemuxContext *s, AVPacket *pkt, uint32_t timestamp)
 {
-    if (s->last_rtcp_ntp_time != AV_NOPTS_VALUE) {
+    if (s->last_rtcp_ntp_time != AV_NOPTS_VALUE && timestamp != RTP_NOTS_VALUE) {
         int64_t addend;
         int delta_timestamp;
 
@@ -408,7 +408,9 @@ int rtp_parse_packet(RTPDemuxContext *s, AVPacket *pkt,
     if (!buf) {
         /* return the next packets, if any */
         if(s->st && s->parse_packet) {
-            timestamp= 0; ///< Should not be used if buf is NULL, but should be set to the timestamp of the packet returned....
+            /* timestamp should be overwritten by parse_packet, if not,
+             * the packet is left with pts == AV_NOPTS_VALUE */
+            timestamp = RTP_NOTS_VALUE;
             rv= s->parse_packet(s->ic, s->dynamic_protocol_context,
                                 s->st, pkt, &timestamp, NULL, 0, flags);
             finalize_packet(s, pkt, timestamp);
diff --git a/libavformat/rtpdec.h b/libavformat/rtpdec.h
index 86af2b9..aa686da 100644
--- a/libavformat/rtpdec.h
+++ b/libavformat/rtpdec.h
@@ -34,6 +34,8 @@ typedef struct RTPDynamicProtocolHandler_s RTPDynamicProtocolHandler;
 #define RTP_MIN_PACKET_LENGTH 12
 #define RTP_MAX_PACKET_LENGTH 1500 /* XXX: suppress this define */
 
+#define RTP_NOTS_VALUE ((uint32_t)-1)
+
 typedef struct RTPDemuxContext RTPDemuxContext;
 RTPDemuxContext *rtp_parse_open(AVFormatContext *s1, AVStream *st, URLContext *rtpc, int payload_type);
 void rtp_parse_set_dynamic_protocol(RTPDemuxContext *s, PayloadContext *ctx,
-- 
1.7.1

From cc9687f4742ef7cd226c02420373260b53103b37 Mon Sep 17 00:00:00 2001
From: Martin Storsjo <[email protected]>
Date: Thu, 8 Jul 2010 22:14:29 +0300
Subject: [PATCH 2/2] rtpdec_svq3: Return the timestamp in *timestamp instead of pkt->pts

The timestamp of the first RTP packet forming the output AVPacket is
written back in *timestamp, which is used in later calculations in generic
rtpdec code (together with RTCP sync timestamps) to form the final pkt->pts
value.
---
 libavformat/rtpdec_svq3.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/libavformat/rtpdec_svq3.c b/libavformat/rtpdec_svq3.c
index a285036..af08c88 100644
--- a/libavformat/rtpdec_svq3.c
+++ b/libavformat/rtpdec_svq3.c
@@ -101,7 +101,7 @@ static int svq3_parse_packet (AVFormatContext *s, PayloadContext *sv,
     if (end_packet) {
         av_init_packet(pkt);
         pkt->stream_index = st->index;
-        pkt->pts          = sv->timestamp;
+        *timestamp        = sv->timestamp;
         pkt->flags        = sv->is_keyframe ? AV_PKT_FLAG_KEY : 0;
         pkt->size         = url_close_dyn_buf(sv->pktbuf, &pkt->data);
         pkt->destruct     = av_destruct_packet;
-- 
1.7.1

_______________________________________________
FFmpeg-soc mailing list
[email protected]
https://lists.mplayerhq.hu/mailman/listinfo/ffmpeg-soc

Reply via email to