On 04/26/2012 11:05 AM, Martin Storsjö wrote:

> On Thu, 26 Apr 2012, Martin Storsjö wrote:
> 
>> On Thu, 26 Apr 2012, Justin Ruggles wrote:
>>
>>> On 04/26/2012 08:33 AM, Martin Storsjö wrote:
>>>
>>>> On Mon, 5 Mar 2012, Justin Ruggles  wrote:
>>>>
>>>>> Module: libav
>>>>> Branch: master
>>>>> Commit: a7fa75684d8fd2551ef87070d9a69349beca7260
>>>>>
>>>>> Author:    Justin Ruggles <[email protected]>
>>>>> Committer: Justin Ruggles <[email protected]>
>>>>> Date:      Mon Feb 27 18:07:07 2012 -0500
>>>>>
>>>>> avformat: do not fill-in audio packet duration in compute_pkt_fields()
>>>>>
>>>>> Use the estimated duration only to calculate missing timestamps if 
>>>>> needed.
>>>>>
>>>>> ---
>>>>>
>>>>> libavformat/utils.c |   47 
>>>>> +++++++++++++++++++++++++++++++++--------------
>>>>> 1 files changed, 33 insertions(+), 14 deletions(-)
>>>>>
>>>>> diff --git a/libavformat/utils.c b/libavformat/utils.c
>>>>> index 7fd7c32..a1f24d4 100644
>>>>> --- a/libavformat/utils.c
>>>>> +++ b/libavformat/utils.c
>>>>> @@ -951,12 +953,29 @@ static void compute_pkt_fields(AVFormatContext *s, 
>>>>> AVStream *st,
>>>>>             st->last_IP_pts= pkt->pts;
>>>>>             /* cannot compute PTS if not present (we can compute it only
>>>>>             by knowing the future */
>>>>> -        } else if(pkt->pts != AV_NOPTS_VALUE || pkt->dts != 
>>>>> AV_NOPTS_VALUE || pkt->duration){
>>>>> -            if(pkt->pts != AV_NOPTS_VALUE && pkt->duration){
>>>>> -                int64_t old_diff= FFABS(st->cur_dts - pkt->duration - 
>>>>> pkt->pts);
>>>>> +        } else if (pkt->pts != AV_NOPTS_VALUE ||
>>>>> +                   pkt->dts != AV_NOPTS_VALUE ||
>>>>> +                   pkt->duration              ||
>>>>> +                   st->codec->codec_type == AVMEDIA_TYPE_AUDIO) {
>>>>> +            int duration = pkt->duration;
>>>>> +            if (!duration && st->codec->codec_type == 
>>>>> AVMEDIA_TYPE_AUDIO) {
>>>>> +                compute_frame_duration(&num, &den, st, pc, pkt);
>>>>> +                if (den && num) {
>>>>> +                    duration = av_rescale_rnd(1, num * 
>>>>> (int64_t)st->time_base.den,
>>>>> +                                                 den * 
>>>>> (int64_t)st->time_base.num,
>>>>> +                                                 AV_ROUND_DOWN);
>>>>> +                    if (duration != 0 && s->packet_buffer) {
>>>>> +                        update_initial_durations(s, st, 
>>>>> pkt->stream_index,
>>>>> +                                                 duration);
>>>>> +                    }
>>>>> +                }
>>>>> +            }
>>>>> +
>>>>> +            if(pkt->pts != AV_NOPTS_VALUE && duration){
>>>>> +                int64_t old_diff= FFABS(st->cur_dts - duration - 
>>>>> pkt->pts);
>>>>>                 int64_t new_diff= FFABS(st->cur_dts - pkt->pts);
>>>>> -                if(old_diff < new_diff && old_diff < 
>>>>> (pkt->duration>>3)){
>>>>> -                    pkt->pts += pkt->duration;
>>>>> +                if(old_diff < new_diff && old_diff < (duration>>3)){
>>>>> +                    pkt->pts += duration;
>>>>>     //                av_log(NULL, AV_LOG_DEBUG, "id:%d old:%"PRId64" 
>>>>> new:%"PRId64" dur:%d cur:%"PRId64" size:%d\n", pkt->stream_index, 
>>>>> old_diff, new_diff, pkt->duration, st->cur_dts, pkt->size);
>>>>>                 }
>>>>>             }
>>>>
>>>> This makes AAC in mpegts return multiple packets with the same timestamp -
>>>> earlier, only the first one had a timestamp and the later packets had
>>>> pts/dts == NOPTS.
>>>>
>>>> Is this intentional or unintentional, and is there a good way to fix it?
>>>
>>>
>>> Do you have a sample I can test?  I didn't get those results when
>>> testing a random aac-in-mpegts file.
>>
>> Hmm, I only seem to get this result if I don't call 
>> avformat_find_stream_info 
>> - if I call it, I get proper continuous timestamps for all packets.
>>
>> It can be reproduced with http://albin.abo.fi/~mstorsjo/trailer.ts.
> 
> The difference caused by calling avformat_find_stream_info is that it 
> initializes the decoder, setting frame_size. (My use case is building a 
> plain demuxer without any decoders enabled.)
> 
> Perhaps the rest of the code block (below) should be enclosed in an if 
> statement like (!audio || duration), since your change added the condition 
> to always run this block for audio (since duration wasn't set but only 
> calculated).
> 
>              if(pkt->pts == AV_NOPTS_VALUE)
>                  pkt->pts = pkt->dts;
>              update_initial_timestamps(s, pkt->stream_index, pkt->pts, 
> pkt->pts);
>              if(pkt->pts == AV_NOPTS_VALUE)
>                  pkt->pts = st->cur_dts;
>              pkt->dts = pkt->pts;
>              if(pkt->pts != AV_NOPTS_VALUE)
>                  st->cur_dts = pkt->pts + duration;
> 
> Would that make sense?


Yes. I'll send a patch after I'm done testing it.

Thanks,
Justin
_______________________________________________
libav-devel mailing list
[email protected]
https://lists.libav.org/mailman/listinfo/libav-devel

Reply via email to