ffmpeg编码示例

// ffmpegTest.cpp : Defines the entry point for the console application.
//
//#include "stdafx.h"
#include "windows.h"
#include "time.h"

#include <avformat.h>
#include <avutil.h>
#include <avcodec.h>
#include <swscale.h>
#pragma comment(lib, "avcodec.lib")
#pragma comment(lib, "avformat.lib")
#pragma comment(lib, "avutil.lib")

void SaveBmp(AVCodecContext *CodecContex, AVFrame *Picture, int width, int height);

#define MAX_BUF_SIZE 256*1024	
int main(int argc, char* argv[])
{
	int ret=-1, i=0, videoindex=-1, nComplete=0, len=0, frame_index=0;
	unsigned char *pEnCodeBuf = new unsigned char[MAX_BUF_SIZE];
	char *sourceFile = "5.avi";
	char *destFile = "123.mp4";
	av_register_all();
		
	AVFormatContext *pInputFormatContext=NULL;
	AVCodec *pInputCodec = NULL;
	AVCodecContext *pInputCodecContext = NULL;
	AVPacket InPack;
	int videoWidth, videoHeight;

	AVOutputFormat *pOutputFmt = NULL;
	AVFormatContext *pOutFormatContext = NULL;
	AVCodecContext *pOutCodecContext = NULL;
	AVCodec *pOutCodec = NULL;
	AVStream *pOutStream = NULL;
	AVPacket OutPack;
	AVFrame OutFrame;
	if(av_open_input_file(&pInputFormatContext, sourceFile, NULL, 0, NULL) !=0 )
	{
		//打开输入文件
		printf("can't open the file %s\n",sourceFile);
		exit(1);
	}

	if(av_find_stream_info(pInputFormatContext)<0)
	{
		//查找流信息
		printf("can't find suitable codec parameters\n");
		goto lk_error;
	}
	
	for(i=0; i<pInputFormatContext->nb_streams; i++)
	{
		if(pInputFormatContext->streams[i]->codec->codec_type==CODEC_TYPE_VIDEO)
		{
			videoindex=i;
			break;
		}
	}

	if(-1 == videoindex)
	{
		//没有找到视频流
		goto lk_error;
	}
	
	pInputCodecContext = pInputFormatContext->streams[videoindex]->codec;
	pInputCodec = avcodec_find_decoder(pInputCodecContext->codec_id);
	if(NULL == pInputCodec)
	{
		//没有找到解码器
		goto lk_error;
	}
	if(avcodec_open(pInputCodecContext, pInputCodec) != 0)
	{
		//打开解码器失败
		goto lk_error;
	}

	videoWidth = pInputCodecContext->width;
	videoHeight = pInputCodecContext->height;

	pOutputFmt = guess_format(NULL, destFile, NULL);
	if(NULL == pOutputFmt)
	{
		//分析输出文件格式失败
		goto lk_error;
	}

	pOutFormatContext = av_alloc_format_context();
	if(NULL == pOutFormatContext)
	{
		goto lk_error;
	}

	pOutFormatContext->oformat = pOutputFmt;
	pOutStream = av_new_stream(pOutFormatContext, 0);
	if(NULL == pOutStream)
	{
		//创建流失败
		goto lk_error;
	}
	
	//设定转换编码参数
	pOutCodecContext = pOutStream->codec;
	pOutCodecContext->codec_id = CODEC_ID_MPEG4;
	pOutCodecContext->codec_type = CODEC_TYPE_VIDEO;
	pOutCodecContext->bit_rate = 98000;
	pOutCodecContext->width = videoWidth;
	pOutCodecContext->height = videoHeight;
	pOutCodecContext->time_base = pInputCodecContext->time_base;
	pOutCodecContext->gop_size = pInputCodecContext->gop_size;
	pOutCodecContext->pix_fmt = pInputCodecContext->pix_fmt;
	pOutCodecContext->max_b_frames = pInputCodecContext->max_b_frames;
	pOutCodecContext->time_base.den = 15;
	pOutCodecContext->time_base.num = 1;
	pOutStream->r_frame_rate = pInputFormatContext->streams[videoindex]->r_frame_rate;

	if (av_set_parameters(pOutFormatContext, NULL) < 0) 
	{
		//转换编码参数设置不正确
		goto lk_error;                               
	}
	
	strcpy(pOutFormatContext->title, pInputFormatContext->title);
	strcpy(pOutFormatContext->author, pInputFormatContext->author);
	strcpy(pOutFormatContext->copyright, pInputFormatContext->copyright);
	strcpy(pOutFormatContext->comment, pInputFormatContext->comment);
	strcpy(pOutFormatContext->album, pInputFormatContext->album);
	pOutFormatContext->year = pInputFormatContext->year;
	pOutFormatContext->track = pInputFormatContext->track;
	strcpy(pOutFormatContext->genre, pInputFormatContext->genre);

	pOutCodec = avcodec_find_encoder(CODEC_ID_MPEG4);
	if(NULL == pOutCodec)
	{
		//找不到指定编码器
		goto lk_error;
	}
	
	if(avcodec_open(pOutCodecContext, pOutCodec) < 0)
	{
		//打开指定编码器错误
		goto lk_error;
	}
	
	if (!(pOutFormatContext->flags & AVFMT_NOFILE))
	{
		if(url_fopen(&pOutFormatContext->pb, destFile, URL_WRONLY)<0)
		{
			//打开输出文件
			goto lk_error;
		}
	}

	if(av_write_header(pOutFormatContext) < 0)
	{
		//写入输出文件头失败
		goto lk_error;
	}

	while(av_read_frame(pInputFormatContext, &InPack) >= 0)
	{
		len = avcodec_decode_video(pInputCodecContext, &OutFrame, &nComplete, InPack.data, InPack.size);
		if(nComplete > 0)
		{
			//解码一帧成功
			SaveBmp(pInputCodecContext, &OutFrame, videoWidth, videoHeight);
			memset(pEnCodeBuf, 0, MAX_BUF_SIZE);
			OutFrame.pts = av_rescale(frame_index, AV_TIME_BASE*(int64_t)pOutCodecContext->time_base.num, pOutCodecContext->time_base.den);
			OutFrame.pict_type = 0;
			len = avcodec_encode_video(pOutCodecContext, pEnCodeBuf, MAX_BUF_SIZE, &OutFrame);   
			if (len > 0)            
			{  
				av_init_packet(&OutPack);                               
				if(pOutCodecContext->coded_frame && pOutCodecContext->coded_frame->key_frame)                                       
				{
					OutPack.flags |= PKT_FLAG_KEY;                                        
				}

				OutPack.flags = InPack.flags;                      
				OutPack.stream_index = InPack.stream_index;                                               
				OutPack.data = pEnCodeBuf;                                                         
				OutPack.size = len;                                             
				ret=av_write_frame(pOutFormatContext, &OutPack);                                       
			}
			frame_index++;
		}
		av_free_packet(&OutPack);
	}
	
	av_write_trailer(pOutFormatContext);
	for(i=0; i<pOutFormatContext->nb_streams; i++) 
	{            
		av_freep(&pOutFormatContext->streams[i]->codec);                       
		av_freep(&pOutFormatContext->streams[i]);                           
	}

lk_error:
	av_free(pOutCodec);
	av_free(pOutputFmt);
	avcodec_close(pInputCodecContext);
	av_free(pInputFormatContext);
	av_free(pOutFormatContext);

	return 0;
}

void SaveBmp(AVCodecContext *CodecContex, AVFrame *Picture, int width, int height)
{
	AVPicture pPictureRGB;//RGB图片

	static struct SwsContext *img_convert_ctx;
	img_convert_ctx = sws_getContext(width, height,	CodecContex->pix_fmt, width, height,\
		PIX_FMT_RGB24, SWS_BICUBIC, NULL, NULL, NULL);
	avpicture_alloc(&pPictureRGB, PIX_FMT_RGB24, width, height);
	sws_scale(img_convert_ctx, Picture->data, Picture->linesize,\
		0, height, pPictureRGB.data, pPictureRGB.linesize);
	
	int lineBytes = pPictureRGB.linesize[0], i=0;
	
	char fileName[1024]={0};
	time_t ltime;
	time(<ime);
	sprintf(fileName, "%d.bmp", ltime);
	
	FILE *pDestFile = fopen(fileName, "wb");
	BITMAPFILEHEADER btfileHeader;
	btfileHeader.bfType = MAKEWORD(66, 77); 
	btfileHeader.bfSize = lineBytes*height; 
	btfileHeader.bfReserved1 = 0; 
	btfileHeader.bfReserved2 = 0; 
	btfileHeader.bfOffBits = 54;

	BITMAPINFOHEADER bitmapinfoheader;
	bitmapinfoheader.biSize = 40; 
	bitmapinfoheader.biWidth = width; 
	bitmapinfoheader.biHeight = height; 
	bitmapinfoheader.biPlanes = 1; 
	bitmapinfoheader.biBitCount = 24;
	bitmapinfoheader.biCompression = BI_RGB; 
	bitmapinfoheader.biSizeImage = lineBytes*height; 
	bitmapinfoheader.biXPelsPerMeter = 0; 
	bitmapinfoheader.biYPelsPerMeter = 0; 
	bitmapinfoheader.biClrUsed = 0; 
	bitmapinfoheader.biClrImportant = 0;

	fwrite(&btfileHeader, 14, 1, pDestFile);
	fwrite(&bitmapinfoheader, 40, 1, pDestFile);
	for(i=height-1; i>=0; i--)
    {
		fwrite(pPictureRGB.data[0]+i*lineBytes, lineBytes, 1, pDestFile);
	}

	fclose(pDestFile);
	avpicture_free(&pPictureRGB);
}

  • 0
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值