Audio and video learning one: under the android platform ffmpeg codec abbreviated - Packaging Solutions

                                                      Decapsulation

1. Common functions:

  • av_register_all (): registration of all components
  • avformat_network_init (): initialize the network environment
  • avformat_open_input (...): Open the input video file
  • avformat_find_stream_info (...): get video file information  
  • av_find_best_stream (...): acquiring audio or video captions stream_index
  • av_read_frame (...): a compressed data read from the input file

2. structure:

  • AVFormatContext : 

https://blog.csdn.net/qq_25333681/article/details/80428852

AVFormatContext the API is in direct contact with the structural body, located in avformat.h is audio and video data, which is an abstraction and encapsulation of audio and video files,

The file contains multiple streams, including audio streaming, video streaming, subtitle streams. Use of the structure, throughout the entire process ffmpeg used.

  • AVStream

https://www.jianshu.com/p/f6e409d62407

Is a structure storing each video / audio stream information, the file is located avformat.h

int index; //在AVFormatContext中的索引,这个数字是自动生成的,可以通过这个数字从AVFormatContext::streams表中索引到该流。
int id;//流的标识,依赖于具体的容器格式。解码:由libavformat设置。编码:由用户设置,如果未设置则由libavformat替换。
AVCodecContext *codec;//指向该流对应的AVCodecContext结构,调用avformat_open_input时生成。
AVRational time_base;//这是表示帧时间戳的基本时间单位(以秒为单位)。该流中媒体数据的pts和dts都将以这个时间基准为粒度。
int64_t start_time;//流的起始时间,以流的时间基准为单位。如需设置,100%确保你设置它的值真的是第一帧的pts。
int64_t duration;//解码:流的持续时间。如果源文件未指定持续时间,但指定了比特率,则将根据比特率和文件大小估计该值。
int64_t nb_frames; //此流中的帧数(如果已知)或0。
enum AVDiscard discard;//选择哪些数据包可以随意丢弃,不需要去demux。
AVRational sample_aspect_ratio;//样本长宽比(如果未知,则为0)。
AVDictionary *metadata;//元数据信息。
AVRational avg_frame_rate;//平均帧速率。解封装:可以在创建流时设置为libavformat,也可以在avformat_find_stream_info()中设置。封装:可以由调用者在avformat_write_header()之前设置。
AVPacket attached_pic;//附带的图片。比如说一些MP3,AAC音频文件附带的专辑封面。
int probe_packets;//编解码器用于probe的包的个数。
int codec_info_nb_frames;//在av_find_stream_info()期间已经解封装的帧数。
int request_probe;//流探测状态,1表示探测完成,0表示没有探测请求,rest 执行探测。
int skip_to_keyframe;//表示应丢弃直到下一个关键帧的所有内容。
int skip_samples;//在从下一个数据包解码的帧开始时要跳过的采样数。
int64_t start_skip_samples;//如果不是0,则应该从流的开始跳过的采样的数目。
int64_t first_discard_sample;//如果不是0,则应该从流中丢弃第一个音频样本。

int64_t pts_reorder_error[MAX_REORDER_DELAY+1];
uint8_t pts_reorder_error_count[MAX_REORDER_DELAY+1];//内部数据,从pts生成dts。

int64_t last_dts_for_order_check;
uint8_t dts_ordered;
uint8_t dts_misordered;//内部数据,用于分析dts和检测故障mpeg流。
AVRational display_aspect_ratio;//显示宽高比。
  • AVPacket  

https://www.jianshu.com/p/bb6d3905907e

AVPacket ffmpeg is very important in a data structure that holds data (the data is still compressed) Knowing the package, before decoding and some additional information about these data, the display time stamp (PTS), Decoding Time Stamp ( dts), data length (duration), the media index (stream_index) where the flow and the like.

The case of video, AVPacket typically comprise a compressed Frame; while the audio is likely to contain more compressed Frame. Further, there is also a packet may be empty, does not comprise any compressed data, the edge data include only side data (additional information packet about the container provided, for example, to update some of the parameters of flow at the end of the encoding).

AVPacket size is common ABI (Public ABI) part, in such a structure is little FFmpeg, which also shows the importance of AVPacket, it can be allocated (AVPacket pkt statement may be used on the stack space; stack space defined a Packet), and unless libavcodec and libavformat changed substantially, or will not add a new field in AVPacket in.

Step 3. decapsulation

① initialization

//ffmpeg 注册所有封装器
av_register_all();
//注册所有的解码器
avcodec_register_all();
//初始化网络
avformat_network_init();

② Open the file avformat_open_input ();

   mux.lock();
    // 打开文件
    int ret = avformat_open_input(&avFormatContext, url, 0, 0);
    if (ret != 0) {
        mux.unlock();
        char buf[1024] = {0};
        //打印失败信息
        av_strerror(ret, buf, sizeof(buf));
        XLOGE("=============>> avformat_open_input failed!");
        return false;
    }

    //读取文件信息
    ret = avformat_find_stream_info(avFormatContext, 0);
    if (ret != 0) {
        mux.unlock();
        char buf[1024] = {0};
        av_strerror(ret, buf, sizeof(buf));
        XLOGE("=============>> avformat_find_stream_info %s failed!", url);
        return false;
    }
    isOPen = true;
    // 文件时长转换单位
    this->totalMs = avFormatContext->duration / (AV_TIME_BASE / 1000);
    mux.unlock();

③ Open thread loop reads the file data by av_read_frame ();

//循环读取文件数据(调用Read()函数,每次读取一帧数据)
void IDemux::Main() {
    while (!isExit) {
        if (IsPausing()) {
            XSleep(2);
            continue;
        }
        XData d = Read();
        // 将读取到的数据发送出去(发送给解码对象)
        if (d.size > 0) {
            observable->Notify(d);
            continue;
        } else {
            XSleep(2);
        }
    }
};

//读取一帧数据,数据由调用者清理
XData FFDemux::Read() {
    mux.lock();
    if (!avFormatContext) {
        mux.unlock();
        return XData();
    }

    XData data;
    AVPacket *avPacket = av_packet_alloc();
    int ret = av_read_frame(avFormatContext, avPacket);
    if (ret != 0) {
        mux.unlock();
        //释放内存
        av_packet_free(&avPacket);
        return XData();
    }
    //转换pts
    avPacket->pts = avPacket->pts *
                    (1000 * r2d(avFormatContext->streams[avPacket->stream_index]->time_base));
    avPacket->dts = avPacket->dts *
                    (1000 * r2d(avFormatContext->streams[avPacket->stream_index]->time_base));
    data.data = (unsigned char *) avPacket;
    data.size = avPacket->size;

    if (avPacket->stream_index == videoStream) {
        data.decodeType = DECODE_TYPE_VIDEO; //视频数据
    } else if (avPacket->stream_index == audioStream) {
        data.decodeType = DECODE_TYPE_AUDIO; //音频数据
    } else {
        mux.unlock();
        av_packet_free(&avPacket);
        return XData();
    }
    mux.unlock();
    return data;
}


Here has been read from the file to the data, a data read, data is sent to a decoding target process.

Recording next chapter decoding process !!!!

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Guess you like

Origin blog.csdn.net/qq_33635618/article/details/91392933
Recommended