Browse code

lavf/segment: add segment_format_options option

Stefano Sabatini authored on 2014/09/06 22:43:11
Showing 3 changed files
... ...
@@ -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, \