音频视频您现在的位置是:首页 > 工具箱 > 音频视频

ffmpeg输出q=28什么意思?

<a href='mailto:'>微wx笑</a>的头像微wx笑 2023-03-05音频视频 2 0关键字: ffmpeg  

参考:ffmpeg命令分析-print命令如下:ffmpeg -i a.mp4 -vcodec libx264 -preset placebo output.mp4本文不讲上面的命令行参数实现,而是打算讲解,ffmpeg 转码过程中输出的 frame

参考:ffmpeg命令分析-printSKK无知

命令如下:ffmpeg -i a.mp4 -vcodec libx264 -preset placebo output.mp4SKK无知


SKK无知

本文不讲上面的命令行参数实现,而是打算讲解,ffmpeg 转码过程中输出的 frame ,fps,q,size, bitrate ,speed 的意义,如下图。SKK无知


SKK无知

最重要的是speed,转码速度SKK无知


SKK无知


SKK无知


SKK无知

从ffmpeg.c 里可以看出,上面的红色圈出来的是 print_report() 函数打印的,下面就来分析 print_report() 的实现,流程图如下:SKK无知


SKK无知


SKK无知


SKK无知

print_report() 入口会做一个时间判断,每 隔0.5 秒才打印一次日志,代码如下:SKK无知


SKK无知

if (!is_last_report) {SKK无知

    if (last_time == -1) {SKK无知

        last_time = cur_time;SKK无知

        return;SKK无知

    }SKK无知

    //50万微妙,0.5秒统计一次。SKK无知

    if ((cur_time - last_time) < 500000) //注意这里SKK无知

        return;SKK无知

    last_time = cur_time;SKK无知

}SKK无知

后续的代码没有什么好分析,逻辑比较简单,自行查看即可。SKK无知


SKK无知

frame= 160 fps= 37 q=28.0 size= 0kB time=00:00:07.23 bitrate= 0.1kbits/s speed=1.68xSKK无知


SKK无知

打印日志的参数解析如下:SKK无知


SKK无知

1,frame ,用的是 ost->frame_number 赋值,代表当前编码到视频流的第几帧。SKK无知


SKK无知

2,fps,用上面的 frame 除以时间得到,代表一秒编码了多少个视频帧。SKK无知


SKK无知

3,q,编码质量,也是针对视频的。q 的计算方式如下:SKK无知


SKK无知

q = ost->quality / (float) FF_QP2LAMBDA;SKK无知

可以看到,q 是 从ost->quality 来的,那 ost->quality 的值是在哪里赋值的呢?代码如下:SKK无知


SKK无知

ffmpeg.c 742行SKK无知

uint8_t *sd = av_packet_get_side_data(pkt, AV_PKT_DATA_QUALITY_STATS,NULL);SKK无知

ost->quality = sd ? AV_RL32(sd) : -1;SKK无知

可以看到,流的质量quality,应该是一个累计的值。我个人猜测编码器会根据以往编码的Frame 不断计算这个值,然后放进去 AVPacket 的side_data 里面。SKK无知


SKK无知

可以 av_packet_get_side_data() 获取到 side_data,side_data 的前32位就是 quality,AV_PKT_DATA_QUALITY_STATS 这个side_data的定义如下。SKK无知


SKK无知

 libavcodec\avcodec.h 1266行SKK无知

 /**SKK无知

     * This side data contains quality related information from the encoder.SKK无知

     * @codeSKK无知

     * u32le quality factor of the compressed frame. Allowed range is between 1 (good) and FF_LAMBDA_MAX (bad).SKK无知

     * u8    picture typeSKK无知

     * u8    error countSKK无知

     * u16   reservedSKK无知

     * u64le[error count] sum of squared differences between encoder in and outputSKK无知

     * @endcodeSKK无知

     */SKK无知

 AV_PKT_DATA_QUALITY_STATS,SKK无知

前面 3个参数都是针对 视频流 的分析SKK无知


SKK无知

4,size,写入文件的数据大小,通过 avio_size(oc->pb) 获得。SKK无知


SKK无知

5,bitrate,比特率,这个bitrate 的单位是 kbits/s ,不是 kb/s ,要注意。 kbits/s 是指每秒传输多少千比特,一个字节有8个比特。SKK无知


SKK无知

所以源码里 bitrate 的计算方式如下:SKK无知


SKK无知

ffmpeg.c 1769行SKK无知

bitrate = pts && total_size >= 0 ? total_size * 8 / (pts / 1000.0) : -1;SKK无知

total_size 是avio_size() 返回的,单位是字节,所以乘以 8,pts 的单位是微妙,除以1000后等于 千分之一秒。千分之一秒能传输 ( total_size * 8) 大小的比特。那1秒就能够传输 ( total_size * 8) * 1000 大小的比特。但是输出的单位不是比特,而是千比特,kbits,前面有个k,所以这个乘以1000就可以抵消掉。就形成源码的计算方式。SKK无知


SKK无知

6,speed,编码速度。用输出流的最后一个AVPacket的pts 除以程序运行时间。哪个流的最后AVPacket的pts最大就以哪个流的pts为准,输出流最后一个AVPacket的pts通过函数 av_stream_get_end_pts() 获得。SKK无知


SKK无知

这样就比较好理解了,如果现在已经编码到视频流的第10秒的数据帧,但是转码程序只运行了2秒,那speed转码速度就是 10 /2 ,speed等于5.SKK无知


SKK无知

ffmpeg.c 1770行SKK无知

speed = t != 0.0 ? (double)pts / AV_TIME_BASE / t : -1;SKK无知

print_report 里面 的qp_hist 跟 AV_CODEC_FLAG_PSNR 本次不讲解,因为我也不知道是做什么的SKK无知

————————————————SKK无知

版权声明:本文为CSDN博主「Loken2020」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。SKK无知

原文链接:https://blog.csdn.net/u012117034/article/details/123453863SKK无知


SKK无知

本文由 微wx笑 创作,采用 署名-非商业性使用-相同方式共享 4.0 许可协议,转载请附上原文出处链接及本声明。
原文链接:https://www.ivu4e.cn/toolbox/media/2023-03-05/1743.html

很赞哦! () 有话说 ()