// 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);
}
ffmpeg编码示例
最新推荐文章于 2024-06-27 14:18:48 发布