使用ffmpeg将图片编码为x264视频文件

ffmpeg开源库,实现将bmp格式的图片编码成x264文件。参考资料:http://blog.csdn.net/eightdegree/article/details/7425635#reply

自己根据博客的代码,vs2010搭建的测试环境。资源下载

具体代码:

#define _AFXDLL
#include<afxwin.h>
#ifdef  __cplusplus
extern "C" {
#endif

#include <libavcodec/avcodec.h>
#include <libavformat/avformat.h>
#include <libswscale/swscale.h>
	void main()
	{
		CFile file[5];
		BYTE *szTxt[5];

		int nWidth = 0;
		int nHeight= 0;

		int nDataLen=0;

		int nLen;

		CString csFileName;
		for (int fileI = 1; fileI <= 5; fileI ++)
		{
			csFileName.Format("%d.bmp", fileI);
			file[fileI - 1].Open(csFileName,CFile::modeRead | CFile::typeBinary);
			nLen = file[fileI - 1].GetLength();

			szTxt[fileI -1] = new BYTE[nLen];
			file[fileI - 1].Read(szTxt[fileI - 1], nLen);
			file[fileI - 1].Close();

			//BMP bmi;//BITMAPINFO bmi;
			//int nHeadLen = sizeof(BMP);
			BITMAPFILEHEADER bmpFHeader;
			BITMAPINFOHEADER bmpIHeader;
			memcpy(&bmpFHeader,szTxt[fileI -1],sizeof(BITMAPFILEHEADER));

			int nHeadLen = bmpFHeader.bfOffBits - sizeof(BITMAPFILEHEADER);
			memcpy(&bmpIHeader,szTxt[fileI - 1]+sizeof(BITMAPFILEHEADER),nHeadLen);

			nWidth = bmpIHeader.biWidth;// 464;// bmi.bmpInfo.bmiHeader.biWidth;// ;
			nHeight = bmpIHeader.biHeight;//362;// bmi.bmpInfo.bmiHeader.biHeight;// ;

			szTxt[fileI - 1] += bmpFHeader.bfOffBits;
			nDataLen = nLen-bmpFHeader.bfOffBits;
		}
		getchar();
		av_register_all();
		avcodec_register_all();
		AVFrame *m_pRGBFrame =  new AVFrame[1];  //RGB帧数据
		AVFrame *m_pYUVFrame = new AVFrame[1];;  //YUV帧数据
		AVCodecContext *c= NULL;
		AVCodecContext *in_c= NULL;
		AVCodec *pCodecH264; //编码器
		uint8_t * yuv_buff;//

		//查找h264编码器
		pCodecH264 = avcodec_find_encoder(CODEC_ID_H264);
		if(!pCodecH264)
		{
			fprintf(stderr, "h264 codec not found\n");
			getchar();
			exit(1);
		}

		c= avcodec_alloc_context3(pCodecH264);
		c->bit_rate = 3000000;// put sample parameters
		c->width =nWidth;//
		c->height = nHeight;// 

		// frames per second
		AVRational rate;
		rate.num = 1;
		rate.den = 25;
		c->time_base= rate;//(AVRational){1,25};
		c->gop_size = 10; // emit one intra frame every ten frames
		c->max_b_frames=1;
		c->thread_count = 1;
		c->pix_fmt = PIX_FMT_YUV420P;//PIX_FMT_RGB24;

		//av_opt_set(c->priv_data, /*"preset"*/"libvpx-1080p.ffpreset", /*"slow"*/NULL, 0);
		//打开编码器
		if(avcodec_open2(c,pCodecH264,NULL)<0){
			printf("avcodec_open2 failed\n");
			TRACE("不能打开编码库");
			getchar();
		}

		int size = c->width * c->height;

		yuv_buff = (uint8_t *) malloc((size * 3) / 2); // size for YUV 420 

		//将rgb图像数据填充rgb帧
		uint8_t * rgb_buff = new uint8_t[nDataLen];

		//图象编码 outbuf_size太小会报错,图像清晰度也会差
		int outbuf_size = 900000;
		uint8_t * outbuf= (uint8_t*)malloc(outbuf_size);
		int u_size = 0;
		FILE *f=NULL;
		char * filename = "myData.h264";
		f = fopen(filename, "wb");
		if (!f)
		{
			TRACE( "could not open %s\n", filename);
			getchar();
			exit(1);
		}

		//初始化SwsContext
		SwsContext * scxt = sws_getContext(c->width,c->height,PIX_FMT_BGR24,c->width,c->height,PIX_FMT_YUV420P,SWS_POINT,NULL,NULL,NULL);

		AVPacket avpkt;

		//AVFrame *pTFrame=new AVFrame
		for (int i=0;i<250;++i)
		{

			//AVFrame *m_pYUVFrame = new AVFrame[1];

			int index = (i / 25) % 5;
			memcpy(rgb_buff,szTxt[index],nDataLen);

			avpicture_fill((AVPicture*)m_pRGBFrame, (uint8_t*)rgb_buff, PIX_FMT_RGB24, nWidth, nHeight);

			//将YUV buffer 填充YUV Frame
			avpicture_fill((AVPicture*)m_pYUVFrame, (uint8_t*)yuv_buff, PIX_FMT_YUV420P, nWidth, nHeight);

			// 翻转RGB图像
			m_pRGBFrame->data[0]  += m_pRGBFrame->linesize[0] * (nHeight - 1);
			m_pRGBFrame->linesize[0] *= -1;
			m_pRGBFrame->data[1]  += m_pRGBFrame->linesize[1] * (nHeight / 2 - 1);
			m_pRGBFrame->linesize[1] *= -1;
			m_pRGBFrame->data[2]  += m_pRGBFrame->linesize[2] * (nHeight / 2 - 1);
			m_pRGBFrame->linesize[2] *= -1;

			//将RGB转化为YUV
			sws_scale(scxt,m_pRGBFrame->data,m_pRGBFrame->linesize,0,c->height,m_pYUVFrame->data,m_pYUVFrame->linesize);

			static int got_packet_ptr = 0;
			av_init_packet(&avpkt);
			avpkt.data = outbuf;
			avpkt.size = outbuf_size;
			u_size = avcodec_encode_video2(c, &avpkt, m_pYUVFrame, &got_packet_ptr);
			m_pYUVFrame->pts++;
			if (u_size == 0)
			{
				fwrite(avpkt.data, 1, avpkt.size, f);
			}
		}

		fclose(f);
		delete []m_pRGBFrame;
		delete []m_pYUVFrame;
		delete []rgb_buff;
		free(outbuf);
		avcodec_close(c);
		av_free(c);

	}

#ifdef  __cplusplus
}
#endif

完全按照博客中的代码测试发现会报下面的信息,而且在播放过程中,画面都是模糊的。修改了outbuff_size的大小解决了这个问题。

疑问:为什么要循环250次?有知道麻烦解答下!

for (int i=0;i<250;++i)

时间: 2025-01-12 16:10:41

使用ffmpeg将图片编码为x264视频文件的相关文章

【学习ffmpeg】打开视频文件,帧分析,并bmp保存关键帧

http://www.tuicool.com/articles/jiUzua http://blog.csdn.net/code_future/article/details/8646717 主题 FFmpeg 任务:需要把一个视频文件的每一帧提取出来,每帧存储成单独的文件. 以前用Matlab处理过这个问题,可是感觉比较慢,而且最近正在逐步转向使用开源的东西.因此搜到ffmpeg这个好东西. ffmpeg可用来处理视频文件的提取和各种转换,跨平台,官网上有Linux,WINDOWS和MAC版本

使用FFmpeg处理视频文件:视频转码、剪切、合并、播放速调整

安装 略. 转码 最简单命令如下: ffmpeg -i out.ogv -vcodec h264 out.mp4ffmpeg -i out.ogv -vcodec mpeg4 out.mp4ffmpeg -i out.ogv -vcodec libxvid out.mp4ffmpeg -i out.mp4 -vcodec wmv1 out.wmvffmpeg -i out.mp4 -vcodec wmv2 out.wmv -i 后面是输入文件名.-vcodec 后面是编码格式,h264 最佳,但

流媒体学习笔记1:一个视频文件常用属性浅析之我见(bpp/vbr/resolution/fps)

因为工作原因,经常要接触视频相关的东西,而有一些视频常见的知识之前都是只知道个大概,甚至只是知道个名字的.很有必要对相关的知识整理下记录下来,以便有需要的人可以借鉴一二.但有些观点纯粹是天地会珠海分舵自己的理解,如果有误请指出,以免荼毒后人. 位深bpp 一般一个像素是由三原色RGB不同的颜色向量组成的,再加上个代表透明度的变量Alhpa值的话就是ARGB,当然,老一点的可能只有黑白,而没有RGB等.那么图片/视频文件中究竟由多少位来表示这些不同的颜色向量代表的就是位深,如只有黑白的话2位就足够

(转载)[FFmpeg]使用ffmpeg从各种视频文件中直接截取视频图片

你曾想过从一个视频文件中提取图片吗?在Linux下就可以,在这个教程中我将使用ffmpeg来从视频中获取图片. 什么是ffmpeg?What is ffmpeg? ffmpeg是一个非常有用的命令行程序,它可以用来转码媒体文件.它是领先的多媒体框架FFmpeg的一部分,其有很多功能,比如解码.编码.转码.混流.分离.转化为流.过滤以及播放几乎所有的由人和机器创建的媒体文件. 在这个框架中包含有各种工具,每一个用于完成特定的功能.例如,ffserver能够将多媒体文件转化为用于实时广播的流,ffp

Java使用FFmpeg处理视频文件指南

Java使用FFmpeg处理视频文件指南 本文主要讲述如何使用Java + FFmpeg实现对视频文件的信息提取.码率压缩.分辨率转换等功能: 之前在网上浏览了一大圈Java使用FFmpeg处理音视频的文章,大多都讲的比较简单,楼主在实操过程中踩了很多坑也填了很多坑,希望这份详细的踩坑&填坑指南能帮助到大家: 1. 什么是FFmpeg 点我了解 2. 开发前准备 在使用Java调用FFmpeg处理音视频之前,需要先安装FFmpeg,安装方法分为两种: 引入封装了FFmpeg的开源框架 在系统中手

ffmpeg与H264编码指南

ffmpeg与H264编码指南 注:本文属于转载译文,原文地址:http://blog.csdn.net/vblittleboy/article/details/8982857. 英文地址:https://trac.ffmpeg.org/wiki/Encode/H.264.内容有一定出入,但是可以借鉴学习. x264是一个 H.264/MPEG4 AVC 编码器,本指南将指导新手如何创建高质量的H.264视频. 对于普通用户通常有两种码率控制模式:crf(Constant Rate Factor

使用ffmpeg合并视频文件的三种方法

ffmpeg合并视频的方法有三种.国内大多数仅介绍了其中之一.于是觉得有必要翻译一下.其实在ffmpeg的 FAQ文档中有比较详细的说明. 使用concat协议进行视频文件的合并 这种方式的适用场景是:视频容器是MPEG-1, MPEG-2 PS或DV等可以直接进行合并的.换句话说,其实可以直接用cat或者copy之类的命令来对视频直接进行合并.很多文章介绍了这种方法,但适用性却没有提及.这并不是一个通用的方法.典型的命令示例如下: ffmpeg -i concat:"intermediate1

ffmpeg转码MPEG2-TS的音视频同步机制分析

http://blog.chinaunix.net/uid-26000296-id-3483782.html 一.FFmpeg忽略了adaptation_field()数据FFmpeg忽略了包含PCR值的adaptation_filed数据; 代码(libavformat/mpegts.c)分析如下: /* 解析TS包 */int handle_packet(MpegTSContext *ts, const uint8_t *packet){  ...   pid = AV_RB16(packe

用FFMPEG做基于图像变形的视频处理

用FFMPEG做基于图像变形的视频处理 在图像变形算法已知的情况下,我们已求得BMP图像的变形效果.因此,要处理视频,也需要把图像的帧提取出来.这里我使用的是FFMPEG. 步骤如下: 1. 分离音视频工a 和 v 2.将视频v的每一帧提取出来,打包成YUV文件 3.读YUV,将每一帧转成BMP图像,进行图像变形或其它处理,再转回YUV. 4.将新得到的所有YUV帧打包成一个新的YUV文件, 将此文件编码成H264 5.混流H264和第一步得到的音频a,得到新的视频文件. 以上步骤中所有的音视频