FFmpeg Code Framework for FFmpeg Open Course, Ali Middleware

  • 2. Open the video file

avformat_open_input(&ifmt_ctx, in_filename, 0, 0)

  • 3. Continuous reading of video frames

while(...) { av_read_frame(ifmt_ctx, &pkt) }

  • 4. Close avformat context

avformat_close_input(&ifmt_ctx)

Write video flow:

  • 1. Create output context

avformat_alloc_output_context2(&ofmt_ctx, NULL, NULL, out_filename)

  • 2. Write Format Header

avformat_write_header(ofmt_ctx, NULL)

  • 3. Continuous Output Frame

while(...) { av_interleaved_write_frame(ofmt_ctx, &pkt) }

  • 4. End of Write Format

av_write_trailer(ofmt_ctx)

  • 5. Close context

avformat_free_context(ofmt_ctx)

AVInputFormat

Demuxer, the formal structure of AVInputFormat, is actually an interface. The function of Demuxer is to unlock the encapsulated format container to get the encoded audio and video.Simply put, it is the unpacking tool.

All kinds of multimedia formats we know, such as MP4, MP3, FLV and so on, are read by AVInputFormat.

There are many types of demuxers and they are configurable. How many demuxers are there? See demuxer_list.c file, too many to list, let's take an example of mp4 demuxer.

Following is the decompressor ff_for mp4 video formatMov_Demuxer, in mov.c:

AVInputFormat ff_mov_demuxer = {
    .name           = "mov,mp4,m4a,3gp,3g2,mj2",
    .long_name      = NULL_IF_CONFIG_SMALL("QuickTime / MOV"),
    .priv_class     = &mov_class,
    .priv_data_size = sizeof(MOVContext),
    .extensions     = "mov,mp4,m4a,3gp,3g2,mj2",
    .read_probe     = mov_probe,
    .read_header    = mov_read_header,
    .read_packet    = mov_read_packet,
    .read_close     = mov_read_close,
    .read_seek      = mov_read_seek,
    .flags          = AVFMT_NO_BYTE_SEEK | AVFMT_SEEK_TO_PTS,
}; 

You see several function pointers:

  • read_probe

Detect what encapsulation format

  • read_header

Read Format Header Data

  • read_packet

Read unpacked packets

  • read_close

Close Object

  • read_seek

Format seek Read Control

You can see that AVInputFormat provides interface-like functionality, while ff_mov_demuxer is one of its implementations.FFmpeg's logic is not complicated, but because of the rich formats it supports, there is so much code.If we ignore most of the formats first and focus on the implementation of several of them by FFmpeg, we can better understand FFmpeg.

AVOutputFormat

The encapsulator Muxer, whose corresponding structure is AVOutputFormat, is also an interface for encoding audio and video into a format container.Simply put, it's a packaging tool.

Follow _Demuxer_DecapsulatorSimilarly, it is an implementation of MP4, MP3, FLV and other formats, the difference is _Encapsulator Muxer_For output.

Similar to demuxer, there are many kinds of muxers, so take a look at muxer_list.c file.Take a look at the Muxer for mp3, in mp3enc.c:

AVOutputFormat ff_mp3_muxer = {
    .name              = "mp3",
    .long_name         = NULL_IF_CONFIG_SMALL("MP3 (MPEG audio layer 3)"),
    .mime_type         = "audio/mpeg",
    .extensions        = "mp3",
    .priv_data_size    = sizeof(MP3Context),
    .audio_codec       = AV_CODEC_ID_MP3,
    .video_codec       = AV_CODEC_ID_PNG,
    .write_header      = mp3_write_header,
    .write_packet      = mp3_write_packet,
    .write_trailer     = mp3_write_trailer,
    .query_codec       = query_codec,
    .flags             = AVFMT_NOTIMESTAMPS,
    .priv_class        = &mp3_muxer_class,
}; 

There is also a corresponding pointer function above, which is the inverse of demuxer.

AVCodecContext

Similar to AVFormatContext, we also pair _with AVCodecContext Encoder_And _Decoder_Operations generally do not directly operate the codec.Therefore, you need to implement codec, which typically deals with AVCodecContext.

Like demuxer and muxer, codec has decode and encode, referring specifically to codec_list.c file: view ff_libx264_encoder, in libx264.c:

AVCodec ff_libx264_encoder = {
    .name             = "libx264",
    .long_name        = NULL_IF_CONFIG_SMALL("libx264 H.264 / AVC / MPEG-4 AVC / MPEG-4 part 10"),
    .type             = AVMEDIA_TYPE_VIDEO,
    .id               = AV_CODEC_ID_H264,
    .priv_data_size   = sizeof(X264Context),
    .init             = X264_init,
    .encode2          = X264_frame,
    .close            = X264_close,
    .capabilities     = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_AUTO_THREADS |
                        AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE,
    .priv_class       = &x264_class,
    .defaults         = x264_defaults,
    .init_static_data = X264_init_static,
    .caps_internal    = FF_CODEC_CAP_INIT_CLEANUP,
    .wrapper_name     = "libx264",
}; 

The core function is encode2, corresponding to X264_frame function

Parser in FFmpeg

Parser, Packets that convert input streams to frames Since the input of the decoder is a complete Frame packet, whether network or file read, it is usually read by a fixed buffer, not by the Frame size of the installation format, so we need Parser to organize the streams into one Frame packet.

The parser's global declaration is in parsers.c, specifically defined in list_parser.c Take a look at h264_Ff_in parser.cH264_Parser example:

AVCodecParser ff_h264_parser = {
    .codec_ids      = { AV_CODEC_ID_H264 },
    .priv_data_size = sizeof(H264ParseContext),
    .parser_init    = init,
    .parser_parse   = h264_parse,
    .parser_close   = h264_close,
    .split          = h264_split,
}; 

The H264ParseContext structure is a frame data definition in H264 format.

typedef struct H264ParseContext {
    ParseContext pc;
    H264ParamSets ps;
    H264DSPContext h264dsp;
    H264POCContext poc;
    H264SEIContext sei;
    int is_avc;
    int nal_length_size;
    int got_first;
    int picture_structure;
    uint8_t parse_history[6];
    int parse_history_count;
    int parse_last_mb;
    int64_t reference_dts;
    int last_frame_num, last_picture_structure;
} H264ParseContext; 

Here's a quick look. H264ParamSets are very important. The key parameters of H264 are defined here: sps and pps, which we know well, are defined here. With these two definitions, we can quickly find the properties of the current frame in the macroblock.

typedef struct H264ParamSets {
    AVBufferRef *sps_list[MAX_SPS_COUNT];
    AVBufferRef *pps_list[MAX_PPS_COUNT];

    AVBufferRef *pps_ref;
    AVBufferRef *sps_ref;
    /* currently active parameters sets */
    const PPS *pps;
    const SPS *sps;
} H264ParamSets; 

Summary

  • The learning process of FFmpeg is difficult. Clear the structure and clear the overall code context, but core modules such as libavfilter are not discussed in this paper.This module is very large and customizable and will be discussed separately later.
  • Learning FFmpeg in practice will improve faster.Here are some practical ideas.
  • FFmpeg Code Structure
  • FFmpeg cross-compilation
  • FFmpeg Decapsulation
  • FFmpeg repackaging
  • FFmpeg decoding
  • FFmpeg Separate Audio and Video Stream

Last

It's not easy. If you like this article, or if you're helpful, I hope you like it a little more and forward your attention.The article will be continuously updated.Absolutely dry!!!

CodeChina Open Source Project: "Android Learning Notes Summary + Mobile Architecture Video + Factory Interview True Topics + Project Actual Source"

  • Android Advanced Learning Complete Manual
    As for actual warfare, I think every development has something to say. For Xiao Bai, lack of practical experience is a common problem. How can we know more about actual warfare in addition to the actual working process?In fact, it's very necessary to read some real-world e-books.At present, the e-books I have sorted out are quite comprehensive, including advanced technologies such as HTTP, custom view, c++, MVP, Android source code design mode, Android development art exploration, Java concurrent programming art, Android Glide-based secondary encapsulation, Android memory optimization - common memory leaks and optimization schemes, and.Java programming ideas (4th edition).

  • Advanced Knowledge System Diagram for Android Senior Architect
    I also collected some videos by myself and made a classification according to the Android learning route.There are eight modules along the Android learning route, all of which have videos to help you learn systematically.Next, take a look at the map and corresponding system video!!!

  • Android Bid Ali P7 Learning Video

  • BATJ Android High Frequency Interview Questions
    This gallery contains a lot of content, except for some popular technical interviews such as Kotlin, Database, Java Virtual Machine, Array, Framework, Mixed Cross-Platform Development, etc.
    Frequently!!!
    [img-MpY0uhJL-1630514734709)]

  • Android Bid Ali P7 Learning Video

[img-Jenj9uT9-1630514734712)]

  • BATJ Android High Frequency Interview Questions
    This gallery contains a lot of content, except for some popular technical interviews such as Kotlin, Database, Java Virtual Machine, Array, Framework, Mixed Cross-Platform Development, etc.

Tags: Android Design Pattern

Posted on Wed, 01 Sep 2021 22:07:34 -0400 by williamg