欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

YUV420P像素数据编码为JPEG图片

程序员文章站 2022-06-24 16:35:51
本文的编码器实现了YUV420P的数据编码为JPEG图片。本着简单的原则,代码基本上精简到了极限。使用了2014年5月6号编译的最新的FFMPEG类库。程序很简单,打开工程后直接运行即可将YUV数据编码为JPEG。本程序十分灵活,可以根据需要修改成编码各种图像格式的编码器,比如PNG,GIF等等。平台使用VC2010。*本程序实现了YUV420P像素数据编码为JPEG图...

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

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

  1.  * 本程序实现了YUV420P像素数据编码为JPEG图片。是最简单的FFmpeg编码方面的教程。 
  2.  * 通过学习本例子可以了解FFmpeg的编码流程。 
  3.  */  
  4.   
  5. #include <stdio.h>  
  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 <libavcodec/avcodec.h>  
  23. #include <libavformat/avformat.h>  
  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)
leixiaohua1020@126.com
http://blog.csdn.net/leixiaohua1020


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

本文地址:https://blog.csdn.net/ZH952016281/article/details/52768216