源文件:
- #include <iostream>
- using namespace std;
- extern "C" { //指定函数是c语言函数,函数名不包含重载标注
- //引用ffmpeg头文件
- #include <libavcodec/avcodec.h>
- }
- //预处理指令导入库
- #pragma comment(lib,"avcodec.lib")
- #pragma comment(lib,"avutil.lib")
- int main(int argc, char* argv[])
- {
- //1 找到编码器
- AVCodec* codec = avcodec_find_encoder(AV_CODEC_ID_H264);
-
- //2 编码上下文的创建
- AVCodecContext* c = avcodec_alloc_context3(codec);
-
- //3设定上下文参数
- c->width = 400;//视频宽度
- c->height = 300;
- c->time_base = { 1,25 };// 1/25,pts*time_base = 播放时间(秒)
- c->pix_fmt = AV_PIX_FMT_YUV420P;//指定元数据的像素格式 与编码算法相关 h264只能yuv420;
- c->thread_count = 16;//编码的线程数 可以调用系统接口获取cpu核心数
- //4 打开编码上下文
- int re = avcodec_open2(c, codec, NULL);
-
- cout << "avcodec_open2 succece!" << endl;
- //5 创建avframe,存储的是未压缩的元数据
- auto frame = av_frame_alloc();
- frame->width = 400;
- frame->height = 300;
- frame->format = c->pix_fmt;
- re = av_frame_get_buffer(frame, 0);
- auto pkt = av_packet_alloc();
- //6 十秒视频 250帧
- for (int i = 0; i < 250; i++)
- {
- //6.1生成AVFrame 数据 每帧数据不同
- //Y
- for (int y = 0; y < c->height; y++)
- {
- for (int x = 0; x < c->width; x++)
- {
- frame->data[0][y * frame->linesize[0] + x] = x + y + i * 3;
- }
- }
- //UV
- for (int y = 0; y < c->height / 2; y++)
- {
- for (int x = 0; x < c->width / 2; x++)
- {
- frame->data[1][y * frame->linesize[1] + x] = 128 + y + i * 2;
- frame->data[2][y * frame->linesize[2] + x] = 64 + x + i * 5;
- }
- }
- frame->pts = i;//显示的时间
- //6.2发送未压缩的帧到线程中进行压缩
-
- //对于解码,调用avcodec_send_packet()以将AVPacket中的原始压缩数据提供给解码器。
- //对于编码,调用avcodec_send_frame()为编码器提供包含未压缩音频或视频的AVFrame。
- re = avcodec_send_frame(c, frame);//此时编码器有了元数据
-
- //6.3接收压缩帧,一般前几次调用返回空(缓冲,立刻返回,编码未完成)
- //编码是在另外独立线程中进行编码的
- //每次调用会重新分配pkt中的空间
- while (re >= 0)//返回多个帧
- {
- //要解码,请调用avcodec_receive_frame()。成功后,它将返回包含未压缩音频或视频数据的AVFrame 。
- //对于编码,请调用avcodec_receive_packet()。成功时,它将返回带有压缩帧的AVPacket 。重复此调用,直到返回AVERROR(EAGAIN)或错误。
- re = avcodec_receive_packet(c, pkt);//此时对编码器中的元数据进行压缩到avpacket中
- cout << pkt->size << " " << flush;//输出压缩后的数据大小 单位为kb
- av_packet_unref(pkt);
- }
- }
- av_packet_free(&pkt);
- av_frame_free(&frame);
- avcodec_free_context(&c);//释放编码器上下文
- auto b = getchar();
- return 0;
- }
复制代码 运行效果:
可以看出这250帧中,根本上每帧就几千kb,压缩后的数据存储在avpacket中,下一步我们把数据写进文件并播放出来
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。 |