一 RGB------->YUV
1.sws_getCachedContext : 像素格式转换上下文(大小也转化)
sws_getCachedContext(struct SwsContext *context , int srcW , int srcH , enum AVPixelFormat srcFormat
int dstW , int dst H , enum AVPixelFormat dstFormat , int flag)
format : AV_PIX_FMT_YUV420P (连续存放YYYY UUVV)
SwsContext : 如果为null 的时候,它会自动创建一个新的,如果不为空,它会根据你传入的数值是否和你配置一样.
如果相同,直接返回内容,如果不同,清除掉你的配置的内容,并返回上下文
flag : 对应图像算法的标志位 //SWS_BICUBIC (尺寸变化使用算法)
2.sws_scale(struct SwsContext *context , srcSlice(高度 Slice[0]Slice[1]Slice[2]) , srcStride(对齐策略--->宽度) ,
srcSilceY(从哪一个位置计算) , srcSliceH(1280*720 H=720) , dst , dstStride) : 对每一帧数据进行转换
输出数据结构
//分配对象的空间
AVFrame *yuv = av_frame_alloc();
yuv->format = AV_PIX_FMT_YUV420P
yuv->width = inWidth
yuv->height = inHeight
yuv->pts = 0
//分配yuv空间
av_frame_get_buffer(yuv , (alignment多少位作为对齐策略)32)
输入数据结构
uint_t *indata[8] = {0};
对于交错存放的数据格式 indata[0] bgrbgrbgr
对于planne(平面存放)的数据格式 indata[0] bbbbb indata[1]ggggg indata[2] rrrrr
indata[0] = frame.data(存放的数据格式RGB交错模式)
int inLineSize[8] = {0};
//一行(宽)数据的字节数
inLineSize[0] = frame.cols(列----->代表宽度) * (frame.elemSize()-----> 代表每一个像素的大小); int h = sws_scale(vsc , indata , inLineSize , 0 , frame.rows(行数--->代表就是高度) , yuv->data , yuv->inLineSize);
二 H264编码
1.找到编码器
avcodec_find_encoder(......) : 通过ID找到编码器
AVCodec *codec = avcodec_find_encoder(AV_CODEC_ID_H264)
avcodec_find_encodec_by_name(.....) :通过名字去找编码器
2.编码上下文空间(为了编码可以缓存)
AVCodecContext *vc = accodec_alloc_context3((AVCodec * code:代表参数) codec)
3. 配置编码器的参数
vc->flags |= AV_CODEC_FLAG_GLOBAL_HEADER //全局参数
vc->codec_id = codec->id
vc->thread_count = 4 ;
针对视频的参数的配置
vc->bit_rate = 50*1024*8 (50KB) //码率, 压缩率 50*1024(kb)*8(字节数)
vc->width = inWidth
vc->height = inHight
vc->time_base(时间基数单位是秒) = {1 , fps}---------> 1 / fps
vc->time_framerate = {fps , 1}---------> fps / 1
vc->gop_size = 50 //画面组的大小,多少帧为一个关键帧,越大压缩率越好,但是容易丢失
vc->max_b_frames = 0; //当B帧为0的时候 , pts和bts显示一致
vc->pix_fmt = AV_PIX_FMT_YUV420P //像素格式
4.打开编码器
avcodec_open2(vc , 0 , 0);
avcodec_open2
三 推流