Simple Analysis of ffplay. c function structure (drawing), simple ffplay. c structure

Source: Internet
Author: User

Simple Analysis of ffplay. c function structure (drawing), simple ffplay. c structure
Recently I reviewed the source code of FFplay. FFplay is an example of a player provided by the FFmpeg project. Although FFplay is just a simple player example, it has a lot of source code. The code is mainly focused on a "point" for research, but not on the overall structure. This article intends to make up for the shortcomings of previous studies, analyze the FFplay source code from the overall structure, and draw a picture of its structure. There are still many shortcomings that will be improved in the future.
Describe the rules of the Self-drawn structure: the figure only shows the call relationship between important functions. The pink function is the FFmpeg codec class library (libavcodec, libavformat, etc.) API. The purple function is the sdl api. Other functions that are not very important are not listed.
Before reading the ffplay. c code, you 'd better take a look at the simple code to understand the core code of playing a video from FFmpeg:

100-line code is the simplest Video Player Based on FFMPEG + SDL.

The simplest Audio Player Based on FFmpeg + SDL


Overall Structure

Shows the overall function call structure of FFplay.


This is a large image in high definition. But the page cannot be displayed. Therefore, a copy is uploaded:
Http://my.csdn.net/leixiaohua1020/album/detail/1788077

The figure at the above address is saved as a clear image.

The following describes the main functions.


Main () is the main function of FFplay.
The following function is called:
Av_register_all (): registers All encoders and decoders.
Show_banner (): prints the output FFmpeg version information (such as the compilation time, compilation options, and class library information ).
Parse_options (): parses the input command.
SDL_Init (): SDL initialization.
Stream_open (): Open the input media.
Event_loop (): Processes various messages and keeps repeating.


The content in the red box is the output result of show_banner.
 

Parse_options () Parse all input options. The command "-f" in "ffplay-f h264 test.264" will be input for parsing. Shows the function call structure. Note that the parse_options () of FFplay (ffplay. c) is the same as the parse_options () in FFmpeg (ffmpeg. c. Therefore, the content of this section is similar to parse_options () in "ffmpeg. c function structure simple analysis (drawing.
Parse_options () calls the following functions:
Parse_option (): parse an input option. The specific parsing steps are not described in detail. Parse_options () cyclically calls parse_option () until all options are parsed. Each option Information of FFmpeg is stored in an OptionDef struct. Definition:
typedef struct OptionDef {    const char *name;    int flags;#define HAS_ARG    0x0001#define OPT_BOOL   0x0002#define OPT_EXPERT 0x0004#define OPT_STRING 0x0008#define OPT_VIDEO  0x0010#define OPT_AUDIO  0x0020#define OPT_INT    0x0080#define OPT_FLOAT  0x0100#define OPT_SUBTITLE 0x0200#define OPT_INT64  0x0400#define OPT_EXIT   0x0800#define OPT_DATA   0x1000#define OPT_PERFILE  0x2000     /* the option is per-file (currently ffmpeg-only).         implied by OPT_OFFSET or OPT_SPEC */#define OPT_OFFSET 0x4000       /* option is specified as an offset in a passed optctx */#define OPT_SPEC   0x8000       /* option is to be stored in an array of SpecifierOpt.         Implies OPT_OFFSET. Next element after the offset is         an int containing element count in the array. */#define OPT_TIME  0x10000#define OPT_DOUBLE 0x20000     union {        void *dst_ptr;        int (*func_arg)(void *, const char *, const char *);        size_t off;    } u;    const char *help;    const char *argname;} OptionDef;

Important fields:
Name: name used to store options. For example, "I", "f", and "codec.
Flags: Type of the stored option value. For example, HAS_ARG (including the option value), OPT_STRING (the option value is of the string type), and OPT_TIME (the option value is of the time type.
U: The processing function that stores this option.
Help: Describes the options.
FFmpeg uses an array named options and its type is OptionDef to store all options. Some common options are stored in cmdutils_common_opts.h. These options are applicable to FFmpeg, FFplay, and FFprobe.
The contents of cmdutils_common_opts.h are as follows:
{ "L"          , OPT_EXIT, {(void*)show_license},      "show license" },    { "h"          , OPT_EXIT, {(void*) show_help},         "show help", "topic" },    { "?"          , OPT_EXIT, {(void*)show_help},         "show help", "topic" },    { "help"       , OPT_EXIT, {(void*)show_help},         "show help", "topic" },    { "-help"      , OPT_EXIT, {(void*)show_help},         "show help", "topic" },    { "version"    , OPT_EXIT, {(void*)show_version},      "show version" },    { "formats"    , OPT_EXIT, {(void*)show_formats  },    "show available formats" },    { "codecs"     , OPT_EXIT, {(void*)show_codecs   },    "show available codecs" },    { "decoders"   , OPT_EXIT, {(void*)show_decoders },    "show available decoders" },    { "encoders"   , OPT_EXIT, {(void*)show_encoders },    "show available encoders" },    { "bsfs"       , OPT_EXIT, {(void*)show_bsfs     },    "show available bit stream filters" },    { "protocols"  , OPT_EXIT, {(void*)show_protocols},    "show available protocols" },    { "filters"    , OPT_EXIT, {(void*)show_filters  },    "show available filters" },    { "pix_fmts"   , OPT_EXIT, {(void*)show_pix_fmts },    "show available pixel formats" },    { "layouts"    , OPT_EXIT, {(void*)show_layouts  },    "show standard channel layouts" },    { "sample_fmts", OPT_EXIT, {(void*)show_sample_fmts }, "show available audio sample formats" },    { "loglevel"   , HAS_ARG,  {(void*)opt_loglevel},      "set libav* logging level", "loglevel" },    { "v",           HAS_ARG,  {(void*)opt_loglevel},      "set libav* logging level", "loglevel" },    { "debug"      , HAS_ARG,  {(void*)opt_codec_debug},   "set debug flags", "flags" },    { "fdebug"     , HAS_ARG,  {(void*)opt_codec_debug},   "set debug flags", "flags" },    { "report"     , 0,        {(void*)opt_report}, "generate a report" },    { "max_alloc"  , HAS_ARG,  {(void*) opt_max_alloc},     "set maximum size of a single allocated block", "bytes" },    { "cpuflags"   , HAS_ARG | OPT_EXPERT, {(void*) opt_cpuflags}, "force specific cpu flags", "flags" },

The options array is defined in ffplay. c, as shown below:
Static const OptionDef options [] = {# include "cmdutils_common_opts.h" // contains {"x", HAS_ARG, {(void *) opt_width}, "force displayed width ", "width" },{ "y", HAS_ARG, {(void *) opt_height}, "force displayed height", "height" },{ "s", HAS_ARG | OPT_VIDEO, {(void *) opt_frame_size}, "set frame size (WxH or abbreviation)", "size" },{ "fs", OPT_BOOL, {& is_full_screen }, "force full screen"}, {"an", O PT_BOOL, {& audio_disable}, "disable audio" },{ "vn", OPT_BOOL, {& video_disable}, "disable video" },{ "ast ", OPT_INT | HAS_ARG | OPT_EXPERT, {& wanted_stream [AVMEDIA_TYPE_AUDIO]}, "select desired audio stream", "stream_number" },{ "vst", OPT_INT | HAS_ARG | OPT_EXPERT, {& wanted_stream [AVMEDIA_TYPE_VIDEO]}, "select desired video stream", "stream_number" },{ "sst", OPT_INT | HAS_ARG | OPT_EXPE RT, {& wanted_stream [AVMEDIA_TYPE_SUBTITLE]}, "select desired subtitle stream", "stream_number" },{ "ss", HAS_ARG, {(void *) opt_seek }, "seek to a given position in seconds", "pos" },{ "t", HAS_ARG, {(void *) opt_duration }, "play \" duration \ "seconds of audio/video", "duration"}, // a large number of options, not listed one by one ...};


There are many options. Here are a few simple examples:
Forcibly set the screen width option ("-x" option ):
{ "x", HAS_ARG, { (void*) opt_width }, "force displayed width", "width" }
The Code shows that the "-x" option contains the option value (HAS_ARG), and the option handler function is opt_width (). The option description is "force displayed width ". The content of opt_width () is as follows:
static int opt_width(void *optctx, const char *opt, const char *arg){screen_width = parse_number_or_die(opt, arg, OPT_INT64, 1, INT_MAX);return 0;}

The function is to parse the input string as an integer and assign the value to the global variable screen_width.


Full Screen ("-fs" option)
{ "fs", OPT_BOOL, { &is_full_screen }, "force full screen" }

The Code shows that the "-fs" option contains the Boolean option value (OPT_BOOL) and is bound to the global variable is_full_screen. The option is "force full screen ".

SDL_Init () is used to initialize SDL. In FFplay, SDL is used for video display and sound playback.
Stream_open () is used to open the input media. This function is still complex, including the creation of various threads in FFplay. Shows its function call structure.
Stream_open () calls the following functions:
Packet_queue_init (): Initialize each PacketQueue (video/audio/subtitle)
Read_thread (): Read media information thread.

Read_thread ()

Read_thread () calls the following functions:

Avformat_open_input (): Open the media.
Avformat_find_stream_info (): obtain media information.
Av_dump_format (): outputs media information to the console.
Stream_component_open (): Enable the video/audio/subtitle decoding threads respectively.
Refresh_thread (): Specifies the video refresh thread.
Av_read_frame (): obtains a compressed frame of encoded data (that is, an AVPacket ).
Packet_queue_put (): Based on the compression encoding data types (video/audio/subtitle), put them in different PacketQueue.



Refresh_thread ()

Refresh_thread () calls the following functions:

SDL_PushEvent (FF_REFRESH_EVENT): Send the SDL_Event of FF_REFRESH_EVENT
Av_usleep (): interval between two sends.

Stream_component_open ()

Stream_component_open () is used to open the video/audio/subtitle decoding thread. Shows the function call relationship.


Stream_component_open () calls the following functions:
Avcodec_find_decoder (): obtains the decoder.
Avcodec_open2 (): Enable the decoder.
Audio_open (): Enable audio decoding.
SDL_PauseAudio (0): the audio playing function in SDL.
Video_thread (): Creates a video decoding thread.
Subtitle_thread (): Creates a subtitle decoding thread.
Packet_queue_start (): Initialize PacketQueue.


Audio_open () calls the following function:
SDL_OpenAudio (): function used to enable the audio device in SDL. Note that it enables the audio device according to the SDL_AudioSpec parameter. The callback field in SDL_AudioSpec specifies the callback function sdl_audio_callback () for audio playback (). This callback function is called when the audio device needs more data. Therefore, this function is called repeatedly.


Next let's take a look at the callback function sdl_audio_callback () specified in SDL_AudioSpec ().
Sdl_audio_callback () calls the following function:
Audio_decode_frame (): decodes audio data.
Update_sample_display (): This function is called when the video image is not displayed but the audio waveform is displayed.


Audio_decode_frame () calls the following function:
Packet_queue_get (): obtains the audio compression and encoding data (an AVPacket ).
Avcodec_decode_audio4 (): decodes audio compression encoding data (to obtain an AVFrame ).
Swr_init (): Initialize SwrContext in libswresample. Libswresample is used to convert the audio sample data (PCM.
Swr_convert (): converts the audio sampling rate to a format suitable for system playback.
Swr_free (): releases SwrContext.


Video_thread () calls the following function:
Avcodec_alloc_frame (): initializes an AVFrame.
Get_video_frame (): obtains an AVFrame that stores decoded data.
Queue_picture ():


Get_video_frame () calls the following function:
Packet_queue_get (): obtains the compressed video encoding data (an AVPacket ).
Avcodec_decode_video2 (): decodes the compressed video encoding data (obtain an AVFrame ).


Queue_picture () calls the following functions:
SDL_LockYUVOverlay (): locks an SDL_Overlay.
Sws_getCachedContext (): Initialize SwsContext in libswscale. Libswscale is used to convert Raw data (YUV, RGB) of an image. Note that the sws_getCachedContext () and sws_getContext () functions are the same.
Sws_scale (): converts image data to a format suitable for system playback.
SDL_UnlockYUVOverlay (): Unlock an SDL_Overlay.




Subtitle_thread () calls the following function
Packet_queue_get (): obtains the compressed subtitle encoding data (an AVPacket ).

Avcodec_decode_subtitle2 (): decodes subtitle compression encoding data.

After event_loop () FFplay starts the media, it enters the event_loop () function and continues continuously. This function is used to receive and process various messages. It is a bit like the message Loop Mechanism in Windows.
PS: the cycle is indeed complete, in the form of the following:
SDL_Event event;for (;;) {SDL_WaitEvent(&event);switch (event.type) {case SDLK_ESCAPE:case SDLK_q:do_exit(cur_stream);break;case SDLK_f:……}}


The call relationship of event_loop () is as follows.
Depending on the SDL_Event type received by SDL_WaitEvent () in event_loop (), different functions are called for processing (from a programming perspective, it is a switch () syntax ). The figure only lists several examples:
SDLK_ESCAPE (Press "ESC"): do_exit (). Exit the program.
SDLK_f (press the "f" key): toggle_full_screen (). Switch to full screen display.
SDLK_SPACE (press the "space" key): toggle_pause (). Switch to "Suspend ".
SDLK_DOWN (press the mouse key): stream_seek (). Jump to the specified time point for playback.
SDL_VIDEORESIZE (window size changed): SDL_SetVideoMode (). Reset the width and height.
FF_REFRESH_EVENT (Video refresh event (Custom Event): video_refresh (). Refresh the video.


The following describes the do_exit () function. This function is used to exit the program. Shows the call relationship of a function.
The do_exit () function calls the following functions:
Stream_close (): close open media.
SDL_Quit (): Disable SDL.


The stream_close () function calls the following functions:
Packet_queue_destroy (): Release PacketQueue.
SDL_FreeYUVOverlay (): releases SDL_Overlay.
Sws_freeContext (): releases SwsContext.


The following describes the video_refresh () function. This function is used to display the image to the display. Shows the call relationship of a function.
The video_refresh () function calls the following functions:
Video_display (): displays pixel data to the screen.
Show_status: this is not a function, but an independent function module, so it is listed. This part prints the output status to the screen. As shown in.
The video_display () function calls the following functions:
Video_open (): called during initialization to open the playing window.
Video_audio_display (): used to display audio waveforms (or spectrum charts. It contains many drawing operations.
Video_image_display (): called when the video screen is displayed.


The video_open () function calls the following functions:
SDL_SetVideoMode (): sets the size of SDL_Surface (I .e., the basic black box of SDL) and other information.
SDL_WM_SetCaption (): Set the title text of the window corresponding to SDL_Surface.


The video_audio_display () function calls the following functions:
SDL_MapRGB (): obtains the specified (R, G, B) and SDL_PixelFormat color values. For example, obtain the black value as the background. (R, G, B) is (0x00,0x00,0x00 ).
Fill_rectangle (): displays the specified color on the screen.
SDL_UpdateRect (): Update screen.


The video_image_display () function calls the following functions:
Calculate_display_rect (): calculates the position of the display screen. When the SDL window is stretched, the video aspect ratio can be maintained.
SDL_DisplayYUVOverlay (): displays the screen.


Use the C language drawing function to draw the moonlight in the pond

Drawing with C language, extremely difficult,

Tell me a drawing software. function: (input a custom function to automatically draw a Graph Based on the function)

You can use "Drawing" in windows.

Very simple... use "selected" (that is, a rectangular icon) to select the size, copy, paste the post...

A few more "drawings" can be opened for multiple images, and the "Drawing" can be pasted together.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.