码迷,mamicode.com
首页 > 其他好文 > 详细

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

时间:2015-06-09 19:19:50      阅读:283      评论:0      收藏:0      [点我收藏+]

标签:

模块:

    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);  

 

 

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位或者更 高的操作系统中所使用的类型.

 

 

 

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

标签:

原文地址:http://www.cnblogs.com/zxqstrong/p/4564169.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!