1 /*
2 * Copyright (c) 2012 Nicolas George
3 *
4 * This file is part of FFmpeg.
5 *
6 * FFmpeg is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public License
8 * as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
10 *
11 * FFmpeg is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public License
17 * along with FFmpeg; if not, write to the Free Software Foundation, Inc.,
18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19 */
20
29
34
39
47
48 typedef struct {
59
61 {
62 return memcmp(probe->
buf,
"ffconcat version 1.0", 20) ?
64 }
65
67 {
70 if (**cursor) {
71 *((*cursor)++) = 0;
73 }
75 }
76
78 {
79 const char *
start = f;
80
81 for (; *f; f++) {
82 /* A-Za-z0-9_- */
83 if (!((unsigned)((*f | 32) - 'a') < 26 ||
84 (unsigned)(*f - '0') < 10 || *f == '_' || *f == '-')) {
85 if (f == start)
86 return 0;
87 else if (*f == '/')
88 start = f + 1;
89 else if (*f != '.')
90 return 0;
91 }
92 }
93 return 1;
94 }
95
96 #define FAIL(retcode) do { ret = (retcode); goto fail; } while(0)
97
99 unsigned *nb_files_alloc)
100 {
103 char *url = NULL;
104 const char *proto;
105 size_t url_len, proto_len;
107
111 }
112
114 proto_len = proto ? strlen(proto) : 0;
115 if (!memcmp(filename, proto, proto_len) &&
116 (filename[proto_len] == ':' || filename[proto_len] == ',')) {
117 url = filename;
118 filename = NULL;
119 } else {
120 url_len = strlen(avf->
filename) + strlen(filename) + 16;
125 }
126
127 if (cat->
nb_files >= *nb_files_alloc) {
128 size_t n =
FFMAX(*nb_files_alloc * 2, 16);
130 if (n <= cat->nb_files || n > SIZE_MAX /
sizeof(*cat->
files) ||
133 cat->
files = new_files;
135 }
136
138 memset(file, 0, sizeof(*file));
139 *rfile = file;
140
144
145 return 0;
146
147 fail:
151 }
152
154 {
156
161 if (ret < 0)
163 }
166 return 0;
167 }
174 return 0;
175 }
176
178 {
183
187 "Auto-inserting h264_mp4toannexb bitstream filter\n");
190 "required for H.264 streams\n");
192 }
194 }
195 return 0;
196 }
197
199 {
203
207 } else {
210 }
214 }
215 return 0;
216 }
217
219 {
223
229 "Match slave stream #%d with stream #%d id 0x%x\n",
234 }
235 }
236 }
237 return 0;
238 }
239
241 {
245
247 return 0;
250 if (!map)
255
261 break;
264 break;
265 default:
267 }
268 if (ret < 0)
274 return 0;
275 }
276
278 {
282
285
289
296 }
304 return 0;
305 }
306
308 {
310 unsigned i;
311
314 for (i = 0; i < cat->
nb_files; i++) {
317 }
319 return 0;
320 }
321
323 {
328 unsigned nb_files_alloc = 0;
330 int64_t time = 0;
331
332 while (1) {
334 break;
335 line++;
338 if (!*keyword || *keyword == '#')
339 continue;
340
341 if (!strcmp(keyword, "file")) {
343 if (!filename) {
346 }
347 if ((ret =
add_file(avf, filename, &file, &nb_files_alloc)) < 0)
349 } else if (!strcmp(keyword, "duration")) {
351 int64_t dur;
352 if (!file) {
354 line);
356 }
359 line, dur_str);
361 }
363 } else if (!strcmp(keyword, "stream")) {
366 } else if (!strcmp(keyword, "exact_stream_id")) {
369 line);
371 }
374 } else if (!strcmp(keyword, "ffconcat")) {
377 if (strcmp(ver_kw, "version") || strcmp(ver_val, "1.0")) {
380 }
383 } else {
385 line, keyword);
387 }
388 }
389 if (ret < 0)
393
394 for (i = 0; i < cat->
nb_files; i++) {
397 else
400 break;
402 }
406 }
407
412 return 0;
413
414 fail:
417 }
418
420 {
423
426
430 }
431
433 {
438
440 for (bsf = cs->
bsf; bsf; bsf = bsf->
next) {
446 if (ret < 0) {
449 }
451 if (ret == 0 && pkt2.
data != pkt->
data) {
455 }
456 ret = 1;
457 }
458 if (ret > 0) {
465 }
466 }
467 *pkt = pkt2;
468 }
469 return 0;
470 }
471
473 {
478
479 while (1) {
484 continue;
485 }
486 if (ret < 0)
491 }
495 continue;
496 }
498 break;
499 }
502
511 }
512
514 int64_t *min_ts, int64_t *ts, int64_t *max_ts)
515 {
521 }
522
524 int64_t min_ts, int64_t ts, int64_t max_ts,
int flags)
525 {
528
530 min_ts = min_ts == INT64_MIN ? INT64_MIN : min_ts -
t0;
531 max_ts = max_ts == INT64_MAX ? INT64_MAX : max_ts -
t0;
532 if (stream >= 0) {
536 &min_ts, &ts, &max_ts);
537 }
539 }
540
542 int64_t min_ts, int64_t ts, int64_t max_ts,
int flags)
543 {
545 int ret, left, right;
546
547 if (stream >= 0) {
551 &min_ts, &ts, &max_ts);
552 }
553
554 left = 0;
556 while (right - left > 1) {
557 int mid = (left + right) / 2;
559 right = mid;
560 else
561 left = mid;
562 }
563
565 return ret;
566
567 ret =
try_seek(avf, stream, min_ts, ts, max_ts, flags);
568 if (ret < 0 &&
569 left < cat->nb_files - 1 &&
571 if ((ret =
open_file(avf, left + 1)) < 0)
573 ret =
try_seek(avf, stream, min_ts, ts, max_ts, flags);
574 }
576 }
577
579 int64_t min_ts, int64_t ts, int64_t max_ts,
int flags)
580 {
585
587 return AVERROR(ESPIPE);
/* XXX: can we use it? */
591 if ((ret =
real_seek(avf, stream, min_ts, ts, max_ts, flags)) < 0) {
594 cat->
avf = cur_avf_saved;
596 } else {
598 }
600 }
601
602 #define OFFSET(x) offsetof(ConcatContext, x)
603 #define DEC AV_OPT_FLAG_DECODING_PARAM
604
606 { "safe", "enable safe mode",
608 { "auto_convert", "automatically convert bitstream format",
610 { NULL }
611 };
612
618 };
619
620
630 .priv_class = &concat_class,
631 };