目录
1. 获取编码器AVCodec
2. 分配编码上下文AVCodecContext
3. 设置编码参数
3.1 音频
ctx->codec_id = AV_CODEC_ID_AAC;
ctx->codec_type = AV_MEDIA_TYPE_AUDIO;
ctx->bit_rate = 128 * 1024;
ctx->channel_layout = AV_CH_LAYOUT_STEREO;
ctx->sample_rate = 48000;
ctx->channels = av_get_channel_layout_nb_channels(ctx->channel_layout);
ctx->profile = FF_PROFILE_AAC_LOW;
ctx->sample_fmt = sample_fmt;
ctx->flags = AV_CODEC_FLAG_GLOBAL_HEADER;
3.2 视频
ctx->width = 1280;
ctx->height = 720;
ctx->time_base = (AVRation){1, 25};
ctx->framerate = (AVRation){25, 1};
ctx->gop_size = 25;
ctx->max_b_frames = 0;
ctx->pix_fmt = AV_PIX_FMT_YUV420P;
ctx->bit_rate = 3000000;
4. 关联编码器与编码上下文
5. 创建frame与packet
6. 初始化frame参数,编码格式
6.1音频参数
frame->nb_samples = ctx->frame_size;
frame->format = ctx->sample_fmt;
frame->channel_layout = ctx->channel_layout;
frame->channels = av_get_channel_layout_nb_channels(frame- >channel_layout);
6.2 视频参数
frame->foramt = ctx->pix_fmt;
frame->width = ctx->width;
frame->height = ctx->height;
7. 为frame中buffer分配内存
8. 循环读取数据进行编码
8.1. 音频逐帧读取pcm数据
- 循环从文件中读取一帧数据(编码一个frame)
- bytes = av_get_bytes_per_sample() * channles * nb_samples
- 设置采样帧可写属性
- 将读取到的数据bytes写入到frame中
- av_samples_fill_arrays
- 更新pts:以样本数量为time_base
- pts += frame->nb_samples
- 编码frame为packet
- av_send_frame
- av_receive_packet
- 判断需要增加adts帧头add_adts_header
- 转储packet
8.2 . 视频逐帧读取yuv数据
- 循环从yuv文件中读取一帧数据(编码一个frame)
- bytes = av_image_get_buffer_size();
- 设置视频帧数据可写属性
- av_frame_make_writable
- 将读取到的yuv数据填充到frame中
- av_image_fill_arrays
- 更新pts:以framerate为单位
- frame->pts += 40
- 编码frame为packet
- avcodec_send_frame
- avcodec_receive_packet
- 写编码文件
9. 冲刷编码数据队列
10. 释放资源
av_frame_free
av_packet_free
avcodec_free_context