FFmpeg source code Simple analysis: Avformat_close_input ()

Source: Internet
Author: User

This paper simply analyzes the Avformat_close_input () function of ffmpeg. This function is used to close a avformatcontext, which is normally used in pairs with avformat_open_input ().

The declaration of Avformat_close_input () is located in Libavformat\avformat.h, as shown below.
/** * Close an opened input avformatcontext. Free It contents * and set *s to NULL. */void avformat_close_input (Avformatcontext **s);

The most typical examples of this function can be consulted:

The simplest ffmpeg+sdl-based video player Ver2 (with SDL2.0)


Function call graph

The call relationship for the function is shown.


Avformat_close_input () Take a look at the source code for Avformat_close_input (), located in the libavformat\utils.c file.
void Avformat_close_input (Avformatcontext **ps) {    avformatcontext *s;    Aviocontext *PB;    if (!ps | |!*ps)        return;    s  = *ps;    PB = s->pb;    if ((S->iformat && strcmp (s->iformat->name, "Image2") && S->iformat->flags & Avfmt_ Nofile) | |        (S->flags & Avfmt_flag_custom_io))        PB = NULL;    Flush_packet_queue (s);    if (S->iformat)        if (s->iformat->read_close)            s->iformat->read_close (s);    Avformat_free_context (s);    *ps = NULL;    Avio_close (PB);}

As can be seen from the source code, Avformat_close_input () mainly do the following steps:
(1) Call Avinputformat's Read_close () method to close the input stream
(2) Call Avformat_free_context () to release Avformatcontext
(3) Call Avio_close () to close and release Aviocontext
Let's take a look at each of these steps.

The Read_close () of avinputformat-> Read_close () Avinputformat is a function pointer that points to the function that closes the input stream. Different avinputformat contain different read_close () methods. For example, the Avinputformat that corresponds to the FLV format is defined as follows.
Avinputformat ff_flv_demuxer = {    . Name           = "flv",    . Long_name      = Null_if_config_small ("flv (Flash Video)" ),    . priv_data_size = sizeof (Flvcontext),    . Read_probe     = Flv_probe,    . Read_header    = Flv_read_ Header,    . read_packet    = Flv_read_packet,    . Read_seek      = Flv_read_seek,    . Read_close     = Flv_read_close,    . Extensions     = "flv",    . Priv_class     = &flv_class,};

As can be seen from the definition of ff_flv_demuxer, the function pointed to by Read_close () is Flv_read_close (). We can look at the definition of Flv_read_close () as shown below.
static int flv_read_close (Avformatcontext *s) {    int i;    Flvcontext *flv = s->priv_data;    for (i=0; i<flv_stream_type_nb; i++)        av_freep (&flv->new_extradata[i]);    return 0;}

As can be seen from the definition of flv_read_close (), this function frees the memory pointed to by each element in the New_extradata array in Flvcontext.

Avformat_free_context () Avformat_free_context () is a ffmpeg API function for releasing a avformatcontext. It is important to be aware of the differences and linkages between avformat_free_context () and Avformat_close_input ().

For Avformat_free_context () refer to the article:

Simple analysis of FFmpeg source code: Allocation and release of memory


Avio_close ()

Avio_close () is a FFmpeg API function that is used to close and release Aviocontext. Its declaration is located in Libavformat\avio.h, as shown below.

/** * Close The resource accessed by the Aviocontext s and free it. * This function can is only used if S is opened by Avio_open (). * * The internal buffer is automatically flushed before closing the * resource. * * @return 0 on success, a Averror < 0 On error. * @see avio_closep */int avio_close (Aviocontext *s);

The definition of Avio_close () is located in Libavformat\aviobuf.c, as shown below.
int Avio_close (Aviocontext *s) {    urlcontext *h;    if (!s)        return 0;    Avio_flush (s);    H = s->opaque;    Av_freep (&s->buffer);    if (S->write_flag)        Av_log (S, Av_log_debug, "Statistics:%d seeks,%d writeouts\n", S->seek_count, s-> Writeout_count);    Else        Av_log (S, Av_log_debug, "Statistics:%" PRId64 "bytes read,%d seeks\n", S->bytes_read, S->seek_count); C10/>av_free (s);    return Ffurl_close (h);}

As you can see from the source code, Avio_close () follows several steps in order:
(1) Call Avio_flush () to force clear the data in the cache
(2) Call Av_freep () to release the buffer of the Aviocontext species
(3) Call Av_free () to release the AVIOCONTEXT structure
(4) Call Ffurl_close () to close and release Urlcontext

Let's look at the two functions of Avio_flush () and Ffurl_close () in order.

Avio_flush () Avio_flush () is a FFmpeg API function, declared in Libavformat\avio.h, as shown below.
/** * Force flushing of buffered data. * For write streams, force the buffered data to is immediately written to the output, * without to wait to fill the inte Rnal buffer. * For read streams, discard all currently buffered data, and advance the * reported file position to that of the underly ing stream. This does isn't * read new data, and does not perform any seeks. */void Avio_flush (Aviocontext *s);

The definition of Avio_flush () is located in Libavformat\aviobuf.c, as shown below.
void Avio_flush (Aviocontext *s) {    flush_buffer (s);    S->must_flush = 0;}

You can see that Avio_flush () simply calls the Flush_buffer () function. Let's take a look at the definition of Flush_buffer ().
static void Flush_buffer (Aviocontext *s) {    if (s->write_flag && s->buf_ptr > S->buffer) {        Writeout (S, S->buffer, s->buf_ptr-s->buffer);        if (s->update_checksum) {            s->checksum     = S->update_checksum (S->checksum, S->checksum_ptr,                                                 s->buf_ptr-s->checksum_ptr);            S->checksum_ptr = s->buffer;        }    }    S->buf_ptr = s->buffer;    if (!s->write_flag)        s->buf_end = S->buffer;}

From the Flush_buffer () definition we can see that the function buf_ptr the position of the current cache pointer to the header of the cache buffer, and then do different processing depending on whether the aviocontext corresponding stream is writable. If the aviocontext corresponding stream is read-only (the Write_flag value is 0), the cached tail buf_end is set to the cache header position, if the aviocontext corresponding stream is writable (write_flag value is not 0). The Writeout () function is called to output the remaining data in the cache.
Here we look at the definition of the writeout () function, as shown below.
static void Writeout (Aviocontext *s, const uint8_t *data, int len) {    if (s->write_packet &&!s->error) { c1/>int ret = S->write_packet (S->opaque, (uint8_t *) data, Len);        if (Ret < 0) {            s->error = ret;        }    }    S->writeout_count + +;    S->pos + = Len;}

As you can see from the definition, writeout () calls the Aviocontext Write_packet () method. According to the previous article "FFmpeg Source code Simple analysis: Avio_open2 ()" In the analysis we can understand that Aviocontext's write_packet () actually pointed to the ffurl_write () function, and Ffurl_write () The Retry_transfer_wrapper () function eventually calls the Urlprotocol's Url_write () function. Url_write () is a function pointer, with different Urlprotocol url_write () pointing to different functions.

For example, the definition of the Urlprotocol that corresponds to file is located in Libavformat\file.c, as shown below.

Urlprotocol Ff_file_protocol = {    . name                = "File",    . Url_open            = File_open,    . Url_read            = File_ Read,    . Url_write           = File_write,    . Url_seek            = File_seek,    . Url_close           = File_close,    . Url_get_file_handle = File_get_handle,    . Url_check           = File_check,    . priv_data_size      = sizeof ( Filecontext),    . Priv_data_class     = &file_class,};

You can see that Url_write () in Ff_file_protocol is pointing to the File_write () function. Let's continue to look at the source code for File_write () as shown below.
static int File_write (Urlcontext *h, const unsigned char *buf, int size) {    Filecontext *c = h->priv_data;    int R;    Size = ffmin (size, c->blocksize);    r = Write (C->FD, buf, size);    return ( -1 = = r)? Averror (errno): R;}

From the source code, it can be seen that file_write () called the system's Write () method for writing data to a file (many people may be unfamiliar with the write () function, which can be simply understood as equivalent to Fwrite ()).


Ffurl_close () and Ffurl_closep () Ffurl_close () and FFURL_CLOSEP () are two functions within ffmpeg, and their declarations are in libavformat\url.h, as shown below.
/** * Close The resource accessed by the Urlcontext H, and free the * memory used by it. Also set the Urlcontext pointer to NULL. * * @return A negative value if an error condition occurred, 0 * Otherwise */int ffurl_closep (Urlcontext **h); int FFURL_CL OSE (Urlcontext *h);

In fact, these two functions are equivalent. The definition of Ffurl_close () is located in Libavformat\avio.c, as shown below.
int Ffurl_close (Urlcontext *h) {    return ffurl_closep (&h);}

Visible ffurl_close () called FFURL_CLOSEP ().
The definition of FFURL_CLOSEP () is as follows.
int Ffurl_closep (Urlcontext **hh) {    urlcontext *h= *hh;    int ret = 0;    if (!h)        return 0;     /* can happen when Ffurl_open fails *    /if (h->is_connected && h->prot->url_close)        ret = H->PR Ot->url_close (h); #if config_network    if (h->prot->flags & url_protocol_flag_network)        ff_ Network_close (); #endif    if (h->prot->priv_data_size) {        if (h->prot->priv_data_class)            av_ Opt_free (h->priv_data);        Av_freep (&h->priv_data);    }    Av_freep (HH);    return ret;}

As can be seen from the definition of ffurl_closep (), it is mainly done in two steps:
(1) Call Urlprotocol's Url_close ()
(2) Call Av_freep () to release the Urlcontext struct
Where Urlprotocol's Url_close () is a function pointer that points to a function that relates to a specific urlprotocol, here's a look at the urlprotocol of the file, as shown below.
Urlprotocol Ff_file_protocol = {    . name                = "File",    . Url_open            = File_open,    . Url_read            = File_ Read,    . Url_write           = File_write,    . Url_seek            = File_seek,    . Url_close           = File_close,    . Url_get_file_handle = File_get_handle,    . Url_check           = File_check,    . priv_data_size      = sizeof ( Filecontext),    . Priv_data_class     = &file_class,};

As can be seen from Ff_file_protocol, Url_close () points to the File_close () function. Let's take a look at the definition of File_close () as shown below.
static int file_close (Urlcontext *h) {    Filecontext *c = h->priv_data;    Return close (C->FD);}

Visible File_close () finally calls the system function close () Closes the file pointer (unfamiliar with close () can simply interpret it as fclose ()).

This avio_close () function analysis is complete.


Lei Huawei
[Email protected]
http://blog.csdn.net/leixiaohua1020

FFmpeg source code Simple analysis: Avformat_close_input ()

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.