7

按照ffmpeg的例子:decode_encoding.c和filtering_video.c,我处理了一个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得到它的pts如下:

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 格式的已处理帧的计数。

为什么他们错了?

4

3 回答 3

7

H.264 视频使用 a90 kHz clock进行编码timestamps。由于您的视频是30 fps,因此 2 个连续帧之间的 PTS 增量应该300020.

值 20 表示以下一项或两项:

  • 对于给定的 30 fps 帧速率,您的编码时钟(即采样率)配置不正确(至 600 Hz)

  • 您的每秒帧数配置不正确(至 4500fps)。

计算 PTS delta 的一般公式为:

PTS delta = (1/fps) * Encoder sampling rate
于 2013-03-17T08:27:34.763 回答
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/帧速率。)

于 2013-03-18T04:20:53.527 回答
0

我想我找到了答案。由于缺乏 ffmpeg 的详细文档,可能会误导用户。我发现,要获得正确的分数,应该始终使用:video_st->time_base NOT video_st->codec->time_base

(a) 一帧的绝对时间:

数据包->dts * (1/video_st->time_base.den)

(b) 帧与其下一帧之间的绝对时间:

frame->repeat_pict * (1/video_st->time_base.den)

于 2013-03-19T19:30:21.890 回答