伴随着毕业论文的完成,这两天终于腾出了空闲,又有时间搞搞FFMPEG的研究了。想着之前一直搞的都是FFMPEG解码方面的工作,很少涉及到FFMPEG编码方面的东西,于是打算研究一下FFMPEG的编码。在网上看了一些例子,发现要不然是难度略微有些大,要不然就是类库比较陈旧,于是就决定自己做一个编码方面的例子,方便以后学习。

简介

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

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

源代码

/*** 最简单的基于FFmpeg的图像编码器* Simplest FFmpeg Picture Encoder* * 雷霄骅 Lei Xiaohua* leixiaohua1020@126.com* 中国传媒大学/数字电视技术* Communication University of China / Digital TV Technology* http://blog.csdn.net/leixiaohua1020* * 本程序实现了YUV420P像素数据编码为JPEG图片。是最简单的FFmpeg编码方面的教程。* 通过学习本例子可以了解FFmpeg的编码流程。*/#include <stdio.h>#define __STDC_CONSTANT_MACROS#ifdef _WIN32
//Windows
extern "C"
{
#include "libavcodec/avcodec.h"
#include "libavformat/avformat.h"
};
#else
//Linux...
#ifdef __cplusplus
extern "C"
{
#endif
#include <libavcodec/avcodec.h>
#include <libavformat/avformat.h>
#ifdef __cplusplus
};
#endif
#endifint main(int argc, char* argv[])
{AVFormatContext* pFormatCtx;AVOutputFormat* fmt;AVStream* video_st;AVCodecContext* pCodecCtx;AVCodec* pCodec;uint8_t* picture_buf;AVFrame* picture;AVPacket pkt;int y_size;int got_picture=0;int size;int ret=0;FILE *in_file = NULL;                            //YUV sourceint in_w=480,in_h=272;                           //YUV's width and heightconst char* out_file = "cuc_view_encode.jpg";    //Output filein_file = fopen("cuc_view_480x272.yuv", "rb");av_register_all();//Method 1pFormatCtx = avformat_alloc_context();//Guess formatfmt = av_guess_format("mjpeg", NULL, NULL);pFormatCtx->oformat = fmt;//Output URLif (avio_open(&pFormatCtx->pb,out_file, AVIO_FLAG_READ_WRITE) < 0){printf("Couldn't open output file.");return -1;}//Method 2. More simple//avformat_alloc_output_context2(&pFormatCtx, NULL, NULL, out_file);//fmt = pFormatCtx->oformat;video_st = avformat_new_stream(pFormatCtx, 0);if (video_st==NULL){return -1;}pCodecCtx = video_st->codec;pCodecCtx->codec_id = fmt->video_codec;pCodecCtx->codec_type = AVMEDIA_TYPE_VIDEO;pCodecCtx->pix_fmt = AV_PIX_FMT_YUVJ420P;pCodecCtx->width = in_w;  pCodecCtx->height = in_h;pCodecCtx->time_base.num = 1;  pCodecCtx->time_base.den = 25;   //Output some informationav_dump_format(pFormatCtx, 0, out_file, 1);pCodec = avcodec_find_encoder(pCodecCtx->codec_id);if (!pCodec){printf("Codec not found.");return -1;}if (avcodec_open2(pCodecCtx, pCodec,NULL) < 0){printf("Could not open codec.");return -1;}picture = av_frame_alloc();size = avpicture_get_size(pCodecCtx->pix_fmt, pCodecCtx->width, pCodecCtx->height);picture_buf = (uint8_t *)av_malloc(size);if (!picture_buf){return -1;}avpicture_fill((AVPicture *)picture, picture_buf, pCodecCtx->pix_fmt, pCodecCtx->width, pCodecCtx->height);//Write Headeravformat_write_header(pFormatCtx,NULL);y_size = pCodecCtx->width * pCodecCtx->height;av_new_packet(&pkt,y_size*3);//Read YUVif (fread(picture_buf, 1, y_size*3/2, in_file) <=0){printf("Could not read input file.");return -1;}picture->data[0] = picture_buf;              // Ypicture->data[1] = picture_buf+ y_size;      // U picture->data[2] = picture_buf+ y_size*5/4;  // V//Encoderet = avcodec_encode_video2(pCodecCtx, &pkt,picture, &got_picture);if(ret < 0){printf("Encode Error.\n");return -1;}if (got_picture==1){pkt.stream_index = video_st->index;ret = av_write_frame(pFormatCtx, &pkt);}av_free_packet(&pkt);//Write Trailerav_write_trailer(pFormatCtx);printf("Encode Successful.\n");if (video_st){avcodec_close(video_st->codec);av_free(picture);av_free(picture_buf);}avio_close(pFormatCtx->pb);avformat_free_context(pFormatCtx);fclose(in_file);return 0;
}

结果

编码前的YUV420P数据:

编码后的JPEG:

下载

simplest ffmpeg picture encoder

项目主页

SourceForge:https://sourceforge.net/projects/simplestffmpegpictureencoder/

Github:https://github.com/leixiaohua1020/simplest_ffmpeg_picture_encoder

开源中国:http://git.oschina.net/leixiaohua1020/simplest_ffmpeg_picture_encoder

CSDN工程下载地址:

http://download.csdn.net/detail/leixiaohua1020/7319265

PUDN工程下载地址:

http://www.pudn.com/downloads644/sourcecode/multimedia/detail2605252.html

本程序实现了YUV420P像素数据编码为JPEG图片。是最简单的FFmpeg编码方面的教程。通过学习本例子可以了解FFmpeg的编码流程。

更新-1.1(2015.2.13)=========================================

这次考虑到了跨平台的要求,调整了源代码。经过这次调整之后,源代码可以在以下平台编译通过:

VC++:打开sln文件即可编译,无需配置。

cl.exe:打开compile_cl.bat即可命令行下使用cl.exe进行编译,注意可能需要按照VC的安装路径调整脚本里面的参数。编译命令如下。

::VS2010 Environment
call "D:\Program Files\Microsoft Visual Studio 10.0\VC\vcvarsall.bat"
::include
@set INCLUDE=include;%INCLUDE%
::lib
@set LIB=lib;%LIB%
::compile and link
cl simplest_ffmpeg_picture_encoder.cpp /link avcodec.lib avformat.lib avutil.lib ^
avdevice.lib avfilter.lib postproc.lib swresample.lib swscale.lib /OPT:NOREF

MinGW:MinGW命令行下运行compile_mingw.sh即可使用MinGW的g++进行编译。编译命令如下。

g++ simplest_ffmpeg_picture_encoder.cpp -g -o simplest_ffmpeg_picture_encoder.exe \
-I /usr/local/include -L /usr/local/lib \
-lavformat -lavcodec -lavutil

GCC:Linux或者MacOS命令行下运行compile_gcc.sh即可使用GCC进行编译。编译命令如下。

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

PS:相关的编译命令已经保存到了工程文件夹中

CSDN下载地址:http://download.csdn.net/detail/leixiaohua1020/8444893

SourceForge上已经更新。

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

  1. 最简单的基于FFMPEG的视频编码器(YUV编码为H.264)

    ===================================================== 最简单的基于FFmpeg的视频编码器文章列表: 最简单的基于FFMPEG的视频编码器(YUV ...

  2. 最简单的基于FFMPEG的音频编码器(PCM编码为AAC)

    本文介绍一个最简单的基于FFMPEG的音频编码器.该编码器实现了PCM音频采样数据编码为AAC的压缩编码数据.编码器代码十分简单,但是每一行代码都很重要.通过看本编码器的源代码,可以了解FFMPEG音 ...

  3. 最简单的基于FFmpeg的编码器-纯净版(不包含libavformat)

    ===================================================== 最简单的基于FFmpeg的视频编码器文章列表: 最简单的基于FFMPEG的视频编码器(YUV ...

  4. 最简单的基于FFMPEG的转码程序

    本文介绍一个简单的基于FFmpeg的转码器.它可以将一种视频格式(包括封转格式和编码格式)转换为另一种视频格式.转码器在视音频编解码处理的程序中,属于一个比较复杂的东西.因为它结合了视频的解码和编码. ...

  5. 最简单的基于FFmpeg的内存读写的例子:内存转码器

    ===================================================== 最简单的基于FFmpeg的内存读写的例子系列文章列表: 最简单的基于FFmpeg的内存读写的 ...

  6. 最简单的基于FFmpeg的内存读写的例子:内存播放器

    ===================================================== 最简单的基于FFmpeg的内存读写的例子系列文章列表: 最简单的基于FFmpeg的内存读写的 ...

  7. 最简单的基于FFmpeg的AVDevice例子(读取摄像头)

    ===================================================== 最简单的基于FFmpeg的AVDevice例子文章列表: 最简单的基于FFmpeg的AVDe ...

  8. 最简单的基于FFmpeg的libswscale的示例附件:测试图片生成工具

    ===================================================== 最简单的基于FFmpeg的libswscale的示例系列文章列表: 最简单的基于FFmpeg ...

  9. 最简单的基于FFmpeg的libswscale的示例(YUV转RGB)

    ===================================================== 最简单的基于FFmpeg的libswscale的示例系列文章列表: 最简单的基于FFmpeg ...

最新文章

  1. Ajax Toolkit日历控件CalendarExtender求教!
  2. 计算机网络——链路层之停止等待协议
  3. codeforces 869C The Intriguing Obsession 组合数学,逆元
  4. python装饰器理解_如何理解Python装饰器?
  5. 解决LInux更新慢的问题, 更换国内软件源
  6. Redis内存缓存系统入门
  7. Delegate示例
  8. Redis-01-NoSQL简介及Redis数据库安装
  9. 文安三中电子计算机老师叫什么,顶岗实习周记:记我的第一次.doc
  10. 实验一 9V稳压电源电路实验
  11. 查看DDR的频率【学习笔记】
  12. 简单的魔方复原方法, 魔方还原公式,图解
  13. php 连接数据库有很多notice,PHP Notice: undefined index 完美解决方法
  14. 【Mediator模式】C++设计模式——中介者模式
  15. SO-Net:点云分析的自组织网络
  16. 练习题 William's Colored Pencils
  17. 股票投资 - 股票的安全边际
  18. 软件测试计划书项目背景,软件测试项目计划书.doc
  19. 解决DBConCurrencyException并发冲突异常(收藏)
  20. HTML5期末大作业:计算机社团设计--可随意更改名称,各个社团协会

热门文章

  1. MySQL 优化之 EXPLAIN 关键字
  2. 计算机科学 —— 冯诺依曼结构
  3. 计算机的组成 —— 磁盘阵列(RAID)
  4. 数据结构(C++)—— 向量(Vector)
  5. Git 基础(八)—— 分支管理
  6. Python 进阶 —— defaultdict
  7. 创建对称矩阵(numpy)
  8. 济南大学转专业计算机面试难吗,我校2016-2017学年学生转专业工作结束
  9. 前端集合删除对象_【两万字】面试官:听说你精通集合源码,接我二十个问题!...
  10. python菱形_python如何输出菱形与空心菱形详解与巧妙地使用center方法