Гарантируется ли длительность пакета одинаковой для всего потока?

Я использую длительность пакета для перевода из индекса кадра в точки и обратно, и я хотел бы быть уверен, что это надежный способ сделать это.

В качестве альтернативы, есть ли лучший способ для перевода очков в индекс кадра и наоборот?

Фрагмент, показывающий мое использование:

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 ответ

Решение

Нет, не гарантировано. Он может работать с некоторой комбинацией кодек / контейнер, где частота кадров является статической. avi, h264 raw (приложение-b) и yuv4mpeg приходят на ум. Но другие контейнеры, такие как flv, mp4, ts, имеют PTS/DTS (или CTS) для КАЖДОГО кадра. Источником может быть переменная частота кадров, или кадры могли быть отброшены в какой-то момент во время обработки из-за пропускной способности. Также некоторые кодеки будут удалять дубликаты кадров.

Так что, если вы не создали файл самостоятельно. Не верь этому. Не существует гарантированного способа посмотреть на фрейм и узнать его "индекс", кроме как начинать с начала и считать.

Однако ваш метод МОЖЕТ быть достаточно хорош для большинства файлов.

Другие вопросы по тегам