YUV420P像素数据编码为JPEG图片

本文的编码器实现了YUV420P的数据编码为JPEG图片。本着简单的原则,代码基本上精简到了极限。使用了2014年5月6号编译的最新的FFMPEG类库。

程序很简单,打开工程后直接运行即可将YUV数据编码为JPEG。本程序十分灵活,可以根据需要修改成编码各种图像格式的编码器,比如PNG,GIF等等。平台使用VC2010。

  1.  * 本程序实现了YUV420P像素数据编码为JPEG图片。是最简单的FFmpeg编码方面的教程。 
  2.  * 通过学习本例子可以了解FFmpeg的编码流程。 
  3.  */  
  4.   
  5. #include   
  6.   
  7. #define __STDC_CONSTANT_MACROS  
  8.   
  9. #ifdef _WIN32  
  10. //Windows  
  11. extern "C"  
  12. {  
  13. #include "libavcodec/avcodec.h"  
  14. #include "libavformat/avformat.h"  
  15. };  
  16. #else  
  17. //Linux...  
  18. #ifdef __cplusplus  
  19. extern "C"  
  20. {  
  21. #endif  
  22. #include   
  23. #include   
  24. #ifdef __cplusplus  
  25. };  
  26. #endif  
  27. #endif  
  28.   
  29.   
  30. int main(int argc, char* argv[])  
  31. {  
  32.     AVFormatContext* pFormatCtx;  
  33.     AVOutputFormat* fmt;  
  34.     AVStream* video_st;  
  35.     AVCodecContext* pCodecCtx;  
  36.     AVCodec* pCodec;  
  37.   
  38.     uint8_t* picture_buf;  
  39.     AVFrame* picture;  
  40.     AVPacket pkt;  
  41.     int y_size;  
  42.     int got_picture=0;  
  43.     int size;  
  44.   
  45.     int ret=0;  
  46.   
  47.     FILE *in_file = NULL;                            //YUV source  
  48.     int in_w=480,in_h=272;                           //YUV's width and height  
  49.     const char* out_file = "cuc_view_encode.jpg";    //Output file  
  50.   
  51.     in_file = fopen("cuc_view_480x272.yuv""rb");  
  52.   
  53.     av_register_all();  
  54.   
  55.     //Method 1  
  56.     pFormatCtx = avformat_alloc_context();  
  57.     //Guess format  
  58.     fmt = av_guess_format("mjpeg", NULL, NULL);  
  59.     pFormatCtx->oformat = fmt;  
  60.     //Output URL  
  61.     if (avio_open(&pFormatCtx->pb,out_file, AVIO_FLAG_READ_WRITE) < 0){  
  62.         printf("Couldn't open output file.");  
  63.         return -1;  
  64.     }  
  65.   
  66.     //Method 2. More simple  
  67.     //avformat_alloc_output_context2(&pFormatCtx, NULL, NULL, out_file);  
  68.     //fmt = pFormatCtx->oformat;  
  69.   
  70.     video_st = avformat_new_stream(pFormatCtx, 0);  
  71.     if (video_st==NULL){  
  72.         return -1;  
  73.     }  
  74.     pCodecCtx = video_st->codec;  
  75.     pCodecCtx->codec_id = fmt->video_codec;  
  76.     pCodecCtx->codec_type = AVMEDIA_TYPE_VIDEO;  
  77.     pCodecCtx->pix_fmt = AV_PIX_FMT_YUVJ420P;  
  78.   
  79.     pCodecCtx->width = in_w;    
  80.     pCodecCtx->height = in_h;  
  81.   
  82.     pCodecCtx->time_base.num = 1;    
  83.     pCodecCtx->time_base.den = 25;     
  84.     //Output some information  
  85.     av_dump_format(pFormatCtx, 0, out_file, 1);  
  86.   
  87.     pCodec = avcodec_find_encoder(pCodecCtx->codec_id);  
  88.     if (!pCodec){  
  89.         printf("Codec not found.");  
  90.         return -1;  
  91.     }  
  92.     if (avcodec_open2(pCodecCtx, pCodec,NULL) < 0){  
  93.         printf("Could not open codec.");  
  94.         return -1;  
  95.     }  
  96.     picture = av_frame_alloc();  
  97.     size = avpicture_get_size(pCodecCtx->pix_fmt, pCodecCtx->width, pCodecCtx->height);  
  98.     picture_buf = (uint8_t *)av_malloc(size);  
  99.     if (!picture_buf)  
  100.     {  
  101.         return -1;  
  102.     }  
  103.     avpicture_fill((AVPicture *)picture, picture_buf, pCodecCtx->pix_fmt, pCodecCtx->width, pCodecCtx->height);  
  104.   
  105.     //Write Header  
  106.     avformat_write_header(pFormatCtx,NULL);  
  107.   
  108.     y_size = pCodecCtx->width * pCodecCtx->height;  
  109.     av_new_packet(&pkt,y_size*3);  
  110.     //Read YUV  
  111.     if (fread(picture_buf, 1, y_size*3/2, in_file) <=0)  
  112.     {  
  113.         printf("Could not read input file.");  
  114.         return -1;  
  115.     }  
  116.     picture->data[0] = picture_buf;              // Y  
  117.     picture->data[1] = picture_buf+ y_size;      // U   
  118.     picture->data[2] = picture_buf+ y_size*5/4;  // V  
  119.   
  120.     //Encode  
  121.     ret = avcodec_encode_video2(pCodecCtx, &pkt,picture, &got_picture);  
  122.     if(ret < 0){  
  123.         printf("Encode Error.\n");  
  124.         return -1;  
  125.     }  
  126.     if (got_picture==1){  
  127.         pkt.stream_index = video_st->index;  
  128.         ret = av_write_frame(pFormatCtx, &pkt);  
  129.     }  
  130.   
  131.     av_free_packet(&pkt);  
  132.     //Write Trailer  
  133.     av_write_trailer(pFormatCtx);  
  134.   
  135.     printf("Encode Successful.\n");  
  136.   
  137.     if (video_st){  
  138.         avcodec_close(video_st->codec);  
  139.         av_free(picture);  
  140.         av_free(picture_buf);  
  141.     }  
  142.     avio_close(pFormatCtx->pb);  
  143.     avformat_free_context(pFormatCtx);  
  144.   
  145.     fclose(in_file);  
  146.   
  147.     return 0;  
  148. }  

雷霄骅 (Lei Xiaohua)
[email protected]
http://blog.csdn.net/leixiaohua1020


版权声明:本文为博主原创文章,未经博主允许不得转载。

你可能感兴趣的:(YUV420P像素数据编码为JPEG图片)