编译ffmpeg(第一次),实现JPG转MP4
ffpmeg网址:http://ffmpeg.org/
ffmpegapi文档:http://ffmpeg.org/doxygen/trunk/index.html
因为这是JPG转MP4,所以不涉及音频部分,可参考例子解码:http://ffmpeg.org/doxygen/trunk/decode_video_8c-example.html 编码:http://ffmpeg.org/doxygen/trunk/encode_video_8c-example.html
一、读取到的JPG图像内容需要解码:
1、打开一个解码器需要的内容
AVCodec* pDecodec;
AVCodecContext* pDecodecCtx;
AVFrame* pDeFrame;
AVPacket pDePacket;
//读取jpg用的解码器mjpeg
pDecodec = avcodec_find_decoder(AV_CODEC_ID_MJPEG);
//获取解码器上下文
pDecodecCtx = avcodec_alloc_context3(pDecodec);
pDecodecCtx->width = 512;
pDecodecCtx->height = 512;
pDecodecCtx->pix_fmt = AV_PIX_FMT_RGB24;
//打开解码器
avcodec_open2(pDecodecCtx,pDecodec,NULL);
2、解码操作
//用一个avstream来接收解码的数据帧
pDeFrame = av_frame_alloc();
//初始化一个ffmpeg的数据包
av_init_packet(&pDePacket);
unsigned char *jpgdata = new unsigned char[2048*2048];
FILE *file;
file = fopen([需要打开的文件全路径], "rw");
int readlen = fread(jpgdata, 1, 2048*2048, file);
//调用解码器解码
avcodec_decode_video2(pDecodecCtx,pDeFrame,&deCFflag,&pDePacket);
二、创建打开编码器
AVCodec* pEncodec;
AVCodecContext* pEncodecCtx;
AVFrame* pEnFrame;
AVPacket pEnPacket; pEncodecCtx = pVideoStream->codec;
pEncodecCtx->codec_id = pOutPutFormatCtx->oformat->video_codec;
pEncodecCtx->codec_type = AVMEDIA_TYPE_VIDEO;
pEncodecCtx->pix_fmt = AV_PIX_FMT_YUV420P;
pEncodecCtx->width = 720;
pEncodecCtx->height = 576;
//pEncodecCtx->bit_rate = 400000; 码流 适用于网络传输
pEncodecCtx->gop_size = 1;
pEncodecCtx->time_base.num = 1;
pEncodecCtx->time_base.den = 25;
pEncodecCtx->qmin = 10;
pEncodecCtx->qmax = 51;
pEncodecCtx->max_b_frames=3;
//质量 文件
pEncodecCtx->bit_rate = 0;
av_opt_set_int(pEncodecCtx->priv_data,"crf",0,0);
//在文件头写入文件信息(默认在每个包写入文件信息,微软默认播放器可能播放不了)
pEncodecCtx->flags |= AV_CODEC_FLAG_GLOBAL_HEADER;
//找一个视频编码器
pEncodec = avcodec_find_encoder(pEncodecCtx->codec_id);
//打开编码器
avcodec_open2(pEncodecCtx,pEncodec,NULL); int picture_size =0;
uint8_t* picture_buf;
//初始换编码用avframe
pEnFrame = av_frame_alloc();
//编码的图像大小
picture_size = avpicture_get_size(pEncodecCtx->pix_fmt,pEncodecCtx->width,pEncodecCtx->height);
//编码图像buf
picture_buf = (uint8_t *)av_malloc(picture_size);
//关联相关属性
avpicture_fill((AVPicture *)pEnFrame,picture_buf, pEncodecCtx->pix_fmt,pEncodecCtx->width,pEncodecCtx->height);
pEnFrame->width = pEncodecCtx->width;
pEnFrame->height = pEncodecCtx->height;
pEnFrame->format = pEncodecCtx->pix_fmt;
//初始话编码的包
av_init_packet(&pEnPacket);
三、输出文件的信息
AVFormatContext* pOutPutFormatCtx;
AVStream* pVideoStream; avformat_alloc_output_context2(&pOutPutFormatCtx, NULL, NULL, [输出的文件全路径].c_str());
pVideoStream = avformat_new_stream(pOutPutFormatCtx, NULL);
avio_open(&pOutPutFormatCtx->pb,[输出的文件全路径],AVIO_FLAG_READ_WRITE);
av_dump_format(pOutPutFormatCtx,0,[输出的文件全路径],1);
//将编码器的信息与输出的信息属性关联起来
avcodec_parameters_from_context(pVideoStream->codecpar,pEncodecCtx);
av_codec_get_tag2(pOutPutFormatCtx->oformat->codec_tag, pEncodecCtx->codec_id, &pVideoStream->codecpar->codec_tag);
//写输出的文件的头
avformat_write_header(pOutPutFormatCtx,NULL);
四、转码,将用解码器打开的jpg文件转码成需要编码的Frame格式
//FFmpeg的一个转换类
SwsContext* pImagectx; pImagectx = sws_getContext(pDecodecCtx->width, pDecodecCtx->height, pDecodecCtx->pix_fmt,pEncodecCtx->width,pEncodecCtx->height, pEncodecCtx->pix_fmt,SWS_BICUBIC, NULL,NULL, NULL); sws_scale(pImagectx,pDeFrame->data,pDeFrame->linesize,0,pDeFrame->height,pEnFrame->data,pEnFrame->linesize);
五、编码写文件
注释信息为测试读取文件的逻辑
//snprintf(imagename, 255, "%d.jpg", i);//X.jpg
//string imagefilePath = dir + imagename;
//printf("---");
//printf(imagefilePath.c_str());
//printf("\n");
//FILE *file;
//file = fopen(imagefilePath.c_str(), "rw");
//int readlen = fread(jpgdata, 1, 2048*2048, file);
//printf("----read file success %d \n",readlen);
//fclose(file);
//pDePacket.data = jpgdata;
//pDePacket.size = readlen;
//int decodecresult = avcodec_decode_video2(pDecodecCtx,pDeFrame,&deCFflag,&pDePacket);
//printf("----decodecresult %d \n",decodecresult);
//sws_scale(pImagectx,pDeFrame->data,pDeFrame->linesize,0,pDeFrame->height,pEnFrame->data,pEnFrame->linesize);
int gotpicture = 0;
pEnFrame->pts = i;
//编码
avcodec_encode_video2(pEncodecCtx,&pEnPacket,pEnFrame,&gotpicture);
//printf("----encodecresult %d \n",gotpicture);
pEnPacket.pts = av_rescale_q(pEnPacket.pts, rational, pVideoStream->time_base);
pEnPacket.stream_index = pVideoStream->index;
//将编码得到的包写入输出文件
av_write_frame(pOutPutFormatCtx,&pEnPacket);
//写文件尾
av_write_trailer(pOutPutFormatCtx);
六、释放资源
av_free_packet(&pDePacket);
if(pDeFrame != NULL)
{
av_free(pDeFrame);
}
if(pDecodecCtx != NULL)
{
avcodec_close(pDecodecCtx);
}
av_free_packet(&pEnPacket);
if(pEnFrame != NULL)
{
av_free(pEnFrame);
}
if(pEncodecCtx != NULL)
{
avcodec_close(pEncodecCtx);
} if(pOutPutFormatCtx!= NULL)
{
avformat_free_context(pOutPutFormatCtx);
}
if(pVideoStream != NULL)
{
av_free(pVideoStream);
}
if(pImagectx != NULL)
{
sws_freeContext(pImagectx);
}
编译ffmpeg(第一次),实现JPG转MP4的更多相关文章
- 第一次编译ffmpeg
今天开始玩ffmpeg了. 从官网下载来的压缩包,不会编译诶,于是我开始研究起来了. 下面就是实时记录的随笔: 首先是从官网下载来的ffmpeg,就是下面这个版本,目前的最新版吧. http://ff ...
- 开源项目:windows下使用MinGW+msys编译ffmpeg
本文参考了网络上的不少文章,但由于版本环境的问题参考文章并不能直接指导编译,本文吸收多方经验,并在自己多次编译实验的基础上写成,欢迎转载,请注名出处. FFmpeg是在Linux平台下开发的,但 ...
- anroid ndk编译ffmpeg 引用librtmp libx264
Ffmpeg 无处不在,自然android系统少不了它,折腾了不少时间完成 ndk编译ffmpeg,生成so库中引用了外部库librtmp,libx264.条条大路通罗马, 也许还有别的更好的方法去完 ...
- windows 下使用 MinGW + msys 编译 ffmpeg
本文参考了网络上的不少文章,但由于版本环境的问题参考文章并不能直接指导编译,本文吸收多方经验,并在自己多次编译实验的基础上写成,欢迎转载,请注名出处. FFmpeg是在Linux平台下开发的,但 ...
- Windows环境下使用cygwin ndk_r9c编译FFmpeg
一.废话 最近学习,第一步就是编译.我们需要编译FFmpag,x264,fdk_aac,一步步来.先来讲一下FFmpeg,网上说的很多都是几百年前的,我亲测完美可用 联系我可以直接评论,也可以加我Q ...
- MinGW下简单编译FFmpeg
2009.03.21补充:ffmpeg-0.5正式发布,地址为:[url]http://www.ffmpeg.org/releases/ffmpeg-0.5.tar.bz2[/url].修改了第7步, ...
- Mac系统编译FFmpeg
转载请标明来源:我不是掌柜的博客 前言 维基百科解释:FFmpeg是一个开源软件,可以运行音频和视频多种格式的录影.转换.流功能,包含了libavcodec – 这是一个用于多个项目中音频和视频的解码 ...
- 一步步实现windows版ijkplayer系列文章之一——Windows10平台编译ffmpeg 4.0.2,生成ffplay
一步步实现windows版ijkplayer系列文章之一--Windows10平台编译ffmpeg 4.0.2,生成ffplay 一步步实现windows版ijkplayer系列文章之二--Ijkpl ...
- Linux下编译ffmpeg并用GDB调试
1.在Ubuntu界面上调处命令行界面,最方便的方式是使用快捷键Ctrl+Alt+T. 2.安装SDL SDL是一个开源的多媒体开发库,可以设置图像和视频的绘制等操作.如果不安装SDL,FFMPEG将 ...
- ubuntu下编译ffmpeg+SDL+ffplay提取motion vector
编译ffmpeg: 第一步: 从官网http://ffmpeg.org/下载最新版本. 解压tar -xjvf ffmpeg-3.3.1.tar.bz2 进入目录cd ffmpeg-3.3.1 第二步 ...
随机推荐
- 【剑指offer】51.构建乘积数组
51.构建乘积数组 知识点:数组: 题目描述 给定一个数组A[0,1,...,n-1],请构建一个数组B[0,1,...,n-1],其中B中的元素B[i]=A[0] * A[1] *... * A[i ...
- PAT甲级:1036 Boys vs Girls (25分)
PAT甲级:1036 Boys vs Girls (25分) 题干 This time you are asked to tell the difference between the lowest ...
- Delimiter must not be alphanumeric or backslash php报错原因
昨天写了一个小程序,其中用到了正则表达式去匹配内容. php源代码如下: preg_match("\b(\w+)\b\s+\1\b",$match): 此报错警告的中文意思是 ...
- SDN与OpenFlow架构--初识
一,为什么需要SDN 1,传统网络的缺点: a,传统网络及其设备的只可配置,不可编程,只能按照已定义好的协议处理或转发数据,不能适应需求新变化,不能自主开发新功能. 如购买一个电饭煲,可以煮饭,煲汤. ...
- RedHat7.4安装在个人电脑(笔记本)中安装遇到的问题总结
RedHat7.4安装在个人电脑(笔记本)中安装 以下纯属个人在安装过程中遇到问题的一些总结,如果有描述不恰当的地方,还请给予指出,欢迎大家评论和交流. 物理主机的配置: 硬件配置: 华硕A456U笔 ...
- mongo-express 远程代码执行漏洞(CVE-2019-10758)
影响版本 mongo-express 0.53.0 POST /checkValid HTTP/1.1 Host: 192.168.49.2:8081 Accept-Encoding: gzip, d ...
- DC-7靶机
仅供个人娱乐 靶机信息 下载地址:http://www.five86.com/downloads/DC-7.zip 一.主机扫描 二.信息收集 或者 python3 cmseek.py --url h ...
- 巧用map解决nginx的Location里if失效问题
需求: Nginx根据参数来输出不同的header 我们想用Nginx来判断一些通用的参数, 根据参数情况在输出中不同的header, 或者cookie, 那么根据正常思路, 有如下配置: locat ...
- 使用 GLFW 在 OpenGL 的场景中漫游
前言 前面已经建立了 OpenGL 框架,加载了 3D 模型,但是还没有在场景中漫游的功能.为了展示 3D 模型,我只是简单地利用变换视图矩阵的方式使模型在视野中旋转.同时,之前的程序连最简单的改变窗 ...
- C++ 1//设计立方体类 //创建立方体的类 //设计属性和行为 //获取立方体的面积和体积 //分别利用(全局函数 和 成员函数)判断俩个立方体是否相等
1 //设计立方体类 2 //创建立方体的类 3 //设计属性和行为 4 //获取立方体的面积和体积 5 //分别利用(全局函数 和 成员函数)判断俩个立方体是否相等 6 #include <i ...