1 /*
2 * Copyright (c) 2010 Nicolas George
3 * Copyright (c) 2011 Stefano Sabatini
4 * Copyright (c) 2014 Andrey Utkin
5 *
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:
12 *
13 * The above copyright notice and this permission notice shall be included in
14 * all copies or substantial portions of the Software.
15 *
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
22 * THE SOFTWARE.
23 */
24
25 /**
26 * @file
27 * API example for demuxing, decoding, filtering, encoding and muxing
28 * @example transcoding.c
29 */
30
39
48
50 {
52 unsigned int i;
53
54 ifmt_ctx = NULL;
58 }
59
63 }
64
69 codec_ctx = stream->
codec;
70 /* Reencode video & audio and remux subtitles etc. */
73 /* Open decoder */
76 if (ret < 0) {
79 }
80 }
81 }
82
84 return 0;
85 }
86
88 {
94 unsigned int i;
95
96 ofmt_ctx = NULL;
98 if (!ofmt_ctx) {
101 }
102
103
106 if (!out_stream) {
109 }
110
111 in_stream = ifmt_ctx->
streams[i];
112 dec_ctx = in_stream->
codec;
113 enc_ctx = out_stream->
codec;
114
117 /* in this example, we choose transcoding to same codec */
119
120 /* In this example, we transcode to same properties (picture size,
121 * sample rate etc.). These properties can be changed for output
122 * streams easily using filters */
127 /* take first format from list of supported formats */
129 /* video time_base can be set to whatever is handy and supported by encoder */
131 } else {
135 /* take first format from list of supported formats */
138 }
139
140 /* Third parameter can be used to pass settings to encoder */
142 if (ret < 0) {
145 }
147 av_log(NULL,
AV_LOG_FATAL,
"Elementary stream #%d is of unknown type, cannot proceed\n", i);
149 } else {
150 /* if this stream must be remuxed */
153 if (ret < 0) {
156 }
157 }
158
161
162 }
164
167 if (ret < 0) {
170 }
171 }
172
173 /* init muxer, write output file header */
175 if (ret < 0) {
178 }
179
180 return 0;
181 }
182
185 {
195
196 if (!outputs || !inputs || !filter_graph) {
199 }
200
204 if (!buffersrc || !buffersink) {
208 }
209
211 "video_size=%dx%d:pix_fmt=%d:time_base=%d/%d:pixel_aspect=%d/%d",
216
218 args, NULL, filter_graph);
219 if (ret < 0) {
222 }
223
225 NULL, NULL, filter_graph);
226 if (ret < 0) {
229 }
230
234 if (ret < 0) {
237 }
241 if (!buffersrc || !buffersink) {
245 }
246
251 "time_base=%d/%d:sample_rate=%d:sample_fmt=%s:channel_layout=0x%"PRIx64,
256 args, NULL, filter_graph);
257 if (ret < 0) {
260 }
261
263 NULL, NULL, filter_graph);
264 if (ret < 0) {
267 }
268
272 if (ret < 0) {
275 }
276
280 if (ret < 0) {
283 }
284
288 if (ret < 0) {
291 }
292 } else {
295 }
296
297 /* Endpoints for the filter graph. */
301 outputs->
next = NULL;
302
307
308 if (!outputs->
name || !inputs->
name) {
311 }
312
314 &inputs, &outputs, NULL)) < 0)
316
319
320 /* Fill FilteringContext */
324
328
330 }
331
333 {
334 const char *filter_spec;
335 unsigned int i;
338 if (!filter_ctx)
340
347 continue;
348
349
351 filter_spec = "null"; /* passthrough (dummy) filter for video */
352 else
353 filter_spec = "anull"; /* passthrough (dummy) filter for audio */
356 if (ret)
358 }
359 return 0;
360 }
361
364 int got_frame_local;
369
370 if (!got_frame)
371 got_frame = &got_frame_local;
372
374 /* encode filtered frame */
378 ret = enc_func(ofmt_ctx->
streams[stream_index]->
codec, &enc_pkt,
379 filt_frame, got_frame);
381 if (ret < 0)
383 if (!(*got_frame))
384 return 0;
385
386 /* prepare packet for muxing */
399
401 /* mux encoded frame */
404 }
405
407 {
410
412 /* push the decoded frame into the filtergraph */
414 frame, 0);
415 if (ret < 0) {
418 }
419
420 /* pull filtered frames from the filtergraph */
421 while (1) {
423 if (!filt_frame) {
425 break;
426 }
429 filt_frame);
430 if (ret < 0) {
431 /* if no more frames for output - returns AVERROR(EAGAIN)
432 * if flushed and no more frames for output - returns AVERROR_EOF
433 * rewrite retcode to 0 to show it as normal procedure completion
434 */
436 ret = 0;
438 break;
439 }
440
443 if (ret < 0)
444 break;
445 }
446
448 }
449
451 {
453 int got_frame;
454
457 return 0;
458
459 while (1) {
462 if (ret < 0)
463 break;
464 if (!got_frame)
465 return 0;
466 }
468 }
469
470 int main(
int argc,
char **argv)
471 {
476 unsigned int stream_index;
477 unsigned int i;
478 int got_frame;
480
481 if (argc != 3) {
483 return 1;
484 }
485
488
495
496 /* read all packets */
497 while (1) {
499 break;
503 stream_index);
504
508 if (!frame) {
510 break;
511 }
522 ret = dec_func(ifmt_ctx->
streams[stream_index]->
codec, frame,
523 &got_frame, &packet);
524 if (ret < 0) {
527 break;
528 }
529
530 if (got_frame) {
534 if (ret < 0)
536 } else {
538 }
539 } else {
540 /* remux this frame without reencoding */
549
551 if (ret < 0)
553 }
555 }
556
557 /* flush filters and encoders */
559 /* flush filter */
561 continue;
563 if (ret < 0) {
566 }
567
568 /* flush encoder */
570 if (ret < 0) {
573 }
574 }
575
586 }
592
593 if (ret < 0)
595
596 return ret ? 1 : 0;
597 }