[FFmpeg-devel] [PATCH] ffmpeg: select input file based on output time.

Michael Niedermayer michaelni at gmx.at
Mon Jul 23 02:43:38 CEST 2012


On Sun, Jul 22, 2012 at 08:33:52PM +0200, Nicolas George wrote:
> Filters can change the timings, so input files must not
> necessarily be read at the same rythm. This patch select
> the input file to read based on the timestamp at output
> instead of input. With complex filter graphs, finding the
> input for a given output is done by making a request and
> checking to what buffer source it has been forwarded.
> 
> Signed-off-by: Nicolas George <nicolas.george at normalesup.org>
> ---
>  ffmpeg.c |   98 ++++++++++++++++++++++++++++++++++++++++++++++++++++----------
>  1 file changed, 83 insertions(+), 15 deletions(-)
> 
> 
> Without that, using the incoming concat filter with -filter_complex (rather
> than movie) will result in the second video to be decoded in memory while
> the first one is processed. Other similar problems can happel with other
> situation, even realistic ones (example: slowing down the video from a PAL
> DVD to merge it with the audio from the corresponding NTSC DVD).
> 
> 
> diff --git a/ffmpeg.c b/ffmpeg.c
> index 93e3f04..2f559c8 100644
> --- a/ffmpeg.c
> +++ b/ffmpeg.c
> @@ -3337,20 +3337,23 @@ static int need_output(void)
>      return 0;
>  }
>  
> -static int select_input_file(uint8_t *no_packet)
> +static int input_acceptable(InputStream *ist, uint8_t *no_packet)
>  {
> -    int64_t ipts_min = INT64_MAX;
> -    int i, file_index = -1;
> -
> -    for (i = 0; i < nb_input_streams; i++) {
> -        InputStream *ist = input_streams[i];
> -        int64_t ipts     = ist->pts;
> +    av_assert1(!ist->discard);
> +    return !no_packet[ist->file_index] &&
> +           !input_files[ist->file_index]->eof_reached;
> +}
>  
> -        if (ist->discard || no_packet[ist->file_index])
> -            continue;
> -        if (!input_files[ist->file_index]->eof_reached) {
> -            if (ipts < ipts_min) {
> -                ipts_min = ipts;
> +static int find_graph_input(FilterGraph *graph, uint8_t *no_packet)
> +{
> +    int i, nb_req_max = 0, file_index = -1;
> +
> +    for (i = 0; i < graph->nb_inputs; i++) {
> +        int nb_req = av_buffersrc_get_nb_failed_requests(graph->inputs[i]->filter);
> +        if (nb_req > nb_req_max) {
> +            InputStream *ist = graph->inputs[i]->ist;
> +            if (input_acceptable(ist, no_packet)) {
> +                nb_req_max = nb_req;
>                  file_index = ist->file_index;
>              }
>          }
> @@ -3359,6 +3362,65 @@ static int select_input_file(uint8_t *no_packet)
>      return file_index;
>  }
>  
> +/**
> + * Select the input file to read from.
> + *
> + * @param no_packet  array of booleans, one per input file;
> + *                   if set, the input file must not be considered
> + * @param no_frame   array of boolean, one per output stream;
> + *                   if set, the stream must not be considered;
> + *                   for internal use

the names of the 2 arguments are confusing
also why are they not members of InputFile & OutputStream ?

except these the code LGTM

[...]
-- 
Michael     GnuPG fingerprint: 9FF2128B147EF6730BADF133611EC787040B0FAB

Democracy is the form of government in which you can choose your dictator
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 198 bytes
Desc: Digital signature
URL: <http://ffmpeg.org/pipermail/ffmpeg-devel/attachments/20120723/81f563fa/attachment.asc>


More information about the ffmpeg-devel mailing list