2 * Copyright (c) 2010 Nicolas George
3 * Copyright (c) 2011 Stefano Sabatini
4 * Copyright (c) 2014 Andrey Utkin
6 * Permission is hereby granted, free of charge, to any person obtaining a copy
7 * of this software and associated documentation files (the "Software"), to deal
8 * in the Software without restriction, including without limitation the rights
9 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 * copies of the Software, and to permit persons to whom the Software is
11 * furnished to do so, subject to the following conditions:
13 * The above copyright notice and this permission notice shall be included in
14 * all copies or substantial portions of the Software.
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
27 * API example for demuxing, decoding, filtering, encoding and muxing
28 * @example transcoding.c
31 #include <libavcodec/avcodec.h>
32 #include <libavformat/avformat.h>
33 #include <libavfilter/avfiltergraph.h>
34 #include <libavfilter/avcodec.h>
35 #include <libavfilter/buffersink.h>
36 #include <libavfilter/buffersrc.h>
37 #include <libavutil/opt.h>
38 #include <libavutil/pixdesc.h>
40 static AVFormatContext
*ifmt_ctx
;
41 static AVFormatContext
*ofmt_ctx
;
42 typedef struct FilteringContext
{
43 AVFilterContext
*buffersink_ctx
;
44 AVFilterContext
*buffersrc_ctx
;
45 AVFilterGraph
*filter_graph
;
47 static FilteringContext
*filter_ctx
;
49 static int open_input_file(const char *filename
)
55 if ((ret
= avformat_open_input(&ifmt_ctx
, filename
, NULL
, NULL
)) < 0) {
56 av_log(NULL
, AV_LOG_ERROR
, "Cannot open input file\n");
60 if ((ret
= avformat_find_stream_info(ifmt_ctx
, NULL
)) < 0) {
61 av_log(NULL
, AV_LOG_ERROR
, "Cannot find stream information\n");
65 for (i
= 0; i
< ifmt_ctx
->nb_streams
; i
++) {
67 AVCodecContext
*codec_ctx
;
68 stream
= ifmt_ctx
->streams
[i
];
69 codec_ctx
= stream
->codec
;
70 /* Reencode video & audio and remux subtitles etc. */
71 if (codec_ctx
->codec_type
== AVMEDIA_TYPE_VIDEO
72 || codec_ctx
->codec_type
== AVMEDIA_TYPE_AUDIO
) {
74 ret
= avcodec_open2(codec_ctx
,
75 avcodec_find_decoder(codec_ctx
->codec_id
), NULL
);
77 av_log(NULL
, AV_LOG_ERROR
, "Failed to open decoder for stream #%u\n", i
);
83 av_dump_format(ifmt_ctx
, 0, filename
, 0);
87 static int open_output_file(const char *filename
)
91 AVCodecContext
*dec_ctx
, *enc_ctx
;
97 avformat_alloc_output_context2(&ofmt_ctx
, NULL
, NULL
, filename
);
99 av_log(NULL
, AV_LOG_ERROR
, "Could not create output context\n");
100 return AVERROR_UNKNOWN
;
104 for (i
= 0; i
< ifmt_ctx
->nb_streams
; i
++) {
105 out_stream
= avformat_new_stream(ofmt_ctx
, NULL
);
107 av_log(NULL
, AV_LOG_ERROR
, "Failed allocating output stream\n");
108 return AVERROR_UNKNOWN
;
111 in_stream
= ifmt_ctx
->streams
[i
];
112 dec_ctx
= in_stream
->codec
;
113 enc_ctx
= out_stream
->codec
;
115 if (dec_ctx
->codec_type
== AVMEDIA_TYPE_VIDEO
116 || dec_ctx
->codec_type
== AVMEDIA_TYPE_AUDIO
) {
117 /* in this example, we choose transcoding to same codec */
118 encoder
= avcodec_find_encoder(dec_ctx
->codec_id
);
120 av_log(NULL
, AV_LOG_FATAL
, "Neccessary encoder not found\n");
121 return AVERROR_INVALIDDATA
;
124 /* In this example, we transcode to same properties (picture size,
125 * sample rate etc.). These properties can be changed for output
126 * streams easily using filters */
127 if (dec_ctx
->codec_type
== AVMEDIA_TYPE_VIDEO
) {
128 enc_ctx
->height
= dec_ctx
->height
;
129 enc_ctx
->width
= dec_ctx
->width
;
130 enc_ctx
->sample_aspect_ratio
= dec_ctx
->sample_aspect_ratio
;
131 /* take first format from list of supported formats */
132 enc_ctx
->pix_fmt
= encoder
->pix_fmts
[0];
133 /* video time_base can be set to whatever is handy and supported by encoder */
134 enc_ctx
->time_base
= dec_ctx
->time_base
;
136 enc_ctx
->sample_rate
= dec_ctx
->sample_rate
;
137 enc_ctx
->channel_layout
= dec_ctx
->channel_layout
;
138 enc_ctx
->channels
= av_get_channel_layout_nb_channels(enc_ctx
->channel_layout
);
139 /* take first format from list of supported formats */
140 enc_ctx
->sample_fmt
= encoder
->sample_fmts
[0];
141 enc_ctx
->time_base
= (AVRational
){1, enc_ctx
->sample_rate
};
144 /* Third parameter can be used to pass settings to encoder */
145 ret
= avcodec_open2(enc_ctx
, encoder
, NULL
);
147 av_log(NULL
, AV_LOG_ERROR
, "Cannot open video encoder for stream #%u\n", i
);
150 } else if (dec_ctx
->codec_type
== AVMEDIA_TYPE_UNKNOWN
) {
151 av_log(NULL
, AV_LOG_FATAL
, "Elementary stream #%d is of unknown type, cannot proceed\n", i
);
152 return AVERROR_INVALIDDATA
;
154 /* if this stream must be remuxed */
155 ret
= avcodec_copy_context(ofmt_ctx
->streams
[i
]->codec
,
156 ifmt_ctx
->streams
[i
]->codec
);
158 av_log(NULL
, AV_LOG_ERROR
, "Copying stream context failed\n");
163 if (ofmt_ctx
->oformat
->flags
& AVFMT_GLOBALHEADER
)
164 enc_ctx
->flags
|= CODEC_FLAG_GLOBAL_HEADER
;
167 av_dump_format(ofmt_ctx
, 0, filename
, 1);
169 if (!(ofmt_ctx
->oformat
->flags
& AVFMT_NOFILE
)) {
170 ret
= avio_open(&ofmt_ctx
->pb
, filename
, AVIO_FLAG_WRITE
);
172 av_log(NULL
, AV_LOG_ERROR
, "Could not open output file '%s'", filename
);
177 /* init muxer, write output file header */
178 ret
= avformat_write_header(ofmt_ctx
, NULL
);
180 av_log(NULL
, AV_LOG_ERROR
, "Error occurred when opening output file\n");
187 static int init_filter(FilteringContext
* fctx
, AVCodecContext
*dec_ctx
,
188 AVCodecContext
*enc_ctx
, const char *filter_spec
)
192 AVFilter
*buffersrc
= NULL
;
193 AVFilter
*buffersink
= NULL
;
194 AVFilterContext
*buffersrc_ctx
= NULL
;
195 AVFilterContext
*buffersink_ctx
= NULL
;
196 AVFilterInOut
*outputs
= avfilter_inout_alloc();
197 AVFilterInOut
*inputs
= avfilter_inout_alloc();
198 AVFilterGraph
*filter_graph
= avfilter_graph_alloc();
200 if (!outputs
|| !inputs
|| !filter_graph
) {
201 ret
= AVERROR(ENOMEM
);
205 if (dec_ctx
->codec_type
== AVMEDIA_TYPE_VIDEO
) {
206 buffersrc
= avfilter_get_by_name("buffer");
207 buffersink
= avfilter_get_by_name("buffersink");
208 if (!buffersrc
|| !buffersink
) {
209 av_log(NULL
, AV_LOG_ERROR
, "filtering source or sink element not found\n");
210 ret
= AVERROR_UNKNOWN
;
214 snprintf(args
, sizeof(args
),
215 "video_size=%dx%d:pix_fmt=%d:time_base=%d/%d:pixel_aspect=%d/%d",
216 dec_ctx
->width
, dec_ctx
->height
, dec_ctx
->pix_fmt
,
217 dec_ctx
->time_base
.num
, dec_ctx
->time_base
.den
,
218 dec_ctx
->sample_aspect_ratio
.num
,
219 dec_ctx
->sample_aspect_ratio
.den
);
221 ret
= avfilter_graph_create_filter(&buffersrc_ctx
, buffersrc
, "in",
222 args
, NULL
, filter_graph
);
224 av_log(NULL
, AV_LOG_ERROR
, "Cannot create buffer source\n");
228 ret
= avfilter_graph_create_filter(&buffersink_ctx
, buffersink
, "out",
229 NULL
, NULL
, filter_graph
);
231 av_log(NULL
, AV_LOG_ERROR
, "Cannot create buffer sink\n");
235 ret
= av_opt_set_bin(buffersink_ctx
, "pix_fmts",
236 (uint8_t*)&enc_ctx
->pix_fmt
, sizeof(enc_ctx
->pix_fmt
),
237 AV_OPT_SEARCH_CHILDREN
);
239 av_log(NULL
, AV_LOG_ERROR
, "Cannot set output pixel format\n");
242 } else if (dec_ctx
->codec_type
== AVMEDIA_TYPE_AUDIO
) {
243 buffersrc
= avfilter_get_by_name("abuffer");
244 buffersink
= avfilter_get_by_name("abuffersink");
245 if (!buffersrc
|| !buffersink
) {
246 av_log(NULL
, AV_LOG_ERROR
, "filtering source or sink element not found\n");
247 ret
= AVERROR_UNKNOWN
;
251 if (!dec_ctx
->channel_layout
)
252 dec_ctx
->channel_layout
=
253 av_get_default_channel_layout(dec_ctx
->channels
);
254 snprintf(args
, sizeof(args
),
255 "time_base=%d/%d:sample_rate=%d:sample_fmt=%s:channel_layout=0x%"PRIx64
,
256 dec_ctx
->time_base
.num
, dec_ctx
->time_base
.den
, dec_ctx
->sample_rate
,
257 av_get_sample_fmt_name(dec_ctx
->sample_fmt
),
258 dec_ctx
->channel_layout
);
259 ret
= avfilter_graph_create_filter(&buffersrc_ctx
, buffersrc
, "in",
260 args
, NULL
, filter_graph
);
262 av_log(NULL
, AV_LOG_ERROR
, "Cannot create audio buffer source\n");
266 ret
= avfilter_graph_create_filter(&buffersink_ctx
, buffersink
, "out",
267 NULL
, NULL
, filter_graph
);
269 av_log(NULL
, AV_LOG_ERROR
, "Cannot create audio buffer sink\n");
273 ret
= av_opt_set_bin(buffersink_ctx
, "sample_fmts",
274 (uint8_t*)&enc_ctx
->sample_fmt
, sizeof(enc_ctx
->sample_fmt
),
275 AV_OPT_SEARCH_CHILDREN
);
277 av_log(NULL
, AV_LOG_ERROR
, "Cannot set output sample format\n");
281 ret
= av_opt_set_bin(buffersink_ctx
, "channel_layouts",
282 (uint8_t*)&enc_ctx
->channel_layout
,
283 sizeof(enc_ctx
->channel_layout
), AV_OPT_SEARCH_CHILDREN
);
285 av_log(NULL
, AV_LOG_ERROR
, "Cannot set output channel layout\n");
289 ret
= av_opt_set_bin(buffersink_ctx
, "sample_rates",
290 (uint8_t*)&enc_ctx
->sample_rate
, sizeof(enc_ctx
->sample_rate
),
291 AV_OPT_SEARCH_CHILDREN
);
293 av_log(NULL
, AV_LOG_ERROR
, "Cannot set output sample rate\n");
297 ret
= AVERROR_UNKNOWN
;
301 /* Endpoints for the filter graph. */
302 outputs
->name
= av_strdup("in");
303 outputs
->filter_ctx
= buffersrc_ctx
;
304 outputs
->pad_idx
= 0;
305 outputs
->next
= NULL
;
307 inputs
->name
= av_strdup("out");
308 inputs
->filter_ctx
= buffersink_ctx
;
312 if (!outputs
->name
|| !inputs
->name
) {
313 ret
= AVERROR(ENOMEM
);
317 if ((ret
= avfilter_graph_parse_ptr(filter_graph
, filter_spec
,
318 &inputs
, &outputs
, NULL
)) < 0)
321 if ((ret
= avfilter_graph_config(filter_graph
, NULL
)) < 0)
324 /* Fill FilteringContext */
325 fctx
->buffersrc_ctx
= buffersrc_ctx
;
326 fctx
->buffersink_ctx
= buffersink_ctx
;
327 fctx
->filter_graph
= filter_graph
;
330 avfilter_inout_free(&inputs
);
331 avfilter_inout_free(&outputs
);
336 static int init_filters(void)
338 const char *filter_spec
;
341 filter_ctx
= av_malloc_array(ifmt_ctx
->nb_streams
, sizeof(*filter_ctx
));
343 return AVERROR(ENOMEM
);
345 for (i
= 0; i
< ifmt_ctx
->nb_streams
; i
++) {
346 filter_ctx
[i
].buffersrc_ctx
= NULL
;
347 filter_ctx
[i
].buffersink_ctx
= NULL
;
348 filter_ctx
[i
].filter_graph
= NULL
;
349 if (!(ifmt_ctx
->streams
[i
]->codec
->codec_type
== AVMEDIA_TYPE_AUDIO
350 || ifmt_ctx
->streams
[i
]->codec
->codec_type
== AVMEDIA_TYPE_VIDEO
))
354 if (ifmt_ctx
->streams
[i
]->codec
->codec_type
== AVMEDIA_TYPE_VIDEO
)
355 filter_spec
= "null"; /* passthrough (dummy) filter for video */
357 filter_spec
= "anull"; /* passthrough (dummy) filter for audio */
358 ret
= init_filter(&filter_ctx
[i
], ifmt_ctx
->streams
[i
]->codec
,
359 ofmt_ctx
->streams
[i
]->codec
, filter_spec
);
366 static int encode_write_frame(AVFrame
*filt_frame
, unsigned int stream_index
, int *got_frame
) {
370 int (*enc_func
)(AVCodecContext
*, AVPacket
*, const AVFrame
*, int *) =
371 (ifmt_ctx
->streams
[stream_index
]->codec
->codec_type
==
372 AVMEDIA_TYPE_VIDEO
) ? avcodec_encode_video2
: avcodec_encode_audio2
;
375 got_frame
= &got_frame_local
;
377 av_log(NULL
, AV_LOG_INFO
, "Encoding frame\n");
378 /* encode filtered frame */
381 av_init_packet(&enc_pkt
);
382 ret
= enc_func(ofmt_ctx
->streams
[stream_index
]->codec
, &enc_pkt
,
383 filt_frame
, got_frame
);
384 av_frame_free(&filt_frame
);
390 /* prepare packet for muxing */
391 enc_pkt
.stream_index
= stream_index
;
392 av_packet_rescale_ts(&enc_pkt
,
393 ofmt_ctx
->streams
[stream_index
]->codec
->time_base
,
394 ofmt_ctx
->streams
[stream_index
]->time_base
);
396 av_log(NULL
, AV_LOG_DEBUG
, "Muxing frame\n");
397 /* mux encoded frame */
398 ret
= av_interleaved_write_frame(ofmt_ctx
, &enc_pkt
);
402 static int filter_encode_write_frame(AVFrame
*frame
, unsigned int stream_index
)
407 av_log(NULL
, AV_LOG_INFO
, "Pushing decoded frame to filters\n");
408 /* push the decoded frame into the filtergraph */
409 ret
= av_buffersrc_add_frame_flags(filter_ctx
[stream_index
].buffersrc_ctx
,
412 av_log(NULL
, AV_LOG_ERROR
, "Error while feeding the filtergraph\n");
416 /* pull filtered frames from the filtergraph */
418 filt_frame
= av_frame_alloc();
420 ret
= AVERROR(ENOMEM
);
423 av_log(NULL
, AV_LOG_INFO
, "Pulling filtered frame from filters\n");
424 ret
= av_buffersink_get_frame(filter_ctx
[stream_index
].buffersink_ctx
,
427 /* if no more frames for output - returns AVERROR(EAGAIN)
428 * if flushed and no more frames for output - returns AVERROR_EOF
429 * rewrite retcode to 0 to show it as normal procedure completion
431 if (ret
== AVERROR(EAGAIN
) || ret
== AVERROR_EOF
)
433 av_frame_free(&filt_frame
);
437 filt_frame
->pict_type
= AV_PICTURE_TYPE_NONE
;
438 ret
= encode_write_frame(filt_frame
, stream_index
, NULL
);
446 static int flush_encoder(unsigned int stream_index
)
451 if (!(ofmt_ctx
->streams
[stream_index
]->codec
->codec
->capabilities
&
456 av_log(NULL
, AV_LOG_INFO
, "Flushing stream #%u encoder\n", stream_index
);
457 ret
= encode_write_frame(NULL
, stream_index
, &got_frame
);
466 int main(int argc
, char **argv
)
469 AVPacket packet
= { .data
= NULL
, .size
= 0 };
470 AVFrame
*frame
= NULL
;
471 enum AVMediaType type
;
472 unsigned int stream_index
;
475 int (*dec_func
)(AVCodecContext
*, AVFrame
*, int *, const AVPacket
*);
478 av_log(NULL
, AV_LOG_ERROR
, "Usage: %s <input file> <output file>\n", argv
[0]);
483 avfilter_register_all();
485 if ((ret
= open_input_file(argv
[1])) < 0)
487 if ((ret
= open_output_file(argv
[2])) < 0)
489 if ((ret
= init_filters()) < 0)
492 /* read all packets */
494 if ((ret
= av_read_frame(ifmt_ctx
, &packet
)) < 0)
496 stream_index
= packet
.stream_index
;
497 type
= ifmt_ctx
->streams
[packet
.stream_index
]->codec
->codec_type
;
498 av_log(NULL
, AV_LOG_DEBUG
, "Demuxer gave frame of stream_index %u\n",
501 if (filter_ctx
[stream_index
].filter_graph
) {
502 av_log(NULL
, AV_LOG_DEBUG
, "Going to reencode&filter the frame\n");
503 frame
= av_frame_alloc();
505 ret
= AVERROR(ENOMEM
);
508 av_packet_rescale_ts(&packet
,
509 ifmt_ctx
->streams
[stream_index
]->time_base
,
510 ifmt_ctx
->streams
[stream_index
]->codec
->time_base
);
511 dec_func
= (type
== AVMEDIA_TYPE_VIDEO
) ? avcodec_decode_video2
:
512 avcodec_decode_audio4
;
513 ret
= dec_func(ifmt_ctx
->streams
[stream_index
]->codec
, frame
,
514 &got_frame
, &packet
);
516 av_frame_free(&frame
);
517 av_log(NULL
, AV_LOG_ERROR
, "Decoding failed\n");
522 frame
->pts
= av_frame_get_best_effort_timestamp(frame
);
523 ret
= filter_encode_write_frame(frame
, stream_index
);
524 av_frame_free(&frame
);
528 av_frame_free(&frame
);
531 /* remux this frame without reencoding */
532 av_packet_rescale_ts(&packet
,
533 ifmt_ctx
->streams
[stream_index
]->time_base
,
534 ofmt_ctx
->streams
[stream_index
]->time_base
);
536 ret
= av_interleaved_write_frame(ofmt_ctx
, &packet
);
540 av_free_packet(&packet
);
543 /* flush filters and encoders */
544 for (i
= 0; i
< ifmt_ctx
->nb_streams
; i
++) {
546 if (!filter_ctx
[i
].filter_graph
)
548 ret
= filter_encode_write_frame(NULL
, i
);
550 av_log(NULL
, AV_LOG_ERROR
, "Flushing filter failed\n");
555 ret
= flush_encoder(i
);
557 av_log(NULL
, AV_LOG_ERROR
, "Flushing encoder failed\n");
562 av_write_trailer(ofmt_ctx
);
564 av_free_packet(&packet
);
565 av_frame_free(&frame
);
566 for (i
= 0; i
< ifmt_ctx
->nb_streams
; i
++) {
567 avcodec_close(ifmt_ctx
->streams
[i
]->codec
);
568 if (ofmt_ctx
&& ofmt_ctx
->nb_streams
> i
&& ofmt_ctx
->streams
[i
] && ofmt_ctx
->streams
[i
]->codec
)
569 avcodec_close(ofmt_ctx
->streams
[i
]->codec
);
570 if (filter_ctx
&& filter_ctx
[i
].filter_graph
)
571 avfilter_graph_free(&filter_ctx
[i
].filter_graph
);
574 avformat_close_input(&ifmt_ctx
);
575 if (ofmt_ctx
&& !(ofmt_ctx
->oformat
->flags
& AVFMT_NOFILE
))
576 avio_close(ofmt_ctx
->pb
);
577 avformat_free_context(ofmt_ctx
);
580 av_log(NULL
, AV_LOG_ERROR
, "Error occurred: %s\n", av_err2str(ret
));