Is packet duration guaranteed to be uniform for entire stream?

770 views Asked by At

I use packet duration to translate from frame index to pts and back, and I'd like to be sure that this is a reliable method of doing so.

Alternatively, is there a better way to translate pts to a frame index and vice versa?

A snippet showing my usage:

bool seekFrame(int64_t frame)
{
    if(frame > container.frameCount)
        frame = container.frameCount;

    // Seek to a frame behind the desired frame because nextFrame() will also increment the frame index
    int64_t seek = pts_cache[frame-1];  // pts_cache is an array of all frame pts values

    // get the nearest prior keyframe
    int preceedingKeyframe = av_index_search_timestamp(container.video_st, seek, AVSEEK_FLAG_BACKWARD);

    // here's where I'm worried that packetDuration isn't a reliable method of translating frame index to 
    // pts value
    int64_t nearestKeyframePts = preceedingKeyframe * container.packetDuration; 

    avcodec_flush_buffers(container.pCodecCtx);

    int ret = av_seek_frame(container.pFormatCtx, container.videoStreamIndex, nearestKeyframePts, AVSEEK_FLAG_ANY);

    if(ret < 0) return false;

    container.lastPts = nearestKeyframePts;

    AVFrame *pFrame = NULL;

    while(nextFrame(pFrame, NULL) && container.lastPts < seek)
    {
        ;
    }

    container.currentFrame = frame-1;
    av_free(pFrame);
    return true;
}
1

There are 1 answers

0
szatmary On BEST ANSWER

No, not guaranteed. It may work with some codec/container combination where frame-rate is static. avi, h264 raw (annex-b) and yuv4mpeg come to mind. But other containers like flv, mp4, ts, have a PTS/DTS (or CTS) for EVERY frame. The source could be variable frame rate, or frames could have be dropped at some point during processing due to bandwidth. Also some codecs will remove duplicate frames.

So unless you created the file yourself. Do not trust it. There is no guaranteed way to look at a frame and know its 'index' except start at the beginning and count.

Your method, MAY be good enough for most files however.