2013-12-12 8 views
1

프레임 길이를 pts 및 back으로 변환하기 위해 패킷 지속 시간을 사용합니다.이 방법이 신뢰할 수있는 방법인지 확인하고 싶습니다.전체 스트림에 대해 패킷 길이가 일정하게 보장됩니까?

또는 pts를 프레임 인덱스로 변환하는 더 좋은 방법이 있습니까? 내 사용을 보여주는

스 니펫은 :

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; 
} 

답변

0

아니, 보증되지 않습니다. 프레임 속도가 정적 인 일부 코덱/컨테이너 조합에서 작동 할 수 있습니다. avi, h264 raw (annex-b) 및 yuv4mpeg가 떠오른다. 그러나 flv, mp4, ts와 같은 다른 컨테이너에는 모든 프레임에 대해 PTS/DTS (또는 CTS)가 있습니다. 소스는 가변 프레임 속도 일 수 있으며 대역폭으로 인해 처리 중 어느 시점에서 프레임을 삭제할 수 있습니다. 또한 일부 코덱은 중복 된 프레임을 제거합니다.

직접 파일을 만들지 않은 경우. 믿지 마라. 프레임을보고 '인덱스'를 알 수있는 방법은 없습니다. 처음부터 시작해서 카운트하는 것입니다.

귀하의 방법은 대부분의 파일에 적합 할 수 있습니다.