原帖地址:http://blog.csdn.net/austinblog/article/details/24800381

首先先看ffmpeg.c文件,有类似于如下的一些变量:

InputStream **input_streams = NULL;
int        nb_input_streams = ;
InputFile   **input_files   = NULL;
int        nb_input_files   = ; OutputStream **output_streams = NULL;
int         nb_output_streams = ;
OutputFile   **output_files   = NULL;
int         nb_output_files   = ;

其中: input_streams是输入流的数组,nb_input_streams是输入流的个数。 input_files是输入文件(也可能是设备)的数组,nb_input_files是输入文件的个数。 下面的输出相关的变量们就不用解释了。

可以看出,文件和流是分别保存的。于是,可以想象,结构InputStream中应有其所属的文件在InputFile中的序号(file_index)。输入流数组应是这样填充的:每当在输入文件中找到一个流时,就把它添加到input_streams中,所以一个输入文件对应的输入流在input_streams中是紧靠着的,于是InputFile结构中应有其第一个流在input_streams中的开始序号(ist_index)和被放在input_streams中的流的总个数(nb_streams)。

InputStream和InputFile结构体如下:

typedef struct InputStream {
int file_index;
AVStream *st;
int discard; /* true if stream data should be discarded */
int decoding_needed; /* true if the packets must be decoded in 'raw_fifo' */
AVCodec *dec;
AVFrame *decoded_frame;
AVFrame *filter_frame; /* a ref of decoded_frame, to be sent to filters */ int64_t start; /* time when read started */
/* predicted dts of the next packet read for this stream or (when there are
* several frames in a packet) of the next frame in current packet (in AV_TIME_BASE units) */
int64_t next_dts;
int64_t dts; ///< dts of the last packet read for this stream (in AV_TIME_BASE units) int64_t next_pts; ///< synthetic pts for the next decode frame (in AV_TIME_BASE units)
int64_t pts; ///< current pts of the decoded frame (in AV_TIME_BASE units)
int wrap_correction_done; int64_t filter_in_rescale_delta_last; double ts_scale;
int saw_first_ts;
int showed_multi_packet_warning;
AVDictionary *opts;
AVRational framerate; /* framerate forced with -r */
int top_field_first;
int guess_layout_max; int resample_height;
int resample_width;
int resample_pix_fmt; int resample_sample_fmt;
int resample_sample_rate;
int resample_channels;
uint64_t resample_channel_layout; int fix_sub_duration;
struct { /* previous decoded subtitle and related variables */
int got_output;
int ret;
AVSubtitle subtitle;
} prev_sub; struct sub2video {
int64_t last_pts;
int64_t end_pts;
AVFrame *frame;
int w, h;
} sub2video; int dr1; /* decoded data from this stream goes into all those filters
* currently video and audio only */
InputFilter **filters;
int nb_filters; int reinit_filters; /* hwaccel options */
enum HWAccelID hwaccel_id;
char *hwaccel_device; /* hwaccel context */
enum HWAccelID active_hwaccel_id;
void *hwaccel_ctx;
void (*hwaccel_uninit)(AVCodecContext *s);
int (*hwaccel_get_buffer)(AVCodecContext *s, AVFrame *frame, int flags);
int (*hwaccel_retrieve_data)(AVCodecContext *s, AVFrame *frame);
enum AVPixelFormat hwaccel_pix_fmt;
enum AVPixelFormat hwaccel_retrieved_pix_fmt;
} InputStream; typedef struct InputFile {
AVFormatContext *ctx;
int eof_reached; /* true if eof reached */
int eagain; /* true if last read attempt returned EAGAIN */
int ist_index; /* index of first stream in input_streams */
int64_t input_ts_offset;
int64_t ts_offset;
int64_t last_ts;
int64_t start_time; /* user-specified start time in AV_TIME_BASE or AV_NOPTS_VALUE */
int64_t recording_time;
int nb_streams; /* number of stream that ffmpeg is aware of; may be different
from ctx.nb_streams if new streams appear during av_read_frame() */
int nb_streams_warn; /* number of streams that the user was warned of */
int rate_emu;
int accurate_seek; int shared_encoding;
#if HAVE_PTHREADS
pthread_t thread; /* thread reading from this file */
int non_blocking; /* reading packets from the thread should not block */
int finished; /* the thread has exited */
int joined; /* the thread has been joined */
pthread_mutex_t fifo_lock; /* lock for access to fifo */
pthread_cond_t fifo_cond; /* the main thread will signal on this cond after reading from fifo */
AVFifoBuffer *fifo; /* demuxed packets are stored here; freed by the main thread */
#endif
} InputFile;

在输出流output_streams中,除了要保存其所在的输出文件在output_files中的序号(index),还应保存其对应的输入流在input_streams中的序号( source_index),也应保存其在所属输出文件中的流序号(file_index)。而输出文件中呢,只需保存它的第一个流在output_streams中的序号(ost_index),但是为啥不保存输出文件中流的个数呢?我也不道,但我知道肯定不用保存也不影响实现功能(嘿嘿,相当于没说).

OutputStream和OutputFile结构体如下:

typedef struct OutputStream {
int file_index; /* file index */
int index; /* stream index in the output file */
int source_index; /* InputStream index */
AVStream *st; /* stream in the output file */
int encoding_needed; /* true if encoding needed for this stream */
int frame_number;
int encoded_frame_number;
/* input pts and corresponding output pts
for A/V sync */
struct InputStream *sync_ist; /* input stream to sync against */
int64_t sync_opts; /* output frame counter, could be changed to some true timestamp */ // FIXME look at frame_number
/* pts of the first frame encoded for this stream, used for limiting
* recording time */
int64_t first_pts;
/* dts of the last packet sent to the muxer */
int64_t last_mux_dts;
AVBitStreamFilterContext *bitstream_filters;
AVCodec *enc;
int64_t max_frames;
AVFrame *filtered_frame; /* video only */
AVRational frame_rate;
int force_fps;
int top_field_first; AVRational frame_aspect_ratio; /* forced key frames */
int64_t *forced_kf_pts;
int forced_kf_count;
int forced_kf_index;
char *forced_keyframes;
AVExpr *forced_keyframes_pexpr;
double forced_keyframes_expr_const_values[FKF_NB]; /* audio only */
int audio_channels_map[SWR_CH_MAX]; /* list of the channels id to pick from the source stream */
int audio_channels_mapped; /* number of channels in audio_channels_map */ char *logfile_prefix;
FILE *logfile; OutputFilter *filter;
char *avfilter;
char *filters; ///< filtergraph associated to the -filter option
char *filters_script; ///< filtergraph script associated to the -filter_script option int64_t sws_flags;
AVDictionary *opts;
AVDictionary *swr_opts;
AVDictionary *resample_opts;
char *apad;
OSTFinished finished; /* no more packets should be written for this stream */
int unavailable; /* true if the steram is unavailable (possibly temporarily) */
int stream_copy;
const char *attachment_filename;
int copy_initial_nonkeyframes;
int copy_prior_start; int keep_pix_fmt; AVCodecParserContext *parser;
} OutputStream; typedef struct OutputFile {
AVFormatContext *ctx;
AVDictionary *opts;
int ost_index; /* index of the first stream in output_streams */
int64_t recording_time; ///< desired length of the resulting file in microseconds == AV_TIME_BASE units
int64_t start_time; ///< start time in microseconds == AV_TIME_BASE units
uint64_t limit_filesize; /* filesize limit expressed in bytes */ int shortest;
} OutputFile;

流和文件都准备好了,下面就是转换,那么转换过程是怎样的呢?还是我来猜一猜吧:
首先打开输入文件们,然后跟据输入流们准备并打开解码器们,然后跟据输出流们准备并打开编码器们,然后创建输出文件们,然后为所有输出文件们写好头部,然后就在循环中把输入流转换到输出流并写入输出文件中,转换完后跳出循环,然后写入文件尾,最后关闭所有的输出文件.

概述就先到这里吧,后面会对几个重要函数做详细分析。

ffmpeg源码分析一:概述 (转1)的更多相关文章

  1. 最新版ffmpeg源码分析

    最新版ffmpeg源码分析一:框架 (ffmpeg v0.9) 框架 最新版的ffmpeg中发现了一个新的东西:avconv,而且ffmpeg.c与avconv.c一个模样,一研究才发现是libav下 ...

  2. Netty源码分析(前言, 概述及目录)

    Netty源码分析(完整版) 前言 前段时间公司准备改造redis的客户端, 原生的客户端是阻塞式链接, 并且链接池初始化的链接数并不高, 高并发场景会有获取不到连接的尴尬, 所以考虑了用netty长 ...

  3. Kafka源码分析(一) - 概述

    系列文章目录 https://zhuanlan.zhihu.com/p/367683572 目录 系列文章目录 一. 实际问题 二. 什么是Kafka, 如何解决这些问题的 三. 基本原理 1. 基本 ...

  4. ffmpeg 源码分析

    http://blog.csdn.net/liuhongxiangm/article/details/8824761 https://code.google.com/p/ffmpegsource/is ...

  5. ffmpeg源码分析五:ffmpeg调用x264编码器的过程分析 (转5)

    原帖地址:http://blog.csdn.net/austinblog/article/details/25127533 该文将以X264编码器为例,解释说明FFMPEG是怎么调用第三方编码器来进行 ...

  6. ffmpeg源码分析三:transcode_init函数 (转3)

    原帖地址:http://blog.csdn.net/austinblog/article/details/25061945 transcode_init()函数是在转换前做准备工作的.下面看看其源代码 ...

  7. ffmpeg源码分析二:main函数和transcode函数 (转2)

    原帖地址:http://blog.csdn.net/austinblog/article/details/24804455 首先从main函数看起,关键解释部分已加注释,该函数在ffmpeg.c文件中 ...

  8. HDFS源码分析一-概述

    HDFS 主要包含 NameNode, SecondaryNameNode, DataNode 以及 HDFS Client . 我们从以下这几部分讲: 1. HDFS概述 2. NameNode 实 ...

  9. ffmpeg源码分析之媒体打开过程

    int avformat_open_input(AVFormatContext **ps,           const char *filename,           AVInputForma ...

随机推荐

  1. Struts标签库详解,非常好的Struts标签详解

    Struts提供了五个标签库,即:HTML.Bean.Logic.Template和Nested. HTML 标签:         用来创建能够和Struts 框架和其他相应的HTML 标签交互的H ...

  2. 《DSP using MATLAB》示例Example 8.7

    %% ------------------------------------------------------------------------ %% Output Info about thi ...

  3. python selenium 开发环境配置

    selenium是一个web测试应用框架也可以拿来做爬虫. 1.安装selenium模块 pip install -U selenium 2.安装selenium模块后需要有相应的浏览器驱动 A.使用 ...

  4. 基于模k可逆计数的数字锁相环fpga实现

    参考http://wenku.baidu.com/view/59420cb069dc5022aaea00bd.html 实现结构是参考的上边的实例,我用的全同步实现,实现过程中发现一些现象,做下记录. ...

  5. 关于在2.7中出现 "UnicodeWarning: Unicode equal comparison failed to convert both arguments to Unicode - interpreting them as being unequal"

    在中文字符串前面加u. Make sure your code is in UTF-8 (NOT Latin-1) and/or use a coding line as so: #! /usr/bi ...

  6. VMware harbor && minio 搭建企业docker私有镜像以及需要注意的问题

    1. docker harbor  配置      建议使用在线安装的模式(离线包太大了)    首先需要安装docker-compose .docker .mino (具体安装可以参考官网后者我的博 ...

  7. Docker-Compose API too old for Windows

    I was working on some code with a Docker Windows container today and ran into this error message: ER ...

  8. selectToUISlider

    版权声明:本文为LZUGIS原创文章,未经同意不得转载. https://blog.csdn.net/GISShiXiSheng/article/details/24304321 用过google e ...

  9. new/delete和malloc/free区别

    相同点: 都可用于申请动态内存和释放内存 不同点: 操作对象有所不同. 本质区别: malloc与free是C++/C 语言的标准库函数,new/delete 是C++的运算符,对象在创建的同时要自动 ...

  10. C#开机启动与退出程序

    最新用到的项目中需要使用开机自启和退出程序,于是需要 http://www.cnblogs.com/Gaoswatou/p/6605760.html C# WinForm程序退出的方法 1.this. ...