... | ... |
@@ -804,6 +804,11 @@ reference stream. The default value is @code{auto}. |
804 | 804 |
Override the inner container format, by default it is guessed by the filename |
805 | 805 |
extension. |
806 | 806 |
|
807 |
+@item segment_format_options @var{options_list} |
|
808 |
+Set output format options using a :-separated list of key=value |
|
809 |
+parameters. Values containing the @code{:} special character must be |
|
810 |
+escaped. |
|
811 |
+ |
|
807 | 812 |
@item segment_list @var{name} |
808 | 813 |
Generate also a listfile named @var{name}. If not specified no |
809 | 814 |
listfile is generated. |
... | ... |
@@ -959,6 +964,12 @@ ffmpeg -i in.mkv -codec copy -map 0 -f segment -segment_list out.list out%03d.nu |
959 | 959 |
@end example |
960 | 960 |
|
961 | 961 |
@item |
962 |
+Segment input and set output format options for the output segments: |
|
963 |
+@example |
|
964 |
+ffmpeg -i in.mkv -f segment -segment_time 10 -segment_format_options movflags=+faststart out%03d.mp4 |
|
965 |
+@end example |
|
966 |
+ |
|
967 |
+@item |
|
962 | 968 |
As the example above, but segment the input file according to the split |
963 | 969 |
points specified by the @var{segment_times} option: |
964 | 970 |
@example |
... | ... |
@@ -72,7 +72,9 @@ typedef struct { |
72 | 72 |
int segment_count; ///< number of segment files already written |
73 | 73 |
AVOutputFormat *oformat; |
74 | 74 |
AVFormatContext *avf; |
75 |
- char *format; ///< format to use for output segment files |
|
75 |
+ char *format; ///< format to use for output segment files |
|
76 |
+ char *format_options_str; ///< format options to use for output segment files |
|
77 |
+ AVDictionary *format_options; |
|
76 | 78 |
char *list; ///< filename for the segment list file |
77 | 79 |
int list_flags; ///< flags affecting list generation |
78 | 80 |
int list_size; ///< number of entries for the segment list file |
... | ... |
@@ -563,6 +565,7 @@ static int seg_write_header(AVFormatContext *s) |
563 | 563 |
{ |
564 | 564 |
SegmentContext *seg = s->priv_data; |
565 | 565 |
AVFormatContext *oc = NULL; |
566 |
+ AVDictionary *options = NULL; |
|
566 | 567 |
int ret; |
567 | 568 |
|
568 | 569 |
seg->segment_count = 0; |
... | ... |
@@ -594,6 +597,15 @@ static int seg_write_header(AVFormatContext *s) |
594 | 594 |
} |
595 | 595 |
} |
596 | 596 |
|
597 |
+ if (seg->format_options_str) { |
|
598 |
+ ret = av_dict_parse_string(&seg->format_options, seg->format_options_str, "=", ":", 0); |
|
599 |
+ if (ret < 0) { |
|
600 |
+ av_log(s, AV_LOG_ERROR, "Could not parse format options list '%s'\n", |
|
601 |
+ seg->format_options_str); |
|
602 |
+ goto fail; |
|
603 |
+ } |
|
604 |
+ } |
|
605 |
+ |
|
597 | 606 |
if (seg->list) { |
598 | 607 |
if (seg->list_type == LIST_TYPE_UNDEFINED) { |
599 | 608 |
if (av_match_ext(seg->list, "csv" )) seg->list_type = LIST_TYPE_CSV; |
... | ... |
@@ -645,7 +657,14 @@ static int seg_write_header(AVFormatContext *s) |
645 | 645 |
goto fail; |
646 | 646 |
} |
647 | 647 |
|
648 |
- if ((ret = avformat_write_header(oc, NULL)) < 0) { |
|
648 |
+ av_dict_copy(&options, seg->format_options, 0); |
|
649 |
+ ret = avformat_write_header(oc, &options); |
|
650 |
+ if (av_dict_count(options)) { |
|
651 |
+ av_log(s, AV_LOG_ERROR, |
|
652 |
+ "Some of the provided format options in '%s' are not recognized\n", seg->format_options_str); |
|
653 |
+ } |
|
654 |
+ av_dict_free(&options); |
|
655 |
+ if (ret < 0) { |
|
649 | 656 |
avio_close(oc->pb); |
650 | 657 |
goto fail; |
651 | 658 |
} |
... | ... |
@@ -799,6 +818,7 @@ fail: |
799 | 799 |
if (seg->list) |
800 | 800 |
avio_close(seg->list_pb); |
801 | 801 |
|
802 |
+ av_dict_free(&seg->format_options); |
|
802 | 803 |
av_opt_free(seg); |
803 | 804 |
av_freep(&seg->times); |
804 | 805 |
av_freep(&seg->frames); |
... | ... |
@@ -820,6 +840,7 @@ fail: |
820 | 820 |
static const AVOption options[] = { |
821 | 821 |
{ "reference_stream", "set reference stream", OFFSET(reference_stream_specifier), AV_OPT_TYPE_STRING, {.str = "auto"}, CHAR_MIN, CHAR_MAX, E }, |
822 | 822 |
{ "segment_format", "set container format used for the segments", OFFSET(format), AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, E }, |
823 |
+ { "segment_format_options", "set list of options for the container format used for the segments", OFFSET(format_options_str), AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, E }, |
|
823 | 824 |
{ "segment_list", "set the segment list filename", OFFSET(list), AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, E }, |
824 | 825 |
|
825 | 826 |
{ "segment_list_flags","set flags affecting segment list generation", OFFSET(list_flags), AV_OPT_TYPE_FLAGS, {.i64 = SEGMENT_LIST_FLAG_CACHE }, 0, UINT_MAX, E, "list_flags"}, |
... | ... |
@@ -31,7 +31,7 @@ |
31 | 31 |
|
32 | 32 |
#define LIBAVFORMAT_VERSION_MAJOR 56 |
33 | 33 |
#define LIBAVFORMAT_VERSION_MINOR 4 |
34 |
-#define LIBAVFORMAT_VERSION_MICRO 100 |
|
34 |
+#define LIBAVFORMAT_VERSION_MICRO 101 |
|
35 | 35 |
|
36 | 36 |
#define LIBAVFORMAT_VERSION_INT AV_VERSION_INT(LIBAVFORMAT_VERSION_MAJOR, \ |
37 | 37 |
LIBAVFORMAT_VERSION_MINOR, \ |