Merge remote-tracking branch 'qatar/master'
* qatar/master: movenc: Write chan atom for all audio tracks in mov mode movies. mpegtsenc: use avio_open_dyn_buf(), zero pointers after freeing doc/avconv: add some details about the transcoding process. avidec: make scale and rate unsigned. avconv: check output stream recording time before each frame returned from filters avconv: split selecting input file out of transcode(). avconv: split checking for active outputs out of transcode(). avfiltergraph: make some functions static. Conflicts: ffmpeg.c libavfilter/avfiltergraph.c libavfilter/internal.h libavformat/mpegtsenc.c tests/ref/fate/acodec-alac tests/ref/fate/acodec-pcm-s16be tests/ref/fate/acodec-pcm-s24be tests/ref/fate/acodec-pcm-s32be tests/ref/fate/acodec-pcm-s8 tests/ref/lavf/mov Merged-by: Michael Niedermayer <michaelni@gmx.at>
This commit is contained in:
		
						commit
						944d049eaa
					
				
							
								
								
									
										120
									
								
								doc/ffmpeg.texi
									
									
									
									
									
								
							
							
						
						
									
										120
									
								
								doc/ffmpeg.texi
									
									
									
									
									
								
							@ -79,6 +79,126 @@ The format option may be needed for raw input files.
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
@c man end DESCRIPTION
 | 
					@c man end DESCRIPTION
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					@chapter Detailed description
 | 
				
			||||||
 | 
					@c man begin DETAILED DESCRIPTION
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					The transcoding process in @command{ffmpeg} for each output can be described by
 | 
				
			||||||
 | 
					the following diagram:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					@example
 | 
				
			||||||
 | 
					 _______              ______________               _________              ______________            ________
 | 
				
			||||||
 | 
					|       |            |              |             |         |            |              |          |        |
 | 
				
			||||||
 | 
					| input |  demuxer   | encoded data |   decoder   | decoded |  encoder   | encoded data |  muxer   | output |
 | 
				
			||||||
 | 
					| file  | ---------> | packets      |  ---------> | frames  | ---------> | packets      | -------> | file   |
 | 
				
			||||||
 | 
					|_______|            |______________|             |_________|            |______________|          |________|
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					@end example
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					@command{ffmpeg} calls the libavformat library (containing demuxers) to read
 | 
				
			||||||
 | 
					input files and get packets containing encoded data from them. When there are
 | 
				
			||||||
 | 
					multiple input files, @command{ffmpeg} tries to keep them synchronized by
 | 
				
			||||||
 | 
					tracking lowest timestamp on any active input stream.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Encoded packets are then passed to the decoder (unless streamcopy is selected
 | 
				
			||||||
 | 
					for the stream, see further for a description). The decoder produces
 | 
				
			||||||
 | 
					uncompressed frames (raw video/PCM audio/...) which can be processed further by
 | 
				
			||||||
 | 
					filtering (see next section). After filtering the frames are passed to the
 | 
				
			||||||
 | 
					encoder, which encodes them and outputs encoded packets again. Finally those are
 | 
				
			||||||
 | 
					passed to the muxer, which writes the encoded packets to the output file.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					@section Filtering
 | 
				
			||||||
 | 
					Before encoding, @command{ffmpeg} can process raw audio and video frames using
 | 
				
			||||||
 | 
					filters from the libavfilter library. Several chained filters form a filter
 | 
				
			||||||
 | 
					graph.  @command{ffmpeg} distinguishes between two types of filtergraphs -
 | 
				
			||||||
 | 
					simple and complex.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					@subsection Simple filtergraphs
 | 
				
			||||||
 | 
					Simple filtergraphs are those that have exactly one input and output, both of
 | 
				
			||||||
 | 
					the same type. In the above diagram they can be represented by simply inserting
 | 
				
			||||||
 | 
					an additional step between decoding and encoding:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					@example
 | 
				
			||||||
 | 
					 _________                        __________              ______________
 | 
				
			||||||
 | 
					|         |                      |          |            |              |
 | 
				
			||||||
 | 
					| decoded |  simple filtergraph  | filtered |  encoder   | encoded data |
 | 
				
			||||||
 | 
					| frames  | -------------------> | frames   | ---------> | packets      |
 | 
				
			||||||
 | 
					|_________|                      |__________|            |______________|
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					@end example
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Simple filtergraphs are configured with the per-stream @option{-filter} option
 | 
				
			||||||
 | 
					(with @option{-vf} and @option{-af} aliases for video and audio respectively).
 | 
				
			||||||
 | 
					A simple filtergraph for video can look for example like this:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					@example
 | 
				
			||||||
 | 
					 _______        _____________        _______        _____        ________
 | 
				
			||||||
 | 
					|       |      |             |      |       |      |     |      |        |
 | 
				
			||||||
 | 
					| input | ---> | deinterlace | ---> | scale | ---> | fps | ---> | output |
 | 
				
			||||||
 | 
					|_______|      |_____________|      |_______|      |_____|      |________|
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					@end example
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Note that some filters change frame properties but not frame contents. E.g. the
 | 
				
			||||||
 | 
					@code{fps} filter in the example above changes number of frames, but does not
 | 
				
			||||||
 | 
					touch the frame contents. Another example is the @code{setpts} filter, which
 | 
				
			||||||
 | 
					only sets timestamps and otherwise passes the frames unchanged.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					@subsection Complex filtergraphs
 | 
				
			||||||
 | 
					Complex filtergraphs are those which cannot be described as simply a linear
 | 
				
			||||||
 | 
					processing chain applied to one stream. This is the case e.g. when the graph has
 | 
				
			||||||
 | 
					more than one input and/or output, or when output stream type is different from
 | 
				
			||||||
 | 
					input. They can be represented with the following diagram:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					@example
 | 
				
			||||||
 | 
					 _________
 | 
				
			||||||
 | 
					|         |
 | 
				
			||||||
 | 
					| input 0 |\                    __________
 | 
				
			||||||
 | 
					|_________| \                  |          |
 | 
				
			||||||
 | 
					             \   _________    /| output 0 |
 | 
				
			||||||
 | 
					              \ |         |  / |__________|
 | 
				
			||||||
 | 
					 _________     \| complex | /
 | 
				
			||||||
 | 
					|         |     |         |/
 | 
				
			||||||
 | 
					| input 1 |---->| filter  |\
 | 
				
			||||||
 | 
					|_________|     |         | \   __________
 | 
				
			||||||
 | 
					               /| graph   |  \ |          |
 | 
				
			||||||
 | 
					              / |         |   \| output 1 |
 | 
				
			||||||
 | 
					 _________   /  |_________|    |__________|
 | 
				
			||||||
 | 
					|         | /
 | 
				
			||||||
 | 
					| input 2 |/
 | 
				
			||||||
 | 
					|_________|
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					@end example
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Complex filtergraphs are configured with the @option{-filter_complex} option.
 | 
				
			||||||
 | 
					Note that this option is global, since a complex filtergraph by its nature
 | 
				
			||||||
 | 
					cannot be unambiguously associated with a single stream or file.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					A trivial example of a complex filtergraph is the @code{overlay} filter, which
 | 
				
			||||||
 | 
					has two video inputs and one video output, containing one video overlaid on top
 | 
				
			||||||
 | 
					of the other. Its audio counterpart is the @code{amix} filter.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					@section Stream copy
 | 
				
			||||||
 | 
					Stream copy is a mode selected by supplying the @code{copy} parameter to the
 | 
				
			||||||
 | 
					@option{-codec} option. It makes @command{ffmpeg} omit the decoding and encoding
 | 
				
			||||||
 | 
					step for the specified stream, so it does only demuxing and muxing. It is useful
 | 
				
			||||||
 | 
					for changing the container format or modifying container-level metadata. The
 | 
				
			||||||
 | 
					diagram above will in this case simplify to this:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					@example
 | 
				
			||||||
 | 
					 _______              ______________            ________
 | 
				
			||||||
 | 
					|       |            |              |          |        |
 | 
				
			||||||
 | 
					| input |  demuxer   | encoded data |  muxer   | output |
 | 
				
			||||||
 | 
					| file  | ---------> | packets      | -------> | file   |
 | 
				
			||||||
 | 
					|_______|            |______________|          |________|
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					@end example
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Since there is no decoding or encoding, it is very fast and there is no quality
 | 
				
			||||||
 | 
					loss. However it might not work in some cases because of many factors. Applying
 | 
				
			||||||
 | 
					filters is obviously also impossible, since filters work on uncompressed data.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					@c man end DETAILED DESCRIPTION
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@chapter Stream selection
 | 
					@chapter Stream selection
 | 
				
			||||||
@c man begin STREAM SELECTION
 | 
					@c man begin STREAM SELECTION
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										97
									
								
								ffmpeg.c
									
									
									
									
									
								
							
							
						
						
									
										97
									
								
								ffmpeg.c
									
									
									
									
									
								
							@ -2027,7 +2027,7 @@ static int poll_filters(void)
 | 
				
			|||||||
            OutputFile    *of = output_files[ost->file_index];
 | 
					            OutputFile    *of = output_files[ost->file_index];
 | 
				
			||||||
            int ret = 0;
 | 
					            int ret = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            if (!ost->filter || ost->is_past_recording_time)
 | 
					            if (!ost->filter)
 | 
				
			||||||
                continue;
 | 
					                continue;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            if (!ost->filtered_frame && !(ost->filtered_frame = avcodec_alloc_frame())) {
 | 
					            if (!ost->filtered_frame && !(ost->filtered_frame = avcodec_alloc_frame())) {
 | 
				
			||||||
@ -2036,7 +2036,7 @@ static int poll_filters(void)
 | 
				
			|||||||
                avcodec_get_frame_defaults(ost->filtered_frame);
 | 
					                avcodec_get_frame_defaults(ost->filtered_frame);
 | 
				
			||||||
            filtered_frame = ost->filtered_frame;
 | 
					            filtered_frame = ost->filtered_frame;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            while (1) {
 | 
					            while (!ost->is_past_recording_time) {
 | 
				
			||||||
                if (ost->enc->type == AVMEDIA_TYPE_AUDIO &&
 | 
					                if (ost->enc->type == AVMEDIA_TYPE_AUDIO &&
 | 
				
			||||||
                    !(ost->enc->capabilities & CODEC_CAP_VARIABLE_FRAME_SIZE))
 | 
					                    !(ost->enc->capabilities & CODEC_CAP_VARIABLE_FRAME_SIZE))
 | 
				
			||||||
                    ret = av_buffersink_read_samples(ost->filter->filter, &picref,
 | 
					                    ret = av_buffersink_read_samples(ost->filter->filter, &picref,
 | 
				
			||||||
@ -3307,6 +3307,57 @@ static int transcode_init(void)
 | 
				
			|||||||
    return 0;
 | 
					    return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @return 1 if there are still streams where more output is wanted,
 | 
				
			||||||
 | 
					 *         0 otherwise
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					static int need_output(void)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    int i;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    for (i = 0; i < nb_output_streams; i++) {
 | 
				
			||||||
 | 
					        OutputStream *ost    = output_streams[i];
 | 
				
			||||||
 | 
					        OutputFile *of       = output_files[ost->file_index];
 | 
				
			||||||
 | 
					        AVFormatContext *os  = output_files[ost->file_index]->ctx;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (ost->is_past_recording_time ||
 | 
				
			||||||
 | 
					            (os->pb && avio_tell(os->pb) >= of->limit_filesize))
 | 
				
			||||||
 | 
					            continue;
 | 
				
			||||||
 | 
					        if (ost->frame_number >= ost->max_frames) {
 | 
				
			||||||
 | 
					            int j;
 | 
				
			||||||
 | 
					            for (j = 0; j < of->ctx->nb_streams; j++)
 | 
				
			||||||
 | 
					                output_streams[of->ost_index + j]->is_past_recording_time = 1;
 | 
				
			||||||
 | 
					            continue;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return 1;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static int select_input_file(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;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (ist->discard || no_packet[ist->file_index])
 | 
				
			||||||
 | 
					            continue;
 | 
				
			||||||
 | 
					        if (!input_files[ist->file_index]->eof_reached) {
 | 
				
			||||||
 | 
					            if (ipts < ipts_min) {
 | 
				
			||||||
 | 
					                ipts_min = ipts;
 | 
				
			||||||
 | 
					                file_index = ist->file_index;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return file_index;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*
 | 
					/*
 | 
				
			||||||
 * The following code is the main loop of the file converter
 | 
					 * The following code is the main loop of the file converter
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
@ -3335,12 +3386,10 @@ static int transcode(void)
 | 
				
			|||||||
    timer_start = av_gettime();
 | 
					    timer_start = av_gettime();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    for (; received_sigterm == 0;) {
 | 
					    for (; received_sigterm == 0;) {
 | 
				
			||||||
        int file_index, ist_index, past_recording_time = 1;
 | 
					        int file_index, ist_index;
 | 
				
			||||||
        AVPacket pkt;
 | 
					        AVPacket pkt;
 | 
				
			||||||
        int64_t ipts_min;
 | 
					 | 
				
			||||||
        int64_t cur_time= av_gettime();
 | 
					        int64_t cur_time= av_gettime();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        ipts_min = INT64_MAX;
 | 
					 | 
				
			||||||
        /* if 'q' pressed, exits */
 | 
					        /* if 'q' pressed, exits */
 | 
				
			||||||
        if (!using_stdin) {
 | 
					        if (!using_stdin) {
 | 
				
			||||||
            static int64_t last_time;
 | 
					            static int64_t last_time;
 | 
				
			||||||
@ -3433,41 +3482,13 @@ static int transcode(void)
 | 
				
			|||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        /* check if there's any stream where output is still needed */
 | 
					        /* check if there's any stream where output is still needed */
 | 
				
			||||||
        for (i = 0; i < nb_output_streams; i++) {
 | 
					        if (!need_output()) {
 | 
				
			||||||
            OutputFile *of;
 | 
					            av_log(NULL, AV_LOG_VERBOSE, "No more output streams to write to, finishing.\n");
 | 
				
			||||||
            ost = output_streams[i];
 | 
					 | 
				
			||||||
            of  = output_files[ost->file_index];
 | 
					 | 
				
			||||||
            os  = output_files[ost->file_index]->ctx;
 | 
					 | 
				
			||||||
            if (ost->is_past_recording_time ||
 | 
					 | 
				
			||||||
                (os->pb && avio_tell(os->pb) >= of->limit_filesize))
 | 
					 | 
				
			||||||
                continue;
 | 
					 | 
				
			||||||
            if (ost->frame_number >= ost->max_frames) {
 | 
					 | 
				
			||||||
                int j;
 | 
					 | 
				
			||||||
                for (j = 0; j < of->ctx->nb_streams; j++)
 | 
					 | 
				
			||||||
                    output_streams[of->ost_index + j]->is_past_recording_time = 1;
 | 
					 | 
				
			||||||
                continue;
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
            past_recording_time = 0;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        if (past_recording_time)
 | 
					 | 
				
			||||||
            break;
 | 
					            break;
 | 
				
			||||||
 | 
					 | 
				
			||||||
        /* select the stream that we must read now by looking at the
 | 
					 | 
				
			||||||
           smallest output pts */
 | 
					 | 
				
			||||||
        file_index = -1;
 | 
					 | 
				
			||||||
        for (i = 0; i < nb_input_streams; i++) {
 | 
					 | 
				
			||||||
            int64_t ipts;
 | 
					 | 
				
			||||||
            ist = input_streams[i];
 | 
					 | 
				
			||||||
            ipts = ist->pts;
 | 
					 | 
				
			||||||
            if (ist->discard || no_packet[ist->file_index])
 | 
					 | 
				
			||||||
                continue;
 | 
					 | 
				
			||||||
            if (!input_files[ist->file_index]->eof_reached) {
 | 
					 | 
				
			||||||
                if (ipts < ipts_min) {
 | 
					 | 
				
			||||||
                    ipts_min = ipts;
 | 
					 | 
				
			||||||
                    file_index = ist->file_index;
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        /* select the stream that we must read now */
 | 
				
			||||||
 | 
					        file_index = select_input_file(no_packet);
 | 
				
			||||||
        /* if none, if is finished */
 | 
					        /* if none, if is finished */
 | 
				
			||||||
        if (file_index < 0) {
 | 
					        if (file_index < 0) {
 | 
				
			||||||
            if (no_packet_count) {
 | 
					            if (no_packet_count) {
 | 
				
			||||||
 | 
				
			|||||||
@ -102,7 +102,15 @@ void avfilter_graph_set_auto_convert(AVFilterGraph *graph, unsigned flags)
 | 
				
			|||||||
    graph->disable_auto_convert = flags;
 | 
					    graph->disable_auto_convert = flags;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int ff_avfilter_graph_check_validity(AVFilterGraph *graph, AVClass *log_ctx)
 | 
					/**
 | 
				
			||||||
 | 
					 * Check for the validity of graph.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * A graph is considered valid if all its input and output pads are
 | 
				
			||||||
 | 
					 * connected.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @return 0 in case of success, a negative value otherwise
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					static int graph_check_validity(AVFilterGraph *graph, AVClass *log_ctx)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    AVFilterContext *filt;
 | 
					    AVFilterContext *filt;
 | 
				
			||||||
    int i, j;
 | 
					    int i, j;
 | 
				
			||||||
@ -132,7 +140,12 @@ int ff_avfilter_graph_check_validity(AVFilterGraph *graph, AVClass *log_ctx)
 | 
				
			|||||||
    return 0;
 | 
					    return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int ff_avfilter_graph_config_links(AVFilterGraph *graph, AVClass *log_ctx)
 | 
					/**
 | 
				
			||||||
 | 
					 * Configure all the links of graphctx.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @return 0 in case of success, a negative value otherwise
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					static int graph_config_links(AVFilterGraph *graph, AVClass *log_ctx)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    AVFilterContext *filt;
 | 
					    AVFilterContext *filt;
 | 
				
			||||||
    int i, ret;
 | 
					    int i, ret;
 | 
				
			||||||
@ -688,7 +701,10 @@ static int pick_formats(AVFilterGraph *graph)
 | 
				
			|||||||
    return 0;
 | 
					    return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int ff_avfilter_graph_config_formats(AVFilterGraph *graph, AVClass *log_ctx)
 | 
					/**
 | 
				
			||||||
 | 
					 * Configure the formats of all the links in the graph.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					static int graph_config_formats(AVFilterGraph *graph, AVClass *log_ctx)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    int ret;
 | 
					    int ret;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -759,11 +775,11 @@ int avfilter_graph_config(AVFilterGraph *graphctx, void *log_ctx)
 | 
				
			|||||||
{
 | 
					{
 | 
				
			||||||
    int ret;
 | 
					    int ret;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if ((ret = ff_avfilter_graph_check_validity(graphctx, log_ctx)))
 | 
					    if ((ret = graph_check_validity(graphctx, log_ctx)))
 | 
				
			||||||
        return ret;
 | 
					        return ret;
 | 
				
			||||||
    if ((ret = ff_avfilter_graph_config_formats(graphctx, log_ctx)))
 | 
					    if ((ret = graph_config_formats(graphctx, log_ctx)))
 | 
				
			||||||
        return ret;
 | 
					        return ret;
 | 
				
			||||||
    if ((ret = ff_avfilter_graph_config_links(graphctx, log_ctx)))
 | 
					    if ((ret = graph_config_links(graphctx, log_ctx)))
 | 
				
			||||||
        return ret;
 | 
					        return ret;
 | 
				
			||||||
    if ((ret = ff_avfilter_graph_config_pointers(graphctx, log_ctx)))
 | 
					    if ((ret = ff_avfilter_graph_config_pointers(graphctx, log_ctx)))
 | 
				
			||||||
        return ret;
 | 
					        return ret;
 | 
				
			||||||
 | 
				
			|||||||
@ -44,28 +44,6 @@ typedef struct AVFilterCommand {
 | 
				
			|||||||
    struct AVFilterCommand *next;
 | 
					    struct AVFilterCommand *next;
 | 
				
			||||||
} AVFilterCommand;
 | 
					} AVFilterCommand;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * Check for the validity of graph.
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * A graph is considered valid if all its input and output pads are
 | 
					 | 
				
			||||||
 * connected.
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * @return 0 in case of success, a negative value otherwise
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
int ff_avfilter_graph_check_validity(AVFilterGraph *graphctx, AVClass *log_ctx);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * Configure all the links of graphctx.
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * @return 0 in case of success, a negative value otherwise
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
int ff_avfilter_graph_config_links(AVFilterGraph *graphctx, AVClass *log_ctx);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * Configure the formats of all the links in the graph.
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
int ff_avfilter_graph_config_formats(AVFilterGraph *graphctx, AVClass *log_ctx);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * Update the position of a link in the age heap.
 | 
					 * Update the position of a link in the age heap.
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
 | 
				
			|||||||
@ -40,8 +40,8 @@ typedef struct AVIStream {
 | 
				
			|||||||
    int remaining;
 | 
					    int remaining;
 | 
				
			||||||
    int packet_size;
 | 
					    int packet_size;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    int scale;
 | 
					    uint32_t scale;
 | 
				
			||||||
    int rate;
 | 
					    uint32_t rate;
 | 
				
			||||||
    int sample_size; /* size of one sample (or packet) (in the rate/scale sense) in bytes */
 | 
					    int sample_size; /* size of one sample (or packet) (in the rate/scale sense) in bytes */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    int64_t cum_len; /* temporary storage (used during seek) */
 | 
					    int64_t cum_len; /* temporary storage (used during seek) */
 | 
				
			||||||
 | 
				
			|||||||
@ -422,7 +422,6 @@ static int mov_write_wave_tag(AVIOContext *pb, MOVTrack *track)
 | 
				
			|||||||
    } else if (track->enc->codec_id == CODEC_ID_AMR_NB) {
 | 
					    } else if (track->enc->codec_id == CODEC_ID_AMR_NB) {
 | 
				
			||||||
        mov_write_amr_tag(pb, track);
 | 
					        mov_write_amr_tag(pb, track);
 | 
				
			||||||
    } else if (track->enc->codec_id == CODEC_ID_AC3) {
 | 
					    } else if (track->enc->codec_id == CODEC_ID_AC3) {
 | 
				
			||||||
        mov_write_chan_tag(pb, track);
 | 
					 | 
				
			||||||
        mov_write_ac3_tag(pb, track);
 | 
					        mov_write_ac3_tag(pb, track);
 | 
				
			||||||
    } else if (track->enc->codec_id == CODEC_ID_ALAC) {
 | 
					    } else if (track->enc->codec_id == CODEC_ID_ALAC) {
 | 
				
			||||||
        mov_write_extradata_tag(pb, track);
 | 
					        mov_write_extradata_tag(pb, track);
 | 
				
			||||||
@ -695,6 +694,9 @@ static int mov_write_audio_tag(AVIOContext *pb, MOVTrack *track)
 | 
				
			|||||||
    else if (track->vos_len > 0)
 | 
					    else if (track->vos_len > 0)
 | 
				
			||||||
        mov_write_glbl_tag(pb, track);
 | 
					        mov_write_glbl_tag(pb, track);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (track->mode == MODE_MOV && track->enc->codec_type == AVMEDIA_TYPE_AUDIO)
 | 
				
			||||||
 | 
					        mov_write_chan_tag(pb, track);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    return update_size(pb, pos);
 | 
					    return update_size(pb, pos);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -232,10 +232,6 @@ typedef struct MpegTSWriteStream {
 | 
				
			|||||||
    int64_t payload_dts;
 | 
					    int64_t payload_dts;
 | 
				
			||||||
    int payload_flags;
 | 
					    int payload_flags;
 | 
				
			||||||
    uint8_t *payload;
 | 
					    uint8_t *payload;
 | 
				
			||||||
 | 
					 | 
				
			||||||
    uint8_t *adata;
 | 
					 | 
				
			||||||
    int adata_pos;
 | 
					 | 
				
			||||||
    int adata_size;
 | 
					 | 
				
			||||||
    AVFormatContext *amux;
 | 
					    AVFormatContext *amux;
 | 
				
			||||||
} MpegTSWriteStream;
 | 
					} MpegTSWriteStream;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -503,19 +499,6 @@ static void section_write_packet(MpegTSSection *s, const uint8_t *packet)
 | 
				
			|||||||
    avio_write(ctx->pb, packet, TS_PACKET_SIZE);
 | 
					    avio_write(ctx->pb, packet, TS_PACKET_SIZE);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Write callback for audio packetizer */
 | 
					 | 
				
			||||||
static int mpegts_audio_write(void *opaque, uint8_t *buf, int size)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    MpegTSWriteStream *ts_st = (MpegTSWriteStream *)opaque;
 | 
					 | 
				
			||||||
    if (ts_st->adata_pos + (int64_t)size > ts_st->adata_size)
 | 
					 | 
				
			||||||
        return AVERROR(EIO);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    memcpy(ts_st->adata + ts_st->adata_pos, buf, size);
 | 
					 | 
				
			||||||
    ts_st->adata_pos += size;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    return 0;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static int mpegts_write_header(AVFormatContext *s)
 | 
					static int mpegts_write_header(AVFormatContext *s)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    MpegTSWrite *ts = s->priv_data;
 | 
					    MpegTSWrite *ts = s->priv_data;
 | 
				
			||||||
@ -616,25 +599,11 @@ static int mpegts_write_header(AVFormatContext *s)
 | 
				
			|||||||
            st->codec->extradata_size > 0)
 | 
					            st->codec->extradata_size > 0)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            AVStream *ast;
 | 
					            AVStream *ast;
 | 
				
			||||||
            uint8_t *buffer;
 | 
					 | 
				
			||||||
            int buffer_size = 32768;
 | 
					 | 
				
			||||||
            ts_st->amux = avformat_alloc_context();
 | 
					            ts_st->amux = avformat_alloc_context();
 | 
				
			||||||
            if (!ts_st->amux) {
 | 
					            if (!ts_st->amux) {
 | 
				
			||||||
                ret = AVERROR(ENOMEM);
 | 
					                ret = AVERROR(ENOMEM);
 | 
				
			||||||
                goto fail;
 | 
					                goto fail;
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            buffer = av_malloc(buffer_size);
 | 
					 | 
				
			||||||
            if (!buffer) {
 | 
					 | 
				
			||||||
                ret = AVERROR(ENOMEM);
 | 
					 | 
				
			||||||
                goto fail;
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
            ts_st->amux->pb = avio_alloc_context(buffer, buffer_size, AVIO_FLAG_WRITE,
 | 
					 | 
				
			||||||
                                                 ts_st, NULL, mpegts_audio_write, NULL);
 | 
					 | 
				
			||||||
            if (!ts_st->amux->pb) {
 | 
					 | 
				
			||||||
                av_free(buffer);
 | 
					 | 
				
			||||||
                ret = AVERROR(ENOMEM);
 | 
					 | 
				
			||||||
                goto fail;
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
            ts_st->amux->oformat = av_guess_format((ts->flags & MPEGTS_FLAG_AAC_LATM) ? "latm" : "adts", NULL, NULL);
 | 
					            ts_st->amux->oformat = av_guess_format((ts->flags & MPEGTS_FLAG_AAC_LATM) ? "latm" : "adts", NULL, NULL);
 | 
				
			||||||
            if (!ts_st->amux->oformat) {
 | 
					            if (!ts_st->amux->oformat) {
 | 
				
			||||||
                ret = AVERROR(EINVAL);
 | 
					                ret = AVERROR(EINVAL);
 | 
				
			||||||
@ -723,8 +692,6 @@ static int mpegts_write_header(AVFormatContext *s)
 | 
				
			|||||||
        if (ts_st) {
 | 
					        if (ts_st) {
 | 
				
			||||||
            av_freep(&ts_st->payload);
 | 
					            av_freep(&ts_st->payload);
 | 
				
			||||||
            if (ts_st->amux) {
 | 
					            if (ts_st->amux) {
 | 
				
			||||||
                av_freep(&ts_st->amux->pb->buffer);
 | 
					 | 
				
			||||||
                av_freep(&ts_st->amux->pb);
 | 
					 | 
				
			||||||
                avformat_free_context(ts_st->amux);
 | 
					                avformat_free_context(ts_st->amux);
 | 
				
			||||||
                ts_st->amux = NULL;
 | 
					                ts_st->amux = NULL;
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
@ -1130,24 +1097,20 @@ static int mpegts_write_packet_internal(AVFormatContext *s, AVPacket *pkt)
 | 
				
			|||||||
            av_init_packet(&pkt2);
 | 
					            av_init_packet(&pkt2);
 | 
				
			||||||
            pkt2.data = pkt->data;
 | 
					            pkt2.data = pkt->data;
 | 
				
			||||||
            pkt2.size = pkt->size;
 | 
					            pkt2.size = pkt->size;
 | 
				
			||||||
            ts_st->adata_size = 1024 + pkt->size;
 | 
					            ret = avio_open_dyn_buf(&ts_st->amux->pb);
 | 
				
			||||||
            ts_st->adata = data = av_malloc(ts_st->adata_size);
 | 
					            if (ret < 0)
 | 
				
			||||||
            ts_st->adata_pos = 0;
 | 
					 | 
				
			||||||
            if (!data)
 | 
					 | 
				
			||||||
                return AVERROR(ENOMEM);
 | 
					                return AVERROR(ENOMEM);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            ret = av_write_frame(ts_st->amux, &pkt2);
 | 
					            ret = av_write_frame(ts_st->amux, &pkt2);
 | 
				
			||||||
            if (ret < 0) {
 | 
					            if (ret < 0) {
 | 
				
			||||||
 | 
					                avio_close_dyn_buf(ts_st->amux->pb, &data);
 | 
				
			||||||
 | 
					                ts_st->amux->pb = NULL;
 | 
				
			||||||
                av_free(data);
 | 
					                av_free(data);
 | 
				
			||||||
                return ret;
 | 
					                return ret;
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            avio_flush(ts_st->amux->pb);
 | 
					            size = avio_close_dyn_buf(ts_st->amux->pb, &data);
 | 
				
			||||||
            if (ts_st->amux->pb->error < 0) {
 | 
					            ts_st->amux->pb = NULL;
 | 
				
			||||||
                av_free(data);
 | 
					            buf = data;
 | 
				
			||||||
                return ts_st->amux->pb->error;
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
            buf = ts_st->adata;
 | 
					 | 
				
			||||||
            size = ts_st->adata_pos;
 | 
					 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -1236,8 +1199,6 @@ static int mpegts_write_end(AVFormatContext *s)
 | 
				
			|||||||
        MpegTSWriteStream *ts_st = st->priv_data;
 | 
					        MpegTSWriteStream *ts_st = st->priv_data;
 | 
				
			||||||
        av_freep(&ts_st->payload);
 | 
					        av_freep(&ts_st->payload);
 | 
				
			||||||
        if (ts_st->amux) {
 | 
					        if (ts_st->amux) {
 | 
				
			||||||
            av_freep(&ts_st->amux->pb->buffer);
 | 
					 | 
				
			||||||
            av_freep(&ts_st->amux->pb);
 | 
					 | 
				
			||||||
            avformat_free_context(ts_st->amux);
 | 
					            avformat_free_context(ts_st->amux);
 | 
				
			||||||
            ts_st->amux = NULL;
 | 
					            ts_st->amux = NULL;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
				
			|||||||
@ -1,4 +1,4 @@
 | 
				
			|||||||
1e5266b204b33ab4608e368d309716cb *tests/data/fate/acodec-alac.mov
 | 
					f01f453dd13c4e88266409cddf2a7177 *tests/data/fate/acodec-alac.mov
 | 
				
			||||||
388994 tests/data/fate/acodec-alac.mov
 | 
					389018 tests/data/fate/acodec-alac.mov
 | 
				
			||||||
64151e4bcc2b717aa5a8454d424d6a1f *tests/data/fate/acodec-alac.out.wav
 | 
					64151e4bcc2b717aa5a8454d424d6a1f *tests/data/fate/acodec-alac.out.wav
 | 
				
			||||||
stddev:    0.00 PSNR:999.99 MAXDIFF:    0 bytes:  1058400/  1058400
 | 
					stddev:    0.00 PSNR:999.99 MAXDIFF:    0 bytes:  1058400/  1058400
 | 
				
			||||||
 | 
				
			|||||||
@ -1,4 +1,4 @@
 | 
				
			|||||||
a874f5c08b8d104a6bbf41b21454180d *tests/data/fate/acodec-pcm-s16be.mov
 | 
					8bffa66afe9e17366af11e77882518a0 *tests/data/fate/acodec-pcm-s16be.mov
 | 
				
			||||||
1059045 tests/data/fate/acodec-pcm-s16be.mov
 | 
					1059069 tests/data/fate/acodec-pcm-s16be.mov
 | 
				
			||||||
64151e4bcc2b717aa5a8454d424d6a1f *tests/data/fate/acodec-pcm-s16be.out.wav
 | 
					64151e4bcc2b717aa5a8454d424d6a1f *tests/data/fate/acodec-pcm-s16be.out.wav
 | 
				
			||||||
stddev:    0.00 PSNR:999.99 MAXDIFF:    0 bytes:  1058400/  1058400
 | 
					stddev:    0.00 PSNR:999.99 MAXDIFF:    0 bytes:  1058400/  1058400
 | 
				
			||||||
 | 
				
			|||||||
@ -1,4 +1,4 @@
 | 
				
			|||||||
833d4afd907139af7106a5642a9c23d3 *tests/data/fate/acodec-pcm-s24be.mov
 | 
					e3013cfce9b792acb9d572268012160d *tests/data/fate/acodec-pcm-s24be.mov
 | 
				
			||||||
1588245 tests/data/fate/acodec-pcm-s24be.mov
 | 
					1588269 tests/data/fate/acodec-pcm-s24be.mov
 | 
				
			||||||
64151e4bcc2b717aa5a8454d424d6a1f *tests/data/fate/acodec-pcm-s24be.out.wav
 | 
					64151e4bcc2b717aa5a8454d424d6a1f *tests/data/fate/acodec-pcm-s24be.out.wav
 | 
				
			||||||
stddev:    0.00 PSNR:999.99 MAXDIFF:    0 bytes:  1058400/  1058400
 | 
					stddev:    0.00 PSNR:999.99 MAXDIFF:    0 bytes:  1058400/  1058400
 | 
				
			||||||
 | 
				
			|||||||
@ -1,4 +1,4 @@
 | 
				
			|||||||
c02c96e37b321f2c978968e3a102c669 *tests/data/fate/acodec-pcm-s32be.mov
 | 
					f3ef00480e89c5c791e87b8af1cc167c *tests/data/fate/acodec-pcm-s32be.mov
 | 
				
			||||||
2117449 tests/data/fate/acodec-pcm-s32be.mov
 | 
					2117473 tests/data/fate/acodec-pcm-s32be.mov
 | 
				
			||||||
64151e4bcc2b717aa5a8454d424d6a1f *tests/data/fate/acodec-pcm-s32be.out.wav
 | 
					64151e4bcc2b717aa5a8454d424d6a1f *tests/data/fate/acodec-pcm-s32be.out.wav
 | 
				
			||||||
stddev:    0.00 PSNR:999.99 MAXDIFF:    0 bytes:  1058400/  1058400
 | 
					stddev:    0.00 PSNR:999.99 MAXDIFF:    0 bytes:  1058400/  1058400
 | 
				
			||||||
 | 
				
			|||||||
@ -1,4 +1,4 @@
 | 
				
			|||||||
111d465266385298fde83005402ac171 *tests/data/fate/acodec-pcm-s8.mov
 | 
					2c504a4e48c19ea1b0e1705893b771bf *tests/data/fate/acodec-pcm-s8.mov
 | 
				
			||||||
529829 tests/data/fate/acodec-pcm-s8.mov
 | 
					529853 tests/data/fate/acodec-pcm-s8.mov
 | 
				
			||||||
651d4eb8d98dfcdda96ae6c43d8f156b *tests/data/fate/acodec-pcm-s8.out.wav
 | 
					651d4eb8d98dfcdda96ae6c43d8f156b *tests/data/fate/acodec-pcm-s8.out.wav
 | 
				
			||||||
stddev:  147.89 PSNR: 52.93 MAXDIFF:  255 bytes:  1058400/  1058400
 | 
					stddev:  147.89 PSNR: 52.93 MAXDIFF:  255 bytes:  1058400/  1058400
 | 
				
			||||||
 | 
				
			|||||||
@ -1,12 +1,12 @@
 | 
				
			|||||||
83754d7142a7770ac374f75b729a9319 *./tests/data/lavf/lavf.mov
 | 
					484aeef3be3eb4deef05c83bdc2dd484 *./tests/data/lavf/lavf.mov
 | 
				
			||||||
367322 ./tests/data/lavf/lavf.mov
 | 
					367346 ./tests/data/lavf/lavf.mov
 | 
				
			||||||
./tests/data/lavf/lavf.mov CRC=0x2f6a9b26
 | 
					./tests/data/lavf/lavf.mov CRC=0x2f6a9b26
 | 
				
			||||||
9a0b239ff596da58debcf210dece3985 *./tests/data/lavf/lavf.mov
 | 
					305a68397e3cdb505704841fedcdc352 *./tests/data/lavf/lavf.mov
 | 
				
			||||||
357821 ./tests/data/lavf/lavf.mov
 | 
					357845 ./tests/data/lavf/lavf.mov
 | 
				
			||||||
./tests/data/lavf/lavf.mov CRC=0x2f6a9b26
 | 
					./tests/data/lavf/lavf.mov CRC=0x2f6a9b26
 | 
				
			||||||
cea874222a6d40b1761d75ea11ebe681 *./tests/data/lavf/lavf.mov
 | 
					6e047bce400f2c4a840f783dee1ae030 *./tests/data/lavf/lavf.mov
 | 
				
			||||||
367251 ./tests/data/lavf/lavf.mov
 | 
					367275 ./tests/data/lavf/lavf.mov
 | 
				
			||||||
./tests/data/lavf/lavf.mov CRC=0xab307eb9
 | 
					./tests/data/lavf/lavf.mov CRC=0xab307eb9
 | 
				
			||||||
9a0b239ff596da58debcf210dece3985 *./tests/data/lavf/lavf.mov
 | 
					305a68397e3cdb505704841fedcdc352 *./tests/data/lavf/lavf.mov
 | 
				
			||||||
357821 ./tests/data/lavf/lavf.mov
 | 
					357845 ./tests/data/lavf/lavf.mov
 | 
				
			||||||
./tests/data/lavf/lavf.mov CRC=0x2f6a9b26
 | 
					./tests/data/lavf/lavf.mov CRC=0x2f6a9b26
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user