ffmpeg编码示例

[html]  view plain copy
  1. // ffmpegTest.cpp : Defines the entry point for the console application.  
  2. //  
  3. //#include "stdafx.h"  
  4. #include "windows.h"  
  5. #include "time.h"  
  6.   
  7. #include <avformat.h>  
  8. #include <avutil.h>  
  9. #include <avcodec.h>  
  10. #include <swscale.h>  
  11. #pragma comment(lib, "avcodec.lib")  
  12. #pragma comment(lib, "avformat.lib")  
  13. #pragma comment(lib, "avutil.lib")  
  14.   
  15. void SaveBmp(AVCodecContext *CodecContex, AVFrame *Picture, int width, int height);  
  16.   
  17. #define MAX_BUF_SIZE 256*1024     
  18. int main(int argc, char* argv[])  
  19. {  
  20.     int ret=-1, i=0videoindex=-1, nComplete=0len=0frame_index=0;  
  21.     unsigned char *pEnCodeBuf = new unsigned char[MAX_BUF_SIZE];  
  22.     char *sourceFile = "5.avi";  
  23.     char *destFile = "123.mp4";  
  24.     av_register_all();  
  25.           
  26.     AVFormatContext *pInputFormatContext=NULL;  
  27.     AVCodec *pInputCodec = NULL;  
  28.     AVCodecContext *pInputCodecContext = NULL;  
  29.     AVPacket InPack;  
  30.     int videoWidth, videoHeight;  
  31.   
  32.     AVOutputFormat *pOutputFmt = NULL;  
  33.     AVFormatContext *pOutFormatContext = NULL;  
  34.     AVCodecContext *pOutCodecContext = NULL;  
  35.     AVCodec *pOutCodec = NULL;  
  36.     AVStream *pOutStream = NULL;  
  37.     AVPacket OutPack;  
  38.     AVFrame OutFrame;  
  39.     if(av_open_input_file(&pInputFormatContext, sourceFile, NULL, 0, NULL) !=0 )  
  40.     {  
  41.         //打开输入文件  
  42.         printf("can't open the file %s\n",sourceFile);  
  43.         exit(1);  
  44.     }  
  45.   
  46.     if(av_find_stream_info(pInputFormatContext)<0)  
  47.     {  
  48.         //查找流信息  
  49.         printf("can't find suitable codec parameters\n");  
  50.         goto lk_error;  
  51.     }  
  52.       
  53.     for(i=0; i<pInputFormatContext->nb_streams; i++)  
  54.     {  
  55.         if(pInputFormatContext->streams[i]->codec->codec_type==CODEC_TYPE_VIDEO)  
  56.         {  
  57.             videoindex=i;  
  58.             break;  
  59.         }  
  60.     }  
  61.   
  62.     if(-1 == videoindex)  
  63.     {  
  64.         //没有找到视频流  
  65.         goto lk_error;  
  66.     }  
  67.       
  68.     pInputCodecContext = pInputFormatContext->streams[videoindex]->codec;  
  69.     pInputCodec = avcodec_find_decoder(pInputCodecContext->codec_id);  
  70.     if(NULL == pInputCodec)  
  71.     {  
  72.         //没有找到解码器  
  73.         goto lk_error;  
  74.     }  
  75.     if(avcodec_open(pInputCodecContext, pInputCodec) != 0)  
  76.     {  
  77.         //打开解码器失败  
  78.         goto lk_error;  
  79.     }  
  80.   
  81.     videoWidth = pInputCodecContext->width;  
  82.     videoHeight = pInputCodecContext->height;  
  83.   
  84.     pOutputFmt = guess_format(NULL, destFile, NULL);  
  85.     if(NULL == pOutputFmt)  
  86.     {  
  87.         //分析输出文件格式失败  
  88.         goto lk_error;  
  89.     }  
  90.   
  91.     pOutFormatContext = av_alloc_format_context();  
  92.     if(NULL == pOutFormatContext)  
  93.     {  
  94.         goto lk_error;  
  95.     }  
  96.   
  97.     pOutFormatContext->oformat = pOutputFmt;  
  98.     pOutStream = av_new_stream(pOutFormatContext, 0);  
  99.     if(NULL == pOutStream)  
  100.     {  
  101.         //创建流失败  
  102.         goto lk_error;  
  103.     }  
  104.       
  105.     //设定转换编码参数  
  106.     pOutCodecContext = pOutStream->codec;  
  107.     pOutCodecContext->codec_id = CODEC_ID_MPEG4;  
  108.     pOutCodecContext->codec_type = CODEC_TYPE_VIDEO;  
  109.     pOutCodecContext->bit_rate = 98000;  
  110.     pOutCodecContext->width = videoWidth;  
  111.     pOutCodecContext->height = videoHeight;  
  112.     pOutCodecContext->time_base = pInputCodecContext->time_base;  
  113.     pOutCodecContext->gop_size = pInputCodecContext->gop_size;  
  114.     pOutCodecContext->pix_fmt = pInputCodecContext->pix_fmt;  
  115.     pOutCodecContext->max_b_frames = pInputCodecContext->max_b_frames;  
  116.     pOutCodecContext->time_base.den = 15;  
  117.     pOutCodecContext->time_base.num = 1;  
  118.     pOutStream->r_frame_rate = pInputFormatContext->streams[videoindex]->r_frame_rate;  
  119.   
  120.     if (av_set_parameters(pOutFormatContext, NULL) < 0)   
  121.     {  
  122.         //转换编码参数设置不正确  
  123.         goto lk_error;                                 
  124.     }  
  125.       
  126.     strcpy(pOutFormatContext->title, pInputFormatContext->title);  
  127.     strcpy(pOutFormatContext->author, pInputFormatContext->author);  
  128.     strcpy(pOutFormatContext->copyright, pInputFormatContext->copyright);  
  129.     strcpy(pOutFormatContext->comment, pInputFormatContext->comment);  
  130.     strcpy(pOutFormatContext->album, pInputFormatContext->album);  
  131.     pOutFormatContext->year = pInputFormatContext->year;  
  132.     pOutFormatContext->track = pInputFormatContext->track;  
  133.     strcpy(pOutFormatContext->genre, pInputFormatContext->genre);  
  134.   
  135.     pOutCodec = avcodec_find_encoder(CODEC_ID_MPEG4);  
  136.     if(NULL == pOutCodec)  
  137.     {  
  138.         //找不到指定编码器  
  139.         goto lk_error;  
  140.     }  
  141.       
  142.     if(avcodec_open(pOutCodecContext, pOutCodec) < 0)  
  143.     {  
  144.         //打开指定编码器错误  
  145.         goto lk_error;  
  146.     }  
  147.       
  148.     if (!(pOutFormatContext->flags & AVFMT_NOFILE))  
  149.     {  
  150.         if(url_fopen(&pOutFormatContext->pb, destFile, URL_WRONLY)<0)  
  151.         {  
  152.             //打开输出文件  
  153.             goto lk_error;  
  154.         }  
  155.     }  
  156.   
  157.     if(av_write_header(pOutFormatContext) < 0)  
  158.     {  
  159.         //写入输出文件头失败  
  160.         goto lk_error;  
  161.     }  
  162.   
  163.     while(av_read_frame(pInputFormatContext, &InPack) >= 0)  
  164.     {  
  165.         len = avcodec_decode_video(pInputCodecContext, &OutFrame, &nComplete, InPack.data, InPack.size);  
  166.         if(nComplete > 0)  
  167.         {  
  168.             //解码一帧成功  
  169.             SaveBmp(pInputCodecContext, &OutFrame, videoWidth, videoHeight);  
  170.             memset(pEnCodeBuf, 0, MAX_BUF_SIZE);  
  171.             OutFrame.pts = av_rescale(frame_index, AV_TIME_BASE*(int64_t)pOutCodecContext->time_base.num, pOutCodecContext->time_base.den);  
  172.             OutFrame.pict_type = 0;  
  173.             len = avcodec_encode_video(pOutCodecContext, pEnCodeBuf, MAX_BUF_SIZE, &OutFrame);     
  174.             if (len > 0)              
  175.             {    
  176.                 av_init_packet(&OutPack);                                 
  177.                 if(pOutCodecContext->coded_frame && pOutCodecContext->coded_frame->key_frame)                                         
  178.                 {  
  179.                     OutPack.flags |= PKT_FLAG_KEY;                                          
  180.                 }  
  181.   
  182.                 OutPack.flags = InPack.flags;                        
  183.                 OutPack.stream_index = InPack.stream_index;                                                 
  184.                 OutPack.data = pEnCodeBuf;                                                           
  185.                 OutPack.size = len;                                               
  186.                 ret=av_write_frame(pOutFormatContext, &OutPack);                                         
  187.             }  
  188.             frame_index++;  
  189.         }  
  190.         av_free_packet(&OutPack);  
  191.     }  
  192.       
  193.     av_write_trailer(pOutFormatContext);  
  194.     for(i=0; i<pOutFormatContext->nb_streams; i++)   
  195.     {              
  196.         av_freep(&pOutFormatContext->streams[i]->codec);                         
  197.         av_freep(&pOutFormatContext->streams[i]);                             
  198.     }  
  199.   
  200. lk_error:  
  201.     av_free(pOutCodec);  
  202.     av_free(pOutputFmt);  
  203.     avcodec_close(pInputCodecContext);  
  204.     av_free(pInputFormatContext);  
  205.     av_free(pOutFormatContext);  
  206.   
  207.     return 0;  
  208. }  
  209.   
  210. void SaveBmp(AVCodecContext *CodecContex, AVFrame *Picture, int width, int height)  
  211. {  
  212.     AVPicture pPictureRGB;//RGB图片  
  213.   
  214.     static struct SwsContext *img_convert_ctx;  
  215.     img_convert_ctx = sws_getContext(width, height, CodecContex->pix_fmt, width, height,\  
  216.         PIX_FMT_RGB24, SWS_BICUBIC, NULL, NULL, NULL);  
  217.     avpicture_alloc(&pPictureRGB, PIX_FMT_RGB24, width, height);  
  218.     sws_scale(img_convert_ctx, Picture->data, Picture->linesize,\  
  219.         0, height, pPictureRGB.data, pPictureRGB.linesize);  
  220.       
  221.     int lineBytes = pPictureRGB.linesize[0], i=0;  
  222.       
  223.     char fileName[1024]={0};  
  224.     time_t ltime;  
  225.     time(<ime);  
  226.     sprintf(fileName, "%d.bmp", ltime);  
  227.       
  228.     FILE *pDestFile = fopen(fileName, "wb");  
  229.     BITMAPFILEHEADER btfileHeader;  
  230.     btfileHeader.bfType = MAKEWORD(66, 77);   
  231.     btfileHeader.bfSize = lineBytes*height;   
  232.     btfileHeader.bfReserved1 = 0;   
  233.     btfileHeader.bfReserved2 = 0;   
  234.     btfileHeader.bfOffBits = 54;  
  235.   
  236.     BITMAPINFOHEADER bitmapinfoheader;  
  237.     bitmapinfoheader.biSize = 40;   
  238.     bitmapinfoheader.biWidth = width;   
  239.     bitmapinfoheader.biHeight = height;   
  240.     bitmapinfoheader.biPlanes = 1;   
  241.     bitmapinfoheader.biBitCount = 24;  
  242.     bitmapinfoheader.biCompression = BI_RGB;   
  243.     bitmapinfoheader.biSizeImage = lineBytes*height;   
  244.     bitmapinfoheader.biXPelsPerMeter = 0;   
  245.     bitmapinfoheader.biYPelsPerMeter = 0;   
  246.     bitmapinfoheader.biClrUsed = 0;   
  247.     bitmapinfoheader.biClrImportant = 0;  
  248.   
  249.     fwrite(&btfileHeader, 14, 1, pDestFile);  
  250.     fwrite(&bitmapinfoheader, 40, 1, pDestFile);  
  251.     for(i=height-1; i>=0; i--)  
  252.     {  
  253.         fwrite(pPictureRGB.data[0]+i*lineBytes, lineBytes, 1, pDestFile);  
  254.     }  
  255.   
  256.     fclose(pDestFile);  
  257.     avpicture_free(&pPictureRGB);  
  258. }  

你可能感兴趣的:(ffmpeg编码示例)