x264 ffmpeg编解码参数笔记

news/2024/11/8 9:09:13/

X264 ffmpeg

1、码率:
码流(Data Rate),是指视频文件在单位时间内使用的数据流量

三种可选的码率控制方法(bitrate, CQP,CRF), 选择的顺序是 bitrate > QP > CRF
QP是固定量化参数,bitrate是固定文件大小,crf则是固定“质量”,abr(ABR平均码率,VBR是动态码率。CBR是静态码率。),crf(限制码率),cqp(固定质量)
–qp, –bitrate, –crf
X264_RC_CQP 动态比特率
X264_RC_CRF 恒定比特率
X264_RC_ABR 平均比特率

480P分辨率仅需1-2M的码率即可达到远超AVI格式的画质,一部电影大小仅为1G;720P分辨率也只需要3-4M码率和2-3G的体积
720P ,码流大约在2到4或者5M;
1080P 大约在4到8M

高码率编码(如下 中码率 = 高码率/2, 极高码率 = 高码率*2,低码率 = 中码率/2
480P –> 250kbps 720P –> 500kbps 1080P –> 1mps 极低码率
480P –> 500kbps 720P –> 1mbps 1080P –> 2mps 低码率
480P –> 1mbps 720P –> 2mbps 1080P –> 4mps 中码率
480P –> 2mbps 720P –> 4mbps 1080P –> 8mps 高码率
480P –> 4mbps 720P –> 8mbps 1080P –> 16mps 极高码率
通常高编码码率:
480P 720X480 1800Kbps
720P 1280X720 3500Kbps
1080P 1920X1080 8500Kbps

ffmpeg中编码器参数设定:

1.如果设置了AVCodecContext中bit_rate的大小,则采用abr的控制方式;
2.如果没有设置AVCodecContext中的bit_rate,则默认按照crf方式编码,crf默认大小为23(此值类似于qp值,同样表示视频质量);
3.如果用户想自己设置,则需要借助av_opt_set函数设置AVCodecContext的priv_data参数。下面给出三种控制方式的实现代码:
int bpsValue; //码流控制方式的对应值
int bpsMode; //码流控制方式,0表示平均码率(abr),1表示固定码率(crf),2表示固定质量(cqp)
AVCodecContext* pCodecCtx;
…….

//码率控制方式
string modeValue = int2String(bpsValue);
switch (bpsMode) {
case 0:
pCodecCtx->bit_rate = bpsValue*1000;
break;
case 1:
av_opt_set(pCodecCtx->priv_data,”crf”,modeValue.c_str(),AV_OPT_SEARCH_CHILDREN);
break;
case 2:
av_opt_set(pCodecCtx->priv_data,”qp”,modeValue.c_str(),AV_OPT_SEARCH_CHILDREN);
break;
default:
pCodecCtx->bit_rate = bpsValue;
break;
}

ffmpeg中VBR(可变率控制)的设置:
c->flags |= CODEC_FLAG_QSCALE;
c->rc_min_rate =min;
c->rc_max_rate = max;
c->bit_rate = br;

ffmpeg中CBR(固定码率控制)的设置:
c->bit_rate = br;
c->rc_min_rate =br;
c->rc_max_rate = br;
c->bit_rate_tolerance = br;
c->rc_buffer_size=br;
c->rc_initial_buffer_occupancy = c->rc_buffer_size*3/4;
c->rc_buffer_aggressivity= (float)1.0;
c->rc_initial_cplx= 0.5;

  //AVCodecContext 相当于虚基类,需要用具体的编码器实现来给他赋值pCodecCtxEnc = video_st->codec;//编码器的ID号,这里我们自行指定为264编码器,实际上也可以根据video_st里的codecID 参数赋值pCodecCtxEnc->codec_id = AV_CODEC_ID_H264;//编码器编码的数据类型pCodecCtxEnc->codec_type = AVMEDIA_TYPE_VIDEO;//目标的码率,即采样的码率;显然,采样码率越大,视频大小越大pCodecCtxEnc->bit_rate = 200000;//固定允许的码率误差,数值越大,视频越小pCodecCtxEnc->bit_rate_tolerance = 4000000;//编码目标的视频帧大小,以像素为单位pCodecCtxEnc->width = 640;pCodecCtxEnc->height = 480;//帧率的基本单位,我们用分数来表示,//用分数来表示的原因是,有很多视频的帧率是带小数的eg:NTSC 使用的帧率是29.97pCodecCtxEnc->time_base.den = 30;pCodecCtxEnc->time_base = (AVRational){1,25};pCodecCtxEnc->time_base.num = 1;//像素的格式,也就是说采用什么样的色彩空间来表明一个像素点pCodecCtxEnc->pix_fmt = PIX_FMT_YUV420P;//每250帧插入1个I帧,I帧越少,视频越小[cpp] view plain copypCodecCtxEnc->gop_size = 250;//两个非B帧之间允许出现多少个B帧数//设置0表示不使用B帧//b 帧越多,图片越小pCodecCtxEnc->max_b_frames = 0;//运动估计pCodecCtxEnc->pre_me = 2;//设置最小和最大拉格朗日乘数//拉格朗日乘数 是统计学用来检测瞬间平均值的一种方法pCodecCtxEnc->lmin = 1;pCodecCtxEnc->lmax = 5;//最大和最小量化系数pCodecCtxEnc->qmin = 10;pCodecCtxEnc->qmax = 50;//因为我们的量化系数q是在qmin和qmax之间浮动的,//qblur表示这种浮动变化的变化程度,取值范围0.0~1.0,取0表示不削减pCodecCtxEnc->qblur = 0.0;//空间复杂度的masking力度,取值范围 0.0-1.0pCodecCtxEnc->spatial_cplx_masking = 0.3;//运动场景预判功能的力度,数值越大编码时间越长pCodecCtxEnc->me_pre_cmp = 2;//采用(qmin/qmax的比值来控制码率,1表示局部采用此方法,)pCodecCtxEnc->rc_qsquish = 1;//设置 i帧、p帧与B帧之间的量化系数q比例因子,这个值越大,B帧越不清楚//B帧量化系数 = 前一个P帧的量化系数q * b_quant_factor + b_quant_offsetpCodecCtxEnc->b_quant_factor = 1.25;//i帧、p帧与B帧的量化系数便宜量,便宜越大,B帧越不清楚pCodecCtxEnc->b_quant_offset = 1.25;//p和i的量化系数比例因子,越接近1,P帧越清楚//p的量化系数 = I帧的量化系数 * i_quant_factor + i_quant_offsetpCodecCtxEnc->i_quant_factor = 0.8;pCodecCtxEnc->i_quant_offset = 0.0;//码率控制测率,宏定义,查APIpCodecCtxEnc->rc_strategy = 2;//b帧的生成策略pCodecCtxEnc->b_frame_strategy = 0;//消除亮度和色度门限pCodecCtxEnc->luma_elim_threshold = 0;pCodecCtxEnc->chroma_elim_threshold = 0;//DCT变换算法的设置,有7种设置,这个算法的设置是根据不同的CPU指令集来优化的取值范围在0-7之间pCodecCtxEnc->dct_algo = 0;//这两个参数表示对过亮或过暗的场景作masking的力度,0表示不作pCodecCtxEnc->lumi_masking = 0.0;pCodecCtxEnc->dark_masking = 0.0;

x264编码时延问题:
a:
avcodec_encode_video2函数输出的延时仅仅跟max_b_frames的设置有关,进行实时编码,将max_b_frames设置为0便没有编码延时了

b:使用264的API设置编码速度
// ultrafast,superfast, veryfast, faster, fast, medium slow, slower, veryslow, placebo. 这是x264编码速度的选项
av_opt_set(m_context->priv_data,”preset”,”ultrafast”,0);

2、ffmpeg中的时间单位

AV_TIME_BASE
ffmpeg中的内部计时单位(时间基),ffmepg中的所有时间都是于它为一个单位,
比如AVStream中的duration即以为着这个流的长度为duration个AV_TIME_BASE。AV_TIME_BASE定义为:

#define         AV_TIME_BASE   1000000

AV_TIME_BASE_Q
ffmpeg内部时间基的分数表示,实际上它是AV_TIME_BASE的倒数。从它的定义能很清楚的看到这点:

#define         AV_TIME_BASE_Q   (AVRational){1, AV_TIME_BASE}

AVRatioal的定义如下:

typedef struct AVRational{
int num; //numerator
int den; //denominator
} AVRational;

ffmpeg提供了一个把AVRatioal结构转换成double的函数:

static inline double av_q2d(AVRational a){
//Convert rational to double.
//@param a rational to convertreturn a.num / (double) a.den;
}

现在可以根据pts来计算一桢在整个视频中的时间位置:
timestamp(秒) = pts * av_q2d(st->time_base)

计算视频长度的方法:
time(秒) = st->duration * av_q2d(st->time_base)这里的st是一个AVStream对象指针。

时间基转换公式
timestamp(ffmpeg内部时间戳) = AV_TIME_BASE * time(秒)
time(秒) = AV_TIME_BASE_Q * timestamp(ffmpeg内部时间戳)
所以当需要把视频跳转到N秒的时候可以使用下面的方法:

int64_t timestamp = N * AV_TIME_BASE;
2
av_seek_frame(fmtctx, index_of_video, timestamp, AVSEEK_FLAG_BACKWARD);

ffmpeg同样为我们提供了不同时间基之间的转换函数:
int64_t av_rescale_q(int64_t a, AVRational bq, AVRational cq)
这个函数的作用是计算a * bq / cq,来把时间戳从一个时基调整到另外一个时基。在进行时基转换的时候,
我们应该首选这个函数,因为它可以避免溢出的情况发生。

  1. 视频时间戳
    pkt.pts= inc++ *(1000/fps); 其中inc是一个静态的,初始值为0,每次打完时间戳inc加1.
    ffmpeg代码:
    pkt.pts= m_nVideoTimeStamp++ * (pctx->time_base.num * 1000 / pctx->time_base.den);

  2. 音频时间戳
    pts = inc++ * (frame_size * 1000 / sample_rate)
    ffmpeg代码:
    pkt.pts= m_nAudioTimeStamp++ * (m_ACtx->frame_size * 1000 / m_ACtx->sample_rate);

采样频率是指将模拟声音波形进行数字化时,每秒钟抽取声波幅度样本的次数。

调用av_rescale_q(pts, timebase1, timebase2)或者av_rescale_q_rnd(pts, timebase1, timebase2, XX)时,其实就是按照下面的公式计算:
x = pts * (timebase1.num / timebase1.den )* (timebase2.den / timebase2.num); //这个x就是转换后的时间戳。


http://www.ppmy.cn/news/185361.html

相关文章

小米AC2100|AX1800/AX3600/cr660x|红米AC2100/AX5/AX6/AX6S固件整理

本帖固件持续更新,请收藏网盘链接!!内容来自:小米官方固件、恩山论坛中大神编译的固件!第三方固件每一款本人都亲测使用过,精挑细选出来的超级好用的版本!无任何改动!下载前一定要看…

x5675相当于e5_2020年最新桌面CPU性能排行天梯图(含至强处理器)

1 Intel Xeon Platinum 8173M @ 2.00GHz 28860 2 Intel Xeon Gold 6154 @ 3.00GHz 27789 3 Intel Core i9-7980XE @ 2.60GHz 27736 4 Intel Xeon W-2195 @ 2.30GHz 26470 5 Intel Core i9-7960X @ 2.80GHz

2023考研高数接力题典1800习题讲解

第一部分(函数、极限、连续) 极限求法: ①直接代入数值 ②约去不能代入的零因子 ③分子分母同除最高次幂 ④分子分母有理化 ⑤公式法 ⑥等价无穷小量的代换 ⑦洛必达法则 ⑧换底公式(对数) P3入门练习填空题讲解&…

计算机组成与结构1800题,最新版数据结构1800题含完整答案详解

详细收录了全国几十所著名高校的数据结构考研真题,并附有完整、详尽的答案。非常适合考研复习和期末考试复习。 数据结构1800例题与答案 第一章 绪 论 一、选择题(每小题2分) 1.算法的计算量的大小称为计算的( B )。 【北京邮电大学2000 二、3 (20/8 分)】 A.效率 B.复杂性 …

HDU1800今年暑假不AC(贪心最大不相交)

Problem Description “今年暑假不AC?” “是的。” “那你干什么呢?” “看世界杯呀,笨蛋!” “#$%^&*%…” 确实如此,世界杯来了,球迷的节日也来了,估计很多ACMer也会抛开电脑&#xff…

x264详解

x264默认是基于帧的线程,比基于切片的吞吐量更好 帧线程添加帧等待时间是需要不同的帧上工作 x264最大线程数128,一般控制16个线程以内。 在基于片段线程的情况下,所有线程都在同一帧上工作。每个帧都被分割成片,每个片在一个核…

android 屏幕适配 drawable-hdpi-1920x1080 values-xhdpi-1800x1080 values-land-xhdpi-1824x1200

drawable-hdpi-1920x1080 values-xhdpi-1800x1080 values-land-xhdpi-1824x1200 1.屏幕分辨率与实际对应的分辨率不一致 今天遇到一个奇葩的事情,在适配华为MediaPad M1 8.0的时候,手机的实际分辨率为1280*800,但是在android自动适配的分辨…

android 屏幕适配 drawable-hdpi-1920x1080 values-xhdpi-1800x1080

drawable-hdpi-1920x1080 values-xhdpi-1800x1080 values-land-xhdpi-1824x1200 1.屏幕分辨率与实际对应的分辨率不一致 今天遇到一个奇葩的事情,在适配华为MediaPad M1 8.0的时候,手机的实际分辨率为1280*800,但是在android自动适配的分辨…