这个不能直接发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;

  1. }

工程下载:地址

FFmpeg将Jpeg 编码到视频中相关推荐

  1. FFmpeg命令(二)、 从视频中提取音频

    @[TOC](FFmpeg命令(二). 从视频中提取音频) 提取为mp3 ffmpeg -i huoying.mp4 -f mp3 -ar 16000 huoying.mp3 //huoying.mp ...

  2. FFmpeg命令(三)、 从视频中提取图片

    FFmpeg 从视频中提取图片 ffmpeg -i test.mp4 -r 30 image-%3d.jpg ffmpeg -i test.mp4 -r 30 -t 4 image-%3d.jpg f ...

  3. ffmpeg 向H.264编码的视频中添加 SEI

    SEI NALU数据格式 NALU 类型 1 字节 0x06 SEI 负载类型 1 字节 0x05 (用户自定义数据) 负载大小(uuid+自定义数据),如果大小 size 大于 255,前 int( ...

  4. ffmpeg 从现有视频中截取一段

    ffmpeg 从现有视频中截取一段 1. ffmpeg -i ./input.mp4 -vcodec copy -acodec copy -ss 00:00:10 -to 00:00:25 ./out ...

  5. 采用FFmpeg从视频中提取音频(声音)保存为mp3文件

    采用FFmpeg从视频中提取音频(声音)保存为mp3文件 作者:雨水,日期:2016年1月9日 CSDN博客:http://blog.csdn.net/gobitan 摘要:看到好的视频文件,如果想把 ...

  6. 音视频开发系列(24)使用FFmpeg添加、删除、替换和提取视频中的音频

    FFmpeg是一个超级强大的工具,它可以在视频文件中添加.删除.提取或者替换音频.如果你的电脑上已经安装了FFmpeg,那么你就拥有了可以给电影添加或删除音频的工具! 我们一起来看看FFmpeg是如何 ...

  7. 工作记录--使用FFmpeg将一个视频文件中音频合成到另一个视频中

    由于工作需要,临时被老大吩咐去研究一个FFmpeg工具,通过linux命令行去将一个视频中的音频提取出来并合成到另一个视频中,最终的效果是要保证2个视频中的音频都在一个视频中播放. 但是本人对FFmp ...

  8. 使用ffmpeg从视频中截取图像帧(最简单实用的视频抽帧,一句命令)

    Table of Contents 1.最佳方式 2.普通的命令:(画质差) 3. 视频旋转: 4. 批量视频抽帧: 参考:ffmpeg视频抽帧 1.最佳方式 第二种方法抽帧图片画质很差,这里提供更好 ...

  9. 使用FFmpeg添加、删除、替换和提取视频中的音频

    FFmpeg是一个超级强大的工具,它可以在视频文件中添加.删除.提取或者替换音频.如果你的电脑上已经安装了FFmpeg,那么你就拥有了可以给电影添加或删除音频的工具! 我们一起来看看FFmpeg是如何 ...

最新文章

  1. 【码书】一本经典且内容全面算法书籍,学算法必备
  2. 腾讯推出的这款高性能 RPC 开发框架,确定不了解下吗?
  3. (五)Maven目录结构及常用命令说明
  4. 利用cmake查看OpenCV的源码的方法
  5. 吴军:区块链催生了新的生产关系
  6. 如何在 Linux 虚拟机上扩展根文件系统
  7. android 去空字符串,android – TextUtils.isEmpty()方法为空字符串返回false
  8. raft引入no-op解决了什么问题
  9. c++中vector使用说明
  10. 16年蓝桥杯省赛-方格填数(dfs+回溯)
  11. 天然纤维复合材料行业调研报告 - 市场现状分析与发展前景预测
  12. SONY SVP1322 笔记本电脑升级
  13. PB12下geturl获取汉字乱码的解决
  14. 新零售电商O2O模式解析
  15. CentOS7快速配置服务器网卡聚合双bond方法
  16. 2021正睿noip十连day2
  17. 好家伙,这几个隐藏功能,太香了
  18. SpringCloud笔记(Hoxton)——Netflix之Eureka服务注册与发现
  19. 用经典的模拟退火算法求解30城市小规模的TSP问题
  20. 什么是中文分词及中文分词的应用

热门文章

  1. Android--框架布局
  2. 算法 - 输出一个字符串的全排列(C++)
  3. 机器人x展架制作_门型展架80*180易拉宝x展架海报架广告架立牌展示架地推海报2元优惠券券后价20元...
  4. php peridot 使用教程,PHP测试框架Peridot-支持BDD
  5. java 搜索业务怎么写_Java项目实战第11天:搜索功能的实现
  6. java的自动装箱和拆箱,Java中的自动装箱和拆箱是什么?
  7. 绝了!这个开源验证码项目,差点晚上瘾...
  8. 皮一皮:这剧透的太厉害了...
  9. 用低代码平台开发比用IDEA还牛逼吗?
  10. IDEA不能一个窗口管理多个项目?那是你不会用!