ffmpeg.exe
The converter will end transcoding or encapsulation in the following three situations.
1, read to the end of the input file.
2.-t 60
The option is used on the input file on the command line , and only 60 seconds of input files are read for processing, and it will exit after processing 60 seconds of data.
3.-t 60
The option is used for the output file on the command line , and only 60 seconds of data is output to the file for saving. Once the storage is enough for 60 seconds, it will automatically exit.
The first case is the most common, the second and third cases are trim
achieved through filters.
This article mainly analyzes the logic of the first case , and readers are invited to explore the second and third cases by themselves.
The following API functions will use an error code of AVERROR_EOF to represent the end of the operation.
1, av_read_frame()
, AVERROR_EOF means that the end of the input file has been read.
2, avcodec_send_packet()
, it is also possible to return AVERROR_EOF when sending to the decoder , usually because you have sent == or == 0 AVPacket
to this decoder before . The second time you send a null or size equal to 0 to the decoder , the function will return AVERROR_EOFpkt
null
pkt.size
AVPacket
AVPacket
avcodec_send_packet()
3, avcodec_receive_frame()
, reading from the decoder AVFrame
may also return AVERROR_EOF, but the premise is that you have sent pkt
== null
or pkt.size
== 0 to this decoder before. After sending this null AVPacket
, keep reading the decoder until there is no data, it will return AVERROR_EOF. avcodec_receive_frame()
The function actually has two error codes, one is ERROR(EAGAIN)
and the other is AVERROR_EOF
, ERROR(EAGAIN)
which means that the decoder has no data to read temporarily, and you need to input more AVPacket
. AVERROR_EOF
, which means that the decoder has finished decoding, and there is no more AVPacket
input.
4, , reading av_buffersink_get_frame_flags()
from the exit filter may also return , but the premise is that all the entrance filters have been closed .buffersink
AVFrame
AVERROR_EOF
av_buffersrc_close()
5, avfilter_graph_request_oldest()
, this function is to return how much of the filter container AVFrame
has not been read, and it may return AVERROR_EOF
, provided that av_buffersrc_close()
all the entry filters have been closed , or the trim filter is used, it will automatically return at the time point AVERROR_EOF
6.avcodec_receive_packet()
Reading from the encoder AVPacket
may also return AVERROR_EOF, provided that you have sent null to this encoder before AVFrame
.
Let's take a look at ffmpeg.exe
how the converter uses the AVERROR_EOF return value of the above API functions.
The first is that av_read_frame()
the function returns AVERROR_EOF, which branch logic will be executed? as follows:
av_read_frame()
Functions are encapsulated get_input_packet()
within functions.
It may be seen that after reading to the end of the file, it will cause process_input_packet()
the function to pass in one NULL
by one AVPacket
.
Note: All input streams of the input file will be passed in one NULL
by one AVPacket
. As mentioned in
" decode_video decoding video frame ", the NULL will be converted process_input_packet()
to size = 0 AVPacket
decode_video()
size = 0
will AVPacket
cause the decoder to start flushing, as follows:
Also pay attention to the above avcodec_send_packet()
return value, although it will return AVERROR_EOF
, but ffmpeg.c
it does not handle this state, as follows:
//如果是 AVERROR_EOF 直接跳过。
if (ret < 0 && ret != AVERROR_EOF)
return ret;
When decode()
the function returns AVERROR_EOF
, what behavior will it lead to? as follows:
Because decode()
it is a public function, it is wrapped with the root, so decode_video()
the return value of the root will bedecode_audio()
decode_video()
decode_audio()
AVERROR_EOF
What happens if decode_video()
the function returns ? AVERROR_EOF
as follows:
It can be seen that it will lead eof_reached
to 1, and by the way break jumps out of while (ist->decoding_needed){...}
the decoding loop.
Then it will cause the calling send_filter_eof()
function to close all the entry filters bound to the stream, as follows:
This will then result in process_input_packet()
a return of 0, as follows:
But process_input_packet()
the return value of this, I personally think it is useless at all, even if it returns 1 in several places, it will turn into 0.
Although process_input_packet()
the return value of is useless, when it passes NULL, after execution, everything in the decoder AVFrame
has been spit out and sent to the filter for processing.
And it will be ifile->eof_reached
set to 1, as follows:
Therefore, the end process of the entire decoder is to return EOF , av_read_frame()
causing the decoder to spit out all the files AVFrame
, and after passing all the AVFrame
events to the filter, then close the entry filter, and then ifile->eof_reached
set it to 1, which means that the input file has been processed .
The whole process is as follows:
There is another important point in the above picture, that is, when ifile->eof_reached
it is set to 1, it will return immediately AVERROR(EAGAIN)
.
When process_input()
the function returns AVERROR(EAGAIN)
, this will result in transcode_step()
a non-execution
reap_filters()
, returns 0 directly. as follows:
Set to 1 when the input stream has been processed, the decoder has spit it out AVFrame
, and the ingress filter has been disabled.ifile->eof_reached
send_filter_eof()
Once the entrance filter is closed, av_buffersink_get_frame_flags()
or avfilter_graph_request_oldest()
there is a chance to return AVERROR_EOF
.
First look at av_buffersink_get_frame_flags()
the behavior of the function returning AVERROR_EOF, as follows:
av_buffersink_get_frame_flags()
is encapsulated reap_filters()
inside.
It can be seen av_buffersink_get_frame_flags()
that the function returning AVERROR_EOF will cause do_video_out()
NULL to be passed, but after actual debugging, it is found that this NULL will cause the encoder to be flushed, and it will not cause NULL to be passed AVPacket
to the encoder
Pass NULL AVPacket
to refresh the encoder, which will flush_encoders()
be done in the function.
Therefore, we don't need to pay attention toav_buffersink_get_frame_flags()
the behavior of the function returning AVERROR_EOF .
Supplement: do_video_out(of, ost, NULL);
It is not used to refresh the encoder, it should be used to refresh the remaining frames of the frame rate change , as follows:
//next_picture 等于 NULL
if (!next_picture) {
//end, flushing
nb0_frames = nb_frames = mid_pred(ost->last_nb0_frames[0],
ost->last_nb0_frames[1],
ost->last_nb0_frames[2]);
}
avfilter_graph_request_oldest()
AVERROR_EOF
However, special attention should be paid to the case of function return .
Because the entry filter was closed before, when the container has no data to read, avfilter_graph_request_oldest()
it will return
AVERROR_EOF
,as follows:
avfilter_graph_request_oldest()
returns AVERROR_EOF
, resulting in two behaviors.
1, reap_filter(1)
, the parameter is 1, so the remaining frames of the frame rate change will be flushed , but the encoder will not be flushed.
2,close_output_stream(graph->outputs[i]->ost)
, set finished
the state of the output stream.
ost->finished |= ENCODER_FINISHED;
This finished
state is particularly important.
In the previous flowchart, you can see that ffmpeg.exe
it will be executed in a loop transcode_step()
, as follows:
ffmpeg.exe
Under what circumstances will the converter jump out of the above while
cycle?
Answer: It is finished
judged by the state of the output stream, as follows:
At this point, the end processing logic of ffmpeg.exe has gone 80%, and has jumped out of while (!received_sigterm)
the loop.
However, the encoder has not been flushed at this time, do_video_out(of, ost, NULL);
and the encoder has not been flushed at this time.
The flushing of the encoder is while (!received_sigterm)
operated after jumping out of the loop , as follows:
flush_encoder()
The function is not too complicated, so I won't explain it.
At the end, there is still an av_write_trailer()
operation to write the tail information of the file, as follows:
There are also some operations to release various resources that will not be explained.
ffmpeg.exe
The conversion of the converter is completed and the analysis is completed.
Analysis of the end of transcoding of the original FFmpeg converter - Nuggets
★The business card at the end of the article can receive audio and video development learning materials for free, including (FFmpeg, webRTC, rtmp, hls, rtsp, ffplay, srs) and audio and video learning roadmaps, etc.
see below!