最简单的基于FFMPEG的图像编码器(YUV编码为JPEG)

43 篇文章 0 订阅

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

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

源代码

 

 
  1. /**

  2. * 最简单的基于FFmpeg的图像编码器

  3. * Simplest FFmpeg Picture Encoder

  4. *

  5. * 雷霄骅 Lei Xiaohua

  6. * leixiaohua1020@126.com

  7. * 中国传媒大学/数字电视技术

  8. * Communication University of China / Digital TV Technology

  9. * http://blog.csdn.net/leixiaohua1020

  10. *

  11. * 本程序实现了YUV420P像素数据编码为JPEG图片。是最简单的FFmpeg编码方面的教程。

  12. * 通过学习本例子可以了解FFmpeg的编码流程。

 
  1. gcc simplest_ffmpeg_picture_encoder.cpp -g -o simplest_ffmpeg_picture_encoder.out -I /usr/local/include -L /usr/local/lib -lavformat -lavcodec -lavutil

  2.  
  1. */

  2.  
  3. #include <stdio.h>

  4.  
  5. #define __STDC_CONSTANT_MACROS

  6.  
  7. #ifdef _WIN32

  8. //Windows

  9. extern "C"

  10. {

  11. #include "libavcodec/avcodec.h"

  12. #include "libavformat/avformat.h"

  13. };

  14. #else

  15. //Linux...

  16. #ifdef __cplusplus

  17. extern "C"

  18. {

  19. #endif

  20. #include <libavcodec/avcodec.h>

  21. #include <libavformat/avformat.h>

  22. #ifdef __cplusplus

  23. };

  24. #endif

  25. #endif

  26.  
  27.  
  28. int main(int argc, char* argv[])

  29. {

  30. AVFormatContext* pFormatCtx;

  31. AVOutputFormat* fmt;

  32. AVStream* video_st;

  33. AVCodecContext* pCodecCtx;

  34. AVCodec* pCodec;

  35.  
  36. uint8_t* picture_buf;

  37. AVFrame* picture;

  38. AVPacket pkt;

  39. int y_size;

  40. int got_picture=0;

  41. int size;

  42.  
  43. int ret=0;

  44.  
  45. FILE *in_file = NULL; //YUV source

  46. int in_w=480,in_h=272; //YUV's width and height

  47. const char* out_file = "cuc_view_encode.jpg"; //Output file

  48.  
  49. in_file = fopen("cuc_view_480x272.yuv", "rb");

  50.  
  51. av_register_all();

  52.  
  53. //Method 1

  54. pFormatCtx = avformat_alloc_context();

  55. //Guess format

  56. fmt = av_guess_format("mjpeg", NULL, NULL);

  57. pFormatCtx->oformat = fmt;

  58. //Output URL

  59. if (avio_open(&pFormatCtx->pb,out_file, AVIO_FLAG_READ_WRITE) < 0){

  60. printf("Couldn't open output file.");

  61. return -1;

  62. }

  63.  
  64. //Method 2. More simple

  65. //avformat_alloc_output_context2(&pFormatCtx, NULL, NULL, out_file);

  66. //fmt = pFormatCtx->oformat;

  67.  
  68. video_st = avformat_new_stream(pFormatCtx, 0);

  69. if (video_st==NULL){

  70. return -1;

  71. }

  72. pCodecCtx = video_st->codec;

  73. pCodecCtx->codec_id = fmt->video_codec;

  74. pCodecCtx->codec_type = AVMEDIA_TYPE_VIDEO;

  75. pCodecCtx->pix_fmt = AV_PIX_FMT_YUVJ420P;

  76.  
  77. pCodecCtx->width = in_w;

  78. pCodecCtx->height = in_h;

  79.  
  80. pCodecCtx->time_base.num = 1;

  81. pCodecCtx->time_base.den = 25;

  82. //Output some information

  83. av_dump_format(pFormatCtx, 0, out_file, 1);

  84.  
  85. pCodec = avcodec_find_encoder(pCodecCtx->codec_id);

  86. if (!pCodec){

  87. printf("Codec not found.");

  88. return -1;

  89. }

  90. if (avcodec_open2(pCodecCtx, pCodec,NULL) < 0){

  91. printf("Could not open codec.");

  92. return -1;

  93. }

  94. picture = av_frame_alloc();

  95. size = avpicture_get_size(pCodecCtx->pix_fmt, pCodecCtx->width, pCodecCtx->height);

  96. picture_buf = (uint8_t *)av_malloc(size);

  97. if (!picture_buf)

  98. {

  99. return -1;

  100. }

  101. avpicture_fill((AVPicture *)picture, picture_buf, pCodecCtx->pix_fmt, pCodecCtx->width, pCodecCtx->height);

  102.  
  103. //Write Header

  104. avformat_write_header(pFormatCtx,NULL);

  105.  
  106. y_size = pCodecCtx->width * pCodecCtx->height;

  107. av_new_packet(&pkt,y_size*3);

  108. //Read YUV

  109. if (fread(picture_buf, 1, y_size*3/2, in_file) <=0)

  110. {

  111. printf("Could not read input file.");

  112. return -1;

  113. }

  114. picture->data[0] = picture_buf; // Y

  115. picture->data[1] = picture_buf+ y_size; // U

  116. picture->data[2] = picture_buf+ y_size*5/4; // V

  117.  
  118. //Encode

  119. ret = avcodec_encode_video2(pCodecCtx, &pkt,picture, &got_picture);

  120. if(ret < 0){

  121. printf("Encode Error.\n");

  122. return -1;

  123. }

  124. if (got_picture==1){

  125. pkt.stream_index = video_st->index;

  126. ret = av_write_frame(pFormatCtx, &pkt);

  127. }

  128.  
  129. av_free_packet(&pkt);

  130. //Write Trailer

  131. av_write_trailer(pFormatCtx);

  132.  
  133. printf("Encode Successful.\n");

  134.  
  135. if (video_st){

  136. avcodec_close(video_st->codec);

  137. av_free(picture);

  138. av_free(picture_buf);

  139. }

  140. avio_close(pFormatCtx->pb);

  141. avformat_free_context(pFormatCtx);

  142.  
  143. fclose(in_file);

  144.  
  145. return 0;

  146. }

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值