[FFmpeg-soc] [PATCH] qdm2 depacketizer
Martin Storsjö
martin at martin.st
Wed Jul 14 14:33:25 CEST 2010
Hi,
On Wed, 14 Jul 2010, Josh Allmann wrote:
> On 8 July 2010 12:22, Martin Storsjö <martin at martin.st> wrote:
> >
> > 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;
> >
>
> In this case, foo is qdm->timestamp != RTP_NOTS_VALUE.
> That makes the whole hunk tautologous, so simplified to
> *timestamp = qdm->timestamp.
True
> Although the whole thing still feels a bit odd, as we assign
> qdm->timestamp = *timestamp earlier in the code, and don't use
> qdm->timestamp otherwise.
Yes we do, you just happened to remove the qdm->timestamp = -1 line :-)
> Fixes have also been made for all earlier comments, with Martin's
> patches applied locally. (Just a heads up -- git complains about ^M
> (DOS-style?) line endings in those)
Hmm, that's weird.
A few more things - we're getting close.
> + switch (config_item) {
> + case 0: /* end of config block */
> + return p - buf + item_len;
> + case 1: /* stream without extradata */
> + /* FIXME: set default qdm->block_size */
> + break;
> + case 2: /**< subpackets per block */
> + if (item_len < 2)
> + return AVERROR_INVALIDDATA;
This needs to be item_len < 3, as I wrote in the previous mail, since
you're reading p[2], which is the third byte.
> + qdm->subpkts_per_block = p[2];
> + break;
> + case 3: /* superblock type */
> + if (item_len < 4)
> + return AVERROR_INVALIDDATA;
> + qdm->block_type = AV_RB16(p + 2);
> + break;
> + case 4: /* stream with extradata */
> + if (item_len < 30)
> + return AVERROR_INVALIDDATA;
> + av_freep(&st->codec->extradata);
> + st->codec->extradata_size = 26 + item_len;
> + if (!(st->codec->extradata = av_malloc(st->codec->extradata_size))){
You need to add the padding to the allocated area - but not as part of
extradata_size. That is, av_mallocz(extradata_size + PADDING), so that the
padding is zero-initialized, too.
> + st->codec->extradata_size = 0;
> + return AVERROR(ENOMEM);
> + }
> + if ((res = av_new_packet(pkt, qdm->block_size)) < 0)
> + return res;
> + memset(pkt->data, 0, pkt->size);
> + pkt->pts = qdm->timestamp;
This still isn't right. The original code did this:
> + if (qdm->timestamp != (uint32_t) -1) {
> + pkt->pts = qdm->timestamp;
> + qdm->timestamp = -1;
> + } else
> + pkt->pts = AV_NOPTS_VALUE;
That is, store a valid pts only in the first packet, then nopts/-1 in the
rest, until qdm->timestamp is reinitialized.
You shouldn't write this into pkt->pts at all, doing that is an incorrect
design that only will creep into more depacketizers if they use this as an
example. pkt->pts gets set by the generic rtpdec code, and shouldn't be
touched by the depacketizers. (Actually, this bug leads to pts values way
off at the beginning, before the first RTCP packet, when the rtpdec code
doesn't touch pkt->pts at all.)
So you probably need to pass the timestamp pointer into this
function, and then do something like this:
*timestamp = qdm->timestamp;
qdm->timestamp = RTP_NOTS_VALUE;
Or simply do that at the end of qdm2_parse_packet, that should be ok as
well (and is a much smaller change compared to what you have now).
Also, you said:
> Although the whole thing still feels a bit odd, as we assign
> qdm->timestamp = *timestamp earlier in the code, and don't use
> qdm->timestamp otherwise.
We reset qdm->timestamp after outputting it into the first packet, so that
warrants doing it this way. Also, for the follow-up packets where no data
has been provided in this call to _parse but we just return buffered data,
we can't really rely on the value of *timestamp at all, I'd say.
So, after my rambling - remove the pkt->pts line, add qdm->timestamp =
RTP_NOTS_VALUE after *timestamp = qdm->timestamp; - then it should be ok,
with the minor changes I suggested above.
And since the changes that were left were quite minor, I went ahead and
fixed them and applied it. Let's move on to other things. :-)
// Martin
More information about the FFmpeg-soc
mailing list