Simple analysis of FFPLAY.C function structure (drawing)

Source: Internet
Author: User
Recently, I have been reviewing the source code of Ffplay. Ffplay is an example of the player provided by the FFmpeg project. Although Ffplay is just a simple example of a player, the amount of its source code is quite a bit. The previous look at the code, mainly focused on a "point" for the study, but not from the overall structure of the analysis. This article intends to make up for the shortcomings of the previous study, from the overall structure of the ffplay of the source code, draw a picture of its structure. There are many shortcomings, the opportunity to gradually improve.
Describe the rules of your own drawing: only the calling relationship between the more important functions is drawn. The pink function is the API for the FFmpeg codec class library (Libavcodec,libavformat, etc.). The purple function is the SDL API. Other functions that are not very important are no longer listed.
Before looking at FFPLAY.C's code, it's a good idea to look at the simple code to understand the core code of FFmpeg playing a video:

100 lines of code for the simplest FFMPEG+SDL-based video player

The simplest ffmpeg+sdl-based audio player
Overall structure diagram

The overall function call structure of the Ffplay is shown in the following figure.


The picture above shows a big picture of high definition. However, the page does not display. So I uploaded a copy of:
http://my.csdn.net/leixiaohua1020/album/detail/1788077

The image of the

above address is a clear picture. The main functions are parsed separately below.


Main () main () is the main function of Ffplay. The
invokes the following function
Av_register_all (): Registers all encoders and decoders.
Show_banner (): Print output FFmpeg version information (compile time, compile options, class library information, etc.).
parse_options (): resolves the input command.
Sdl_init (): SDL initialization.
Stream_open (): Turns on input media.
Event_loop (): Handles various messages and keeps looping.


The contents of the red box in the following figure are the output of Show_banner ().
 

parse_options () parse_options () resolve all input options. A command such as "-F" in the command "Ffplay-f h264 test.264" will be entered to parse it out. The function call structure is shown in the following figure. It is important to note that ffmpeg.c () in Ffplay (FFPLAY.C) parse_options () and FFmpeg (parse_options) are actually the same. Therefore, the contents of this section and "FFMPEG.C function structure simple analysis (Drawing)" in the Parse_options () there is a lot of repetition.
  Parse_options () invokes the following function:
parse_option (): resolves an input option. Specific parsing steps are not mentioned. Parse_options () loops through the parse_option () until all options have been resolved. Each option information for the ffmpeg is stored in a optiondef structure. is defined as follows:

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 OPTCT
         X */#define OPT_SPEC 0x8000/* option is to being stored in an array of specifieropt. Implies Opt_offset. The Next element after the offset is a 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;

The important fields are:
Name: Names used to store options. For example "I", "F", "codec" and so on.
Flags: Stores the type of option value. For example: Has_arg (contains option values), opt_string (option value is String type), opt_time (option value is a time type.)
U: The handler function that stores the option.
Help: Description of the option.
FFmpeg uses an array of type optiondef, called options, to store all the options. A subset of the common options are stored in cmdutils_common_opts.h. These options are for Ffmpeg,ffplay and Ffprobe.
Cmdutils_common_opts.h content is as follows:
	{"L", Opt_exit, {(void*) Show_license}, "Show License"}, {"H", Opt_exit, {(void*) Show_hel          P}, "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"}, {"D Ecoders ", Opt_exit, {(void*) show_decoders}," Show available Decoders "}, {" Encoders ", Opt_exit, {(void*) Sho W_encoders}, "Show available Encoders"}, {"Bsfs", Opt_exit, {(void*) Show_bsfs}, "Show available B It 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 Availab Le audio sample Formats "}, {" LogLevel ", Has_arg, {(void*) Opt_loglevel}," Set libav* logging Level "," Loglev      El "}, {" 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_code  C_debug}, "Set Debug Flags", "flags"}, {"Report", 0, {(void*) Opt_report}, "Generate a"}, { "Max_alloc", Has_arg, {(void*) Opt_max_alloc}, "Set maximum size of a single allocated block", "bytes"}, {"C Puflags ", Has_arg | OPt_expert, {(void*) Opt_cpuflags}, "Force specific CPU Flags", "Flags"}, 

The options array is defined in Ffplay.c, as follows:
static const OPTIONDEF options[] = {#include "cmdutils_common_opts.h"//included in {"X", Has_arg, {(void*) opt_width}, "Forc E 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 Screens"}, {"An", Opt_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_in T | Has_arg | Opt_expert, {&wanted_stream[avmedia_type_video]}, "Select desired VIDEO stream", "Stream_number"}, {"SST", opt_in T | Has_arg | Opt_expert, {&wanted_stream[avmedia_type_subtitle]}, "Select desired SUBTITLE stream", "Stream_number"}, {"ss", H As_arg, {(void*) Opt_seek}, "seek to a given Position in seconds "," pos "}, {" T ", Has_arg, {(void*) opt_duration}," Play \ "duration\" Seconds of Audio/video "," D Uration "},//Many options, no longer listed ...};


There are a number of options, simply a few examples:
Force set width options for setting screen ("-X" option):
{"X", Has_arg, {(void*) Opt_width}, "force displayed width", "width"}
As you can see from the code, the "-X" option contains the option value (Has_arg), and the option handler is Opt_width (). The option description is "force displayed width". The contents of Opt_width () are 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;
}

You can see that 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"}

As you can see from the code, the "-FS" option contains the Boolean option value (Opt_bool) and binds the global variable Is_full_screen. The option description is "Force full screen".

Sdl_init ()Sdl_init () is used to initialize the SDL. SDL is used for both video display and sound playback in Ffplay.
Stream_open ()The function of Stream_open () is to open the input media. This function is still more complex and contains the creation of various threads in the Ffplay. Its function call structure is shown in the following figure.
Stream_open () invokes the following function:
Packet_queue_init (): Initialize each packetqueue (video/audio/subtitle)
Read_thread (): Reads the media information thread.

Read_thread ()

Read_thread () invokes the following function: Avformat_open_input (): Opens the media.
Avformat_find_stream_info (): Get media information.
Av_dump_format (): Outputs media information to the console.
Stream_component_open (): Turn on the video/audio/subtitle decoding thread respectively.
Refresh_thread (): Video refresh thread.
Av_read_frame (): Gets a frame of compressed encoded data (that is, a avpacket).
Packet_queue_put (): Depending on the type of compression encoded data (video/audio/subtitle), put it in a different packetqueue.



Refresh_thread ()

Refresh_thread () calls the following function: Sdl_pushevent (ff_refresh_event): Send Ff_refresh_event Sdl_event
Av_usleep (): Every two times between sends, interval period of time.

Stream_component_open ()

Stream_component_open () is used to turn on the video/audio/subtitle decoding thread. The function call relationship is shown in the following figure.


Stream_component_open () invokes the following function:
Avcodec_find_decoder (): Gets the decoder.
Avcodec_open2 (): Opens the decoder.
Audio_open (): Turn on audio decoding.
Sdl_pauseaudio (0): Functions for playing audio in SDL.
Video_thread (): Creates a video decoding thread.
Subtitle_thread (): Creates a caption decoding thread.
Packet_queue_start (): initializes the packetqueue.


Audio_open () calls the following function
Sdl_openaudio (): The function that opens the audio device in SDL. Note that it is the audio device that is opened according to the Sdl_audiospec parameter. The callback field in SDL_AUDIOSPEC specifies the callback function sdl_audio_callback () for audio playback. The callback function is called when more data is required by the audio device. Therefore, the function is called repeatedly.


Here's 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 (): Call this function when the video image is not displayed, but the audio waveform is displayed.


Audio_decode_frame () calls the following function
Packet_queue_get (): Gets the audio compression encoded data (one avpacket).
Avcodec_decode_audio4 (): Decodes audio compression encoded data (gets a avframe).
Swr_init (): Initializes the Swrcontext in the libswresample. The libswresample is used for the conversion of audio sample sampling data (PCM).
Swr_convert (): Converts the audio sample rate to a format suitable for system playback.
Swr_free (): Release Swrcontext.


Video_thread () calls the following function
Avcodec_alloc_frame (): Initializes a avframe.
Get_video_frame (): Gets a avframe that stores the decoded data.
Queue_picture ():


Get_video_frame () calls the following function
Packet_queue_get (): Gets the video compression encoded data (one avpacket).
Avcodec_decode_video2 (): Decode the video compression encoded data (get a avframe).


Queue_picture () calls the following function
Sdl_lockyuvoverlay (): Locks a sdl_overlay.
Sws_getcachedcontext (): Initializes the Swscontext in the Libswscale. Libswscale is used for conversion between RAW format data (YUV,RGB) for images. Note that the Sws_getcachedcontext () and Sws_getcontext () functions are consistent.
Sws_scale (): Converts image data to a format suitable for system playback.
Sdl_unlockyuvoverlay (): Unlocks a sdl_overlay.




Subtitle_thread () calls the following function
Packet_queue_get (): Gets the caption compression encoded data (one avpacket).

Avcodec_decode_subtitle2 (): Decode subtitle compression encoded data. event_loop ()Ffplay after the media is turned on, it goes into the Event_loop () function and loops forever. This function is used to receive and process a wide variety of messages. A bit like the Windows message loop mechanism.
PS: The loop is indeed endless, 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 Event_loop () function call relationship is as follows.
Depending on the type of sdl_event received by Sdl_waitevent () in Event_loop (), different functions are called for processing (a switch () syntax from a programmatic point of view). Just a few examples are listed:
Sdlk_escape (Press "ESC" key): Do_exit (). Exits the program.
Sdlk_f (press "F" key): Toggle_full_screen (). Toggles the full-screen display.
Sdlk_space (Press the "SPACEBAR" key): Toggle_pause (). Toggle "Pause".
Sdlk_down (Press the mouse button): Stream_seek (). Jumps to the specified point in time to play.
Sdl_videoresize (window size changed): Sdl_setvideomode (). Reset the width height.
Ff_refresh_event (Video Refresh event (custom event)): Video_refresh (). Refresh the video.


The Do_exit () function is analyzed below. This function is used to exit the program. The call relationship for a function is shown in the following figure.
The Do_exit () function calls the following function
Stream_close (): Turns off the open media.
Sdl_quit (): Turn off SDL.


The Stream_close () function calls the following function
Packet_queue_destroy (): Release Packetqueue.
Sdl_freeyuvoverlay (): Release Sdl_overlay.
Sws_freecontext (): Release Swscontext.


The following focuses on analyzing the Video_refresh () function. This function is used to display the image on the display. The call relationship for a function is shown in the following figure.
The Video_refresh () function calls the following function
Video_display (): Displays the pixel data to the screen.
Show_status: This is not a function, but it is a separate function module, so it is listed. This section prints out the status of the playback to the screen. As shown in the following figure.
The Video_display () function calls the following function
Video_open (): Called when initializing, open the playback window.
Video_audio_display (): Called when an audio waveform (or spectral graph) is displayed. It contains a lot of drawing operations.
Video_image_display (): Called when the video screen is displayed.


The Video_open () function calls the following function
Sdl_setvideomode (): Sets information such as the size of the sdl_surface (that is, the most basic black box of the SDL).
Sdl_wm_setcaption (): Sets the caption text for the sdl_surface corresponding window.


The Video_audio_display () function calls the following function
Sdl_maprgb (): Gets the color value of the specified (R,G,B) and Sdl_pixelformat. For example, get the black value as the background. (r,g,b) for (0x00,0x00,0x00).
Fill_rectangle (): Displays the specified color to the screen.
Sdl_updaterect (): Update screen.


The Video_image_display () function calls the following function
Calculate_display_rect (): Calculates the position of the display screen. When you stretch the SDL window, you can keep the video in its aspect ratio.
Sdl_displayyuvoverlay (): Display to screen.

Related Article

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.