2014-11-07 2 views
1

파일의 특정 프레임의 PTS가 스트리밍되는 동안 동일한 파일의 동일한 프레임의 PTS와 다를 수 있습니까?비디오 파일 및 미디어 스트림의 PTS에 대한 혼동

av_read_frame을 사용하여 프레임을 읽을 때 비디오 스트림을 AVStream에 저장합니다. avcodec_decode_video2를 사용하여 프레임을 디코딩 한 후 av_frame_get_best_effort_timestamp를 사용하여 int64_t에 해당 프레임의 타임 스탬프를 저장합니다. 이제 프로그램이 파일에서 입력을 얻는다면 프로그램에 동일한 파일의 입력을 스트리밍 할 때와 다른 타임 스탬프를 얻습니다.

입력 형식을 변경하려면 단순히 "argv"인수를 "/path/to/file.mp4"에서 "udp : // localhost : 1234"와 같은 것으로 변경하면 명령 줄에서 ffmpeg로 파일을 스트리밍합니다. "ffmpeg -re -i /path/to/file.mp4 -f mpegts udp : // localhost : 1234"를 입력하십시오. "-f mpegts"인수가 미디어의 일부 특성을 변경하기 때문일 수 있습니까?

다음은 내 코드 (간체)입니다. ffmpeg 메일 링리스트 아카이브를 읽음으로써 내가 찾고있는 time_base가 AVStream에 있고 AVCodecContext에 없다는 것을 깨달았습니다. av_frame_get_best_effort_timestamp를 사용하는 대신 packet.pts를 사용해 보았지만 결과는 바뀌지 않았습니다. 수신중인 스트리밍 비디오에서 프레임 번호 개념을 사용하려면 타임 스탬프가 필요합니다. 나는 어떤 종류의 도움에 정말로 감사 할 것입니다.

//.. 
//argv[1]="/file.mp4"; 
argv[1]="udp://localhost:7777"; 
// define AVFormatContext, AVFrame, etc. 
// register av, avcodec, avformat_network_init(), etc. 
avformat_open_input(&pFormatCtx, argv, NULL, NULL); 
avformat_find_stream_info(pFormatCtx, NULL); 
// find the video stream... 
// pointer to the codec context... 
// open codec... 
pFrame=av_frame_alloc(); 
while(av_read_frame(pFormatCtx, &packet)>=0) { 
     AVStream *strem = pFormatCtx->streams[videoStream]; 
     if(packet.stream_index==videoStream) { 
      avcodec_decode_video2(pCodecCtx, pFrame, &frameFinished, &packet); 
      if(frameFinished) { 
       int64_t perts = av_frame_get_best_effort_timestamp(pFrame); 
       if (isMyFrame(pFrame)){ 
        cout << perts*av_q2d(strem->time_base) << "\n"; 
       } 
      } 
} 
//free allocated space 
} 
//.. 

답변

2

타임 스탬프는 컨테이너 수준에 저장되므로 컨테이너를 변경하면 타임 스탬프가 변경 될 수 있습니다. 또한 TS는 모든 프레임에 대해 타임 스탬프를 저장합니다 (90kHz 클록 기준). MP4는 가정 된 시작 시간이 0 인 프레임 지속 시간 만 저장합니다 (첫 번째 PTS가 0이고 첫 번째 DTS가 <이므로 bframes를 사용하면 복잡해집니다). 따라서 타임 스탬프를 얻으려면 모든 프레임 지속 시간이 추가됩니다. 또한 Mp4를 사용하면 클럭 속도를 설정할 수 있습니다. 그것은 종종 초당 1001/3000 틱이고 29.97FPS이지만 아무 것도 설정할 수 있습니다. 그래서 av_frame_get_best_effort_timestamp는 코덱 -> stream_base 단위로 틱을 반환합니다. TS 코덱에 대해 -> stream_base는 항상 1/90000입니다

+0

고맙습니다. 매우 유익합니다. 이 경우 스트리밍 명령의 "-f mpegts"인수가 컨테이너를 즉시 바꾼다고 가정합니다. – user2452253

+1

수정하십시오. mpegts는 컨테이너 형식입니다. – szatmary