2016-10-11 4 views
2
int64_t timeBase; 
timeBase = (int64_t(pavStrm-> time_base.num) * AV_TIME_BASE)/int64_t(pavStrm->time_base.den); 
int64_t seekTarget = int64_t(iFrameNumber) * timeBase; 
av_seek_frame(fmt_ctx, -1, seekTarget, AVSEEK_FLAG_FRAME); 

здесь я хочу прочитать следующий 5 кадр после iFrameNumebrКак читать любой кадр, имея номер кадра с использованием FFmpeg av_seek_frame()

for(int iCnt = 0; iCnt <= 4; iCnt++) 
{ 
    iRet = av_read_frame(fmt_ctx, &pkt); 
     do 
     { 
      ret = decode_packet(&got_frame, 0); 
      if (ret < 0) 
       break; 
      pkt.data += ret; 
      pkt.size -= ret; 

     }while (pkt.size > 0); 
    av_free_packet(&pkt); 
} 

static int decode_packet(int *got_frame, int cached) 
{ 
int ret = 0; 
int decoded = pkt.size; 
*got_frame = 0; 

if (pkt.stream_index == video_stream_idx) 
{ 
    /* decode video frame */ 
    ret = avcodec_decode_video2(video_dec_ctx, frame, got_frame, &pkt); 
} 

, когда я использую AVSEEK_FLAG_BACKWARD его возвращение 5 пакетов и 5 кадр первый два пустые, но правильные.

, когда я использую AVSEEK_FLAG_FRAME его возврат 5 пакетов и 3 кадра, которые не являются первым 3 кадрами, возвращающими определенный кадр из видео.

для любого iFrameNumber

так, пожалуйста, помогите мне, как получить кадр, имея номер кадра и что точное значение seektarget 3 паров из av_seek_frame()

также у меня есть проблемы в процессе преобразования кадра в rgb24 формате

ответ

1
int64_t FrameToPts(AVStream* pavStream, int frame) const 
{ 
return (int64_t(frame) * pavStream->r_frame_rate.den * pavStream- 
>time_base.den)/
(int64_t(pavStream->r_frame_rate.num) * 
pavStream->time_base.num); 
} 

iSeekTarget = FrameToPts(m_pAVVideoStream, max(0, lFrame)); 
iSuccess = av_seek_frame(m_pAVFmtCtx, m_iVideo_Stream_idx, 
iSeekTarget, iSeekFlag); 

AVPacket avPacket; 
iRet = av_read_frame(m_pAVFmtCtx, &avPacket); 
7

Я думаю, что av_seek_frame() является одной из наиболее распространенных, но трудных для понимания функций, также недостаточно хорошо прокомментированных.

Если установлен флаг AVSEEK_FLAG_FRAME, третьим параметром должен быть номер кадра, который вы хотите найти, и у вас все в порядке.

Давайте посмотрим пример, чтобы лучше понять из av_seek_frame():

Скажем, у меня есть видео 10 кадров, с кадров в секунду = 10. Первый и пятый кадры являются ключевыми кадрами (I Frame или intra frame). Другие - это P-фреймы или даже B-кадры в некотором формате.

5 6 7 8 9 (номер кадра)

0,1 0,2 0,3 0,4 0,5 0,6 0,7 0,8 0,9 (развертка)

av_seek_frame(fmt_ctx, -1, 2, AVSEEK_FLAG_FRAME); 
av_seek_frame(fmt_ctx, -1, 0.15, 0); 
// These will seek to the fifth frame. Cause `AVSEEK_FLAG_ANY` is not given. Seeking to the next key frame after third parameter. 

av_seek_frame(fmt_ctx, -1, 2, AVSEEK_FLAG_FRAME | AVSEEK_FLAG_ANY); 
// This will seek to exactly the third parameter specified. But probably only a frame with no actual meaning. (We can't get a meaningful image if no related I/P/B frames given.) 

av_seek_frame(fmt_ctx, -1, 0.15, AVSEEK_FLAG_ANY); 
// Seek to 0.2. Nothing interesting as above. 

av_seek_frame(fmt_ctx, -1, 0.15, AVSEEK_FLAG_ANY | AVSEEK_FLAG_BACKWARD); 
// Seek to 0.1. Also nothing interesting. 

av_seek_frame(fmt_ctx, -1, 2, AVSEEK_FLAG_FRAME | AVSEEK_FLAG_BACKWARD); 
// Got the first frame. Seeking to the nearest key frame before the third parameter. 

Поэтому, если я хотел бы получить произвольный фрейм, обычно, сначала ищу с AVSEEK_FLAG_BACKWARD, декодированием, как обычно. Затем проверьте первые несколько пакетов и длительность пакетов, посмотрите, нужно ли их отбрасывать.

+0

Его еще позволяют достичь желаемого кадра и нормально, когда я строила его в режиме воспроизведения не возвращает непрерывный бит кадра расстроен тем, как благодарить за комментарий надежды я начнется после получения непрерывного кадра. –

+0

@halfelf Что такое поведение _expected_, когда вы ищете номер кадра «4» (пятый кадр) с флагами (ЛЮБОЙ | BACKWARD). Должны ли они искать «0» или «4»? – ZeroDefect

+1

@ZeroDefect Согласно документу 'avformat_seek_file()', который будет вызываться 'av_seek_frame()', пятый параметр 'avformat_seek_file',' max_ts', означает самую большую приемлемую временную метку, которая эквивалентна третьему параметру ' av_seek_frame', если задано 'AV_SEEK_FLAG_BACKWARD', так что ожидается, что ожидается« 0,4 ». Кстати, может быть еще одна необычная ошибка, что 'AVSEEK_FLAG_ANY' не поддерживается некоторыми демультиплексорами. – halfelf

-1
timeBase = (int64_t(video_stream-> time_base.num) * AV_TIME_BASE)/int64_t(video_stream->time_base.den); 
int64_t seekTarget = int64_t(iFrameNumber) * timeBase * (video_stream->time_base.den/video_stream->avg_frame_rate.num); 


int iiiret = av_seek_frame(fmt_ctx, -1, seekTarget, AVSEEK_FLAG_FRAME); 

 Смежные вопросы

  • Нет связанных вопросов^_^