[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