FFmpeg将Jpeg 编码到视频中
这个不能直接发h264,需要先解码,再编码
利用FFmpeg将Jpeg图片转为任意视频容器格式
原文: https://blog.csdn.net/oHanTanYanYing/article/details/45872093
在一些嵌入式系统中,视频以jpeg图像格式传出来,而且数据量非常大。这种情况下如果要对jpeg图像进行解码并且重新编码成264之类的格式再放入视频容器中会消耗大量的CPU资源,若不是性能特别犀利的CPU是无法承受的,这个时候有一个折衷的办法,就是直接将jpeg连续保存起来(也就是保存成mjpeg视频格式),然后直接放入视频容器中。
这个方面的代码实现网上资料比较少,可以说几乎没有,基本都是直接用FFmpeg的命令行来实现的,这一方法虽然可行但毕竟不太适合软件的集成,是故本人做了些研究,并将代码放出来供各位参考指正。
在贴出代码之前特别感谢雷霄骅老师的博客,其关于FFmpeg的博文提供了非常多的参考,如果对FFmpeg有深入了解需求的可以去看看,会有很多收获。
下面上代码:
环境为:VS2013 C++ 控制台程序(空项目)+ FFmpeg(配置相关可参考本人之前博文)
#include <stdio.h>
extern "C"//包含C文件头
{
#include "libavformat/avformat.h"
};
#define DATASIZE 1024*1024
AVStream *add_vidio_stream(AVFormatContext *oc, enum AVCodecID codec_id)//用以初始化一个用于输出的AVFormatContext结构体
{
AVStream *st;
AVCodec *codec;
st = avformat_new_stream(oc, NULL);
if (!st)
{
printf("Could not alloc stream\n");
exit(1);
}
codec = avcodec_find_encoder(codec_id);//查找mjpeg解码器
if (!codec)
{
printf("codec not found\n");
exit(1);
}
avcodec_get_context_defaults3(st->codec, codec);//申请AVStream->codec(AVCodecContext对象)空间并设置默认值(由avcodec_get_context_defaults3()设置
st->codec->bit_rate = 400000;//设置采样参数,即比特率
st->codec->width = 1080;//设置视频宽高,这里跟图片的宽高保存一致即可
st->codec->height = 1800;
st->codec->time_base.den = 10;//设置帧率
st->codec->time_base.num = 1;
st->codec->pix_fmt = PIX_FMT_YUV420P;//设置像素格式
st->codec->codec_tag = 0;
if (oc->oformat->flags & AVFMT_GLOBALHEADER)//一些格式需要视频流数据头分开
st->codec->flags |= CODEC_FLAG_GLOBAL_HEADER;
return st;
}
void main()
{
AVFormatContext *ofmt_ctx = NULL;//其包含码流参数较多,是一个贯穿始终的数据结构,很多函数都要用到它作为参数
const char *out_filename = "out.mkv";//输出文件路径,在这里也可以将mkv改成别的ffmpeg支持的格式,如mp4,flv,avi之类的
int ret;//返回标志
av_register_all();//初始化解码器和复用器
avformat_alloc_output_context2(&ofmt_ctx, NULL, NULL, out_filename);//初始化一个用于输出的AVFormatContext结构体,视频帧率和宽高在此函数里面设置
if (!ofmt_ctx)
{
printf("Could not create output context\n");
return;
}
AVStream *out_stream = add_vidio_stream(ofmt_ctx, AV_CODEC_ID_MJPEG);//创造输出视频流
av_dump_format(ofmt_ctx, 0, out_filename, 1);//该函数会打印出视频流的信息,如果看着不开心可以不要
if (!(ofmt_ctx->oformat->flags & AVFMT_NOFILE))//打开输出视频文件
{
ret = avio_open(&ofmt_ctx->pb, out_filename, AVIO_FLAG_WRITE);
if (ret < 0) {
printf("Could not open output file '%s'", out_filename);
return;
}
}
if (avformat_write_header(ofmt_ctx, NULL) < 0)//写文件头(Write file header)
{
printf("Error occurred when opening output file\n");
return;
}
int frame_index = 0;//放入视频的图像计数
unsigned char *mydata = new unsigned char[DATASIZE];
AVPacket pkt;
av_init_packet(&pkt);
pkt.flags |= AV_PKT_FLAG_KEY;
pkt.stream_index = out_stream->index;//获取视频信息,为压入帧图像做准备
while (frame_index<100)//将图像压入视频中
{
FILE *file;//打开一张jpeg图像并读取其数据,在这里图像最大为1M,如果超过1M,则需要修改1024*1024这里
fopen_s(&file, "1.jpg", "rb");
pkt.size = fread(mydata, 1, DATASIZE, file);
pkt.data = mydata;
fclose(file);
if (av_interleaved_write_frame(ofmt_ctx, &pkt) < 0) //写入图像到视频
{
printf("Error muxing packet\n");
break;
}
printf("Write %8d frames to output file\n", frame_index);//打印出当前压入的帧数
frame_index++;
}
av_free_packet(&pkt);//释放掉帧数据包对象
av_write_trailer(ofmt_ctx);//写文件尾(Write file trailer)
delete[]mydata;//释放数据对象
if (ofmt_ctx && !(ofmt_ctx->oformat->flags & AVFMT_NOFILE))
avio_close(ofmt_ctx->pb);//关闭视频文件
avformat_free_context(ofmt_ctx);//释放输出视频相关数据结构
return;
}
工程下载:地址
FFmpeg将Jpeg 编码到视频中相关推荐
- FFmpeg命令(二)、 从视频中提取音频
@[TOC](FFmpeg命令(二). 从视频中提取音频) 提取为mp3 ffmpeg -i huoying.mp4 -f mp3 -ar 16000 huoying.mp3 //huoying.mp ...
- FFmpeg命令(三)、 从视频中提取图片
FFmpeg 从视频中提取图片 ffmpeg -i test.mp4 -r 30 image-%3d.jpg ffmpeg -i test.mp4 -r 30 -t 4 image-%3d.jpg f ...
- ffmpeg 向H.264编码的视频中添加 SEI
SEI NALU数据格式 NALU 类型 1 字节 0x06 SEI 负载类型 1 字节 0x05 (用户自定义数据) 负载大小(uuid+自定义数据),如果大小 size 大于 255,前 int( ...
- ffmpeg 从现有视频中截取一段
ffmpeg 从现有视频中截取一段 1. ffmpeg -i ./input.mp4 -vcodec copy -acodec copy -ss 00:00:10 -to 00:00:25 ./out ...
- 采用FFmpeg从视频中提取音频(声音)保存为mp3文件
采用FFmpeg从视频中提取音频(声音)保存为mp3文件 作者:雨水,日期:2016年1月9日 CSDN博客:http://blog.csdn.net/gobitan 摘要:看到好的视频文件,如果想把 ...
- 音视频开发系列(24)使用FFmpeg添加、删除、替换和提取视频中的音频
FFmpeg是一个超级强大的工具,它可以在视频文件中添加.删除.提取或者替换音频.如果你的电脑上已经安装了FFmpeg,那么你就拥有了可以给电影添加或删除音频的工具! 我们一起来看看FFmpeg是如何 ...
- 工作记录--使用FFmpeg将一个视频文件中音频合成到另一个视频中
由于工作需要,临时被老大吩咐去研究一个FFmpeg工具,通过linux命令行去将一个视频中的音频提取出来并合成到另一个视频中,最终的效果是要保证2个视频中的音频都在一个视频中播放. 但是本人对FFmp ...
- 使用ffmpeg从视频中截取图像帧(最简单实用的视频抽帧,一句命令)
Table of Contents 1.最佳方式 2.普通的命令:(画质差) 3. 视频旋转: 4. 批量视频抽帧: 参考:ffmpeg视频抽帧 1.最佳方式 第二种方法抽帧图片画质很差,这里提供更好 ...
- 使用FFmpeg添加、删除、替换和提取视频中的音频
FFmpeg是一个超级强大的工具,它可以在视频文件中添加.删除.提取或者替换音频.如果你的电脑上已经安装了FFmpeg,那么你就拥有了可以给电影添加或删除音频的工具! 我们一起来看看FFmpeg是如何 ...
最新文章
- 【码书】一本经典且内容全面算法书籍,学算法必备
- 腾讯推出的这款高性能 RPC 开发框架,确定不了解下吗?
- (五)Maven目录结构及常用命令说明
- 利用cmake查看OpenCV的源码的方法
- 吴军:区块链催生了新的生产关系
- 如何在 Linux 虚拟机上扩展根文件系统
- android 去空字符串,android – TextUtils.isEmpty()方法为空字符串返回false
- raft引入no-op解决了什么问题
- c++中vector使用说明
- 16年蓝桥杯省赛-方格填数(dfs+回溯)
- 天然纤维复合材料行业调研报告 - 市场现状分析与发展前景预测
- SONY SVP1322 笔记本电脑升级
- PB12下geturl获取汉字乱码的解决
- 新零售电商O2O模式解析
- CentOS7快速配置服务器网卡聚合双bond方法
- 2021正睿noip十连day2
- 好家伙,这几个隐藏功能,太香了
- SpringCloud笔记(Hoxton)——Netflix之Eureka服务注册与发现
- 用经典的模拟退火算法求解30城市小规模的TSP问题
- 什么是中文分词及中文分词的应用
热门文章
- Android--框架布局
- 算法 - 输出一个字符串的全排列(C++)
- 机器人x展架制作_门型展架80*180易拉宝x展架海报架广告架立牌展示架地推海报2元优惠券券后价20元...
- php peridot 使用教程,PHP测试框架Peridot-支持BDD
- java 搜索业务怎么写_Java项目实战第11天:搜索功能的实现
- java的自动装箱和拆箱,Java中的自动装箱和拆箱是什么?
- 绝了!这个开源验证码项目,差点晚上瘾...
- 皮一皮:这剧透的太厉害了...
- 用低代码平台开发比用IDEA还牛逼吗?
- IDEA不能一个窗口管理多个项目?那是你不会用!