按照ffmpeg:decoding_encoding.c和filtering_video.c的exmaples,我处理iPhone拍摄的一个视频文件。视频文件:.mov,视频尺寸; 480x272,视频编解码器:H.264 / AVC,每秒30帧,比特率:605 kbps。
我首先提取每个帧,即YUV。 我将YUV转换为RGB24,并处理RGB24,然后将RGB24写入.ppm文件。它显示.ppm文件是正确的。
然后我计划将处理过的RGB24帧编码为视频文件。 由于MPEG不支持RGB24图像格式,我使用了AV_CODEC_ID_HUFFYUV。 但输出视频文件(显示18.5 MB)无法播放。 Ubuntu上的电影播放器声称有错误:无法确定流的类型。 我也在VCL上尝试过。它根本不起作用,没有任何错误信息。
我的第二个问题是: 对于输入视频文件中的每个提取的帧,我根据filtering_video.c得到如下:
frame->pts = av_frame_get_best_effort_timestamp(frame);
我打印出每个帧的pts,发现它增加了20,如下所示:
pFrameRGB_count: 0, frame->pts: 0
pFrameRGB_count: 1, frame->pts: 20
pFrameRGB_count: 2, frame->pts: 40
pFrameRGB_count: 3, frame->pts: 60
其中frame是输入视频中提取的帧,pFrameRGB_count是RGB24格式的已处理帧的计数。
为什么他们错了?
答案 0 :(得分:5)
H.264视频使用90 kHz clock
进行编码timestamps
。由于您的视频为30 fps
,因此两个连续帧之间的PTS增量应为3000
而不是20
。
值20表示以下一项或两项:
对于30 fps的给定帧速率,您的编码时钟(即采样率)配置不正确(至600 Hz)
您的每秒帧数配置不正确(至4500fps)。
计算PTS delta的通用公式为:
PTS delta = (1/fps) * Encoder sampling rate
答案 1 :(得分:0)
我调试以获取输入视频文件的编解码器上下文,dec_ctx-> time_base.den = 1200; 我知道fps,30,通过右键单击输入视频文件来检查其属性(Ubuntu 12.04) 所以看起来帧持续时间应该是1200/30 = 40个基本单位。 但是使用frame-> pts = av_frame_get_best_effort_timestamp(frame)是20;
输入视频的读取数据包的持续时间= 20。
我发现dec_ctx-> ticks_per_frame = 2.我猜ticks_per_frame为40到20。 也许有一些内部公式,例如:基本单位的帧持续时间=帧持续时间x ticks_per_frame(但它似乎与ffmpeg文档中的内容不同,例如time_base等于1 /帧速率。)
答案 2 :(得分:0)
我想我找到了答案。 由于缺乏ffmpeg的详细文档,用户可能会误导。 我发现,为了得到正确的答案,我应该总是使用: video_st->那么time_base NOT video_st-> codec-> time_base
(a)一帧的绝对时间:
packet-> dts *(1 / video_st-> time_base.den)
(b)帧与下一帧之间的绝对时间:
frame-> repeat_pict *(1 / video_st-> time_base.den)