最简单的基于FFMPEG的转码程序 [转] —— 分析

模块:

    libavcodec    - 编码解码器
       
libavdevice   - 输入输出设备的支持
       
libavfilter   - 视音频滤镜支持
       
libavformat   - 视音频等格式的解析
       
libavutil    
- 工具库
       
libpostproc   - 后期效果处理
       
libswscale    -
图像颜色、尺寸转换

1. 主函数分析:

  1. int_tmain(int argc, _TCHAR* argv[])
  2. {
  3. int ret;
  4. AVPacketpacket;
  5. AVFrame *frame= NULL;
  6. enum AVMediaType type;
  7. unsigned intstream_index;
  8. unsigned int i;
  9. int got_frame;
  10. int (*dec_func)(AVCodecContext *, AVFrame *, int *, const AVPacket*);
  11. if (argc != 3) {
  12. av_log(NULL, AV_LOG_ERROR, "Usage: %s<input file> <output file>\n", argv[0]);
  13. return 1;
  14. }
  15. av_register_all();
  16. avfilter_register_all();
  17. if ((ret = open_input_file(argv[1])) < 0)
  18. goto end;
  19. if ((ret = open_output_file(argv[2])) < 0)
  20. goto end;
  21. if ((ret = init_filters()) < 0)
  22. goto end;
  23. /* read all packets */
  24. while (1) {
  25. if ((ret= av_read_frame(ifmt_ctx, &packet)) < 0)
  26. break;
  27. stream_index = packet.stream_index;
  28. type =ifmt_ctx->streams[packet.stream_index]->codec->codec_type;
  29. av_log(NULL, AV_LOG_DEBUG, "Demuxergave frame of stream_index %u\n",
  30. stream_index);
  31. if (filter_ctx[stream_index].filter_graph) {
  32. av_log(NULL, AV_LOG_DEBUG, "Going toreencode&filter the frame\n");
  33. frame =av_frame_alloc();
  34. if (!frame) {
  35. ret = AVERROR(ENOMEM);
  36. break;
  37. }
  38. packet.dts = av_rescale_q_rnd(packet.dts,
  39. ifmt_ctx->streams[stream_index]->time_base,
  40. ifmt_ctx->streams[stream_index]->codec->time_base,
  41. (AVRounding)(AV_ROUND_NEAR_INF|AV_ROUND_PASS_MINMAX));
  42. packet.pts = av_rescale_q_rnd(packet.pts,
  43. ifmt_ctx->streams[stream_index]->time_base,
  44. ifmt_ctx->streams[stream_index]->codec->time_base,
  45. (AVRounding)(AV_ROUND_NEAR_INF|AV_ROUND_PASS_MINMAX));
  46. dec_func = (type == AVMEDIA_TYPE_VIDEO) ? avcodec_decode_video2 :
  47. avcodec_decode_audio4;
  48. ret =dec_func(ifmt_ctx->streams[stream_index]->codec, frame,
  49. &got_frame, &packet);
  50. if (ret < 0) {
  51. av_frame_free(&frame);
  52. av_log(NULL, AV_LOG_ERROR, "Decodingfailed\n");
  53. break;
  54. }
  55. if (got_frame) {
  56. frame->pts = av_frame_get_best_effort_timestamp(frame);
  57. ret= filter_encode_write_frame(frame, stream_index);
  58. av_frame_free(&frame);
  59. if (ret< 0)
  60. goto end;
  61. } else {
  62. av_frame_free(&frame);
  63. }
  64. } else {
  65. /* remux this frame without reencoding */
  66. packet.dts = av_rescale_q_rnd(packet.dts,
  67. ifmt_ctx->streams[stream_index]->time_base,
  68. ofmt_ctx->streams[stream_index]->time_base,
  69. (AVRounding)(AV_ROUND_NEAR_INF|AV_ROUND_PASS_MINMAX));
  70. packet.pts = av_rescale_q_rnd(packet.pts,
  71. ifmt_ctx->streams[stream_index]->time_base,
  72. ofmt_ctx->streams[stream_index]->time_base,
  73. (AVRounding)(AV_ROUND_NEAR_INF|AV_ROUND_PASS_MINMAX));
  74. ret =av_interleaved_write_frame(ofmt_ctx, &packet);
  75. if (ret < 0)
  76. goto end;
  77. }
  78. av_free_packet(&packet);
  79. }
  80. /* flush filters and encoders */
  81. for (i = 0; i < ifmt_ctx->nb_streams; i++) {
  82. /* flush filter */
  83. if (!filter_ctx[i].filter_graph)
  84. continue;
  85. ret =filter_encode_write_frame(NULL, i);
  86. if (ret < 0) {
  87. av_log(NULL, AV_LOG_ERROR, "Flushingfilter failed\n");
  88. goto end;
  89. }
  90. /* flush encoder */
  91. ret = flush_encoder(i);
  92. if (ret < 0) {
  93. av_log(NULL, AV_LOG_ERROR, "Flushingencoder failed\n");
  94. goto end;
  95. }
  96. }
  97. av_write_trailer(ofmt_ctx);
  98. end:
  99. av_free_packet(&packet);
  100. av_frame_free(&frame);
  101. for (i = 0; i < ifmt_ctx->nb_streams; i++) {
  102. avcodec_close(ifmt_ctx->streams[i]->codec);
  103. if (ofmt_ctx && ofmt_ctx->nb_streams >i && ofmt_ctx->streams[i] &&ofmt_ctx->streams[i]->codec)
  104. avcodec_close(ofmt_ctx->streams[i]->codec);
  105. if(filter_ctx && filter_ctx[i].filter_graph)
  106. avfilter_graph_free(&filter_ctx[i].filter_graph);
  107. }
  108. av_free(filter_ctx);
  109. avformat_close_input(&ifmt_ctx);
  110. if (ofmt_ctx &&!(ofmt_ctx->oformat->flags & AVFMT_NOFILE))
  111. avio_close(ofmt_ctx->pb);
  112. avformat_free_context(ofmt_ctx);
  113. if (ret < 0)
  114. av_log(NULL, AV_LOG_ERROR, "Erroroccurred\n");
  115. return (ret? 1:0);
  116. }

1.1 int _tmain(int argc, _TCHAR* argv[])

   用过C的人都知道每一个C的程序都会有一个main(),但有时看别人写的程序发现主函数不是int main(),而是int _tmain(),而且头文件也不是<iostream.h>而是<stdafx.h>,会困惑吧?首先,这个_tmain() 是为了支持unicode所使用的main一个别名而已,既然是别名,应该有宏定义过的,在哪里定义的呢?就在那个让你困惑 的<stdafx.h>里,有这么两行
  #include <stdio.h>
  #include <tchar.h>
我们可以在头文件<tchar.h>里找到_tmain的宏定义
  #define _tmain main
所以,经过预编译以后, _tmain就变成main了

//_TCHAR类型是宽字符型字符串,和我们一般常用的字符串不同,它是32位或者更 高的操作系统中所使用的类型.

时间: 2024-08-03 15:44:42

最简单的基于FFMPEG的转码程序 [转] —— 分析的相关文章

最简单的基于FFMPEG的转码程序 [转]

本文介绍一个简单的基于FFmpeg的转码器.它可以将一种视频格式(包括封转格式和编码格式)转换为另一种视频格式.转码器在视音频编解码处理的 程序中,属于一个比较复杂的东西.因为它结合了视频的解码和编码.一个视频播放器,一般只包含解码功能:一个视频编码工具,一般只包含编码功能:而一个视 频转码器,则需要先对视频进行解码,然后再对视频进行编码,因而相当于解码器和编码器的结合.下图例举了一个视频的转码流程.输入视频的封装格式是 FLV,视频编码标准是H.264,音频编码标准是AAC:输出视频的封装格式

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

本文介绍一个简单的基于FFmpeg的转码器.转码器在视音频编解码处理的程序中,属于一个比较复杂的东西.因为它结合了视频的解码和编码.一个视频播放器,一般只包含解码功能:一个视频编码工具,一般只包含编码功能:而一个视频转码器,则需要先对视频进行解码,然后再对视频进行编码,因而相当于解码器和编码器的结合.下图例举了一个视频的转码流程.输入视频的封装格式是FLV,视频编码标准是H.264,音频编码标准是AAC:输出视频的封装格式是AVI,视频编码标准是MPEG2,音频编码标准是MP3.从流程中可以看出

最简单的基于FFMPEG的转码程序分析 +ffmpga代码简析(转 +总结)

模块:  libavcodec    - 编码解码器         libavdevice   - 输入输出设备的支持         libavfilter   - 视音频滤镜支持         libavformat   - 视音频等格式的解析         libavutil     - 工具库         libpostproc   - 后期效果处理         libswscale    - 图像颜色.尺寸转换 1. ffmpga代码简析 1.1 av_log() av_

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

上篇文章记录了一个基于FFmpeg的内存播放器,可以使用FFmpeg读取并播放内存中的数据.这篇文章记录一个基于FFmpeg的内存转码器.该转码器可以使用FFmpeg读取内存中的数据,转码为H.264之后再将数据输出到内存.关于如何从内存读取数据,以及如何将数据输出到内存,可以参考文章: ffmpeg 从内存中读取数据(或将数据输出到内存) FFmpeg读写内存的关键点有2个:1.       初始化自定义的AVIOContext,指定自定义的回调函数.2.       自己写回调函数.注意函数

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

打算记录两个最简单的FFmpeg进行内存读写的例子.之前的所有有关FFmpeg的例子都是对文件进行操作的.例如<100行代码实现最简单的基于FFMPEG+SDL的视频播放器>播放的是一个视频的文件.而<最简单的基于FFMPEG的转码程序>也是将一个视频文件转换为另一个视频文件.<最简单的基于FFmpeg的视频编码器(YUV编码为H.264)>也是最后编码得到一个H.264视频文件.实际上,并不是所有视频的编码,解码都是针对文件进行处理的.有的时候需要的解码的视频数据在一

(转)最简单的基于FFmpeg的内存读写的例子:内存播放器

ffmpeg内存播放解码 目录(?)[+] ===================================================== 最简单的基于FFmpeg的内存读写的例子系列文章列表: 最简单的基于FFmpeg的内存读写的例子:内存播放器 最简单的基于FFmpeg的内存读写的例子:内存转码器 ===================================================== 打算记录两个最简单的FFmpeg进行内存读写的例子.之前的所有有关FFmpe

最简单的基于FFmpeg的移动端例子:Android 转码器

本文记录一个安卓平台下基于FFmpeg的视频转码器.该转码器实际上移植自ffmpeg工程中的ffmpeg.c源代码.有关ffmpeg.c的源代码可以参考文章<ffmpeg.c函数结构简单分析(画图)>,在这里就不重复记录了. 源代码 项目的目录结构如图所示.Java源代码位于src目录,而C代码位于jni目录. Android程序Java端代码位于src\com\leixiaohua1020\sffmpegandroidtranscoder\MainActivity.java,如下所示. /*

最简单的基于FFmpeg的移动端样例:IOS 视频转码器

===================================================== 最简单的基于FFmpeg的移动端样例系列文章列表: 最简单的基于FFmpeg的移动端样例:Android HelloWorld 最简单的基于FFmpeg的移动端样例:Android 视频解码器 最简单的基于FFmpeg的移动端样例:Android 视频解码器-单个库版 最简单的基于FFmpeg的移动端样例:Android 推流器 最简单的基于FFmpeg的移动端样例:Android 视频转

最简单的基于FFmpeg的移动端例子:IOS 视频转码器

本文记录iOS平台下基于FFmpeg的视频转码器.该转码器实际上移植自ffmpeg工程中的ffmpeg.c源代码.有关ffmpeg.c的源代码可以参考文章<ffmpeg.c函数结构简单分析(画图)>,在这里就不重复记录了. 源代码 项目的目录结构如图所示. 下列C语言文件拷贝自FFmpeg源代码: cmdutils.ccmdutils.hcmdutils_common_opts.hconfig.hffmpeg.hffmpeg_filter.cffmpeg_opt.c 此外在编译ffmpeg.c