Browse code

lavf/asfenc: add support for setting packet size

This can provide a manual workaround for ticket #4230.

Reviewed-by: Michael Niedermayer <michael@niedermayer.cc>
Signed-off-by: Marton Balint <cus@passwd.hu>

Marton Balint authored on 2016/02/04 09:30:31
Showing 4 changed files
... ...
@@ -37,6 +37,26 @@ ID3v2.3 and ID3v2.4) are supported. The default is version 4.
37 37
 
38 38
 @end table
39 39
 
40
+@anchor{asf}
41
+@section asf
42
+
43
+Advanced Systems Format muxer.
44
+
45
+Note that Windows Media Audio (wma) and Windows Media Video (wmv) use this
46
+muxer too.
47
+
48
+@subsection Options
49
+
50
+It accepts the following options:
51
+
52
+@table @option
53
+@item packet_size
54
+Set the muxer packet size. By tuning this setting you may reduce data
55
+fragmentation or muxer overhead depending on your source. Default value is
56
+3200, minimum is 100, maximum is 64k.
57
+
58
+@end table
59
+
40 60
 @anchor{chromaprint}
41 61
 @section chromaprint
42 62
 
... ...
@@ -26,8 +26,6 @@
26 26
 #include "metadata.h"
27 27
 #include "riff.h"
28 28
 
29
-#define PACKET_SIZE 3200
30
-
31 29
 typedef enum ASFDataType {
32 30
     ASF_UNICODE    = 0,
33 31
     ASF_BYTE_ARRAY = 1,
... ...
@@ -23,6 +23,7 @@
23 23
 #include "libavutil/dict.h"
24 24
 #include "libavutil/mathematics.h"
25 25
 #include "libavutil/parseutils.h"
26
+#include "libavutil/opt.h"
26 27
 #include "avformat.h"
27 28
 #include "avlanguage.h"
28 29
 #include "avio_internal.h"
... ...
@@ -172,19 +173,20 @@
172 172
      ASF_PAYLOAD_REPLICATED_DATA_LENGTH +                 \
173 173
      ASF_PAYLOAD_LENGTH_FIELD_SIZE)
174 174
 
175
-#define SINGLE_PAYLOAD_DATA_LENGTH                        \
176
-    (PACKET_SIZE -                                        \
177
-     PACKET_HEADER_MIN_SIZE -                             \
175
+#define SINGLE_PAYLOAD_HEADERS                            \
176
+    (PACKET_HEADER_MIN_SIZE +                             \
178 177
      PAYLOAD_HEADER_SIZE_SINGLE_PAYLOAD)
179 178
 
180
-#define MULTI_PAYLOAD_CONSTANT                            \
181
-    (PACKET_SIZE -                                        \
182
-     PACKET_HEADER_MIN_SIZE -                             \
183
-     1 -         /* Payload Flags */                      \
179
+#define MULTI_PAYLOAD_HEADERS                             \
180
+    (PACKET_HEADER_MIN_SIZE +                             \
181
+     1 +         /* Payload Flags */                      \
184 182
      2 * PAYLOAD_HEADER_SIZE_MULTIPLE_PAYLOADS)
185 183
 
186 184
 #define DATA_HEADER_SIZE 50
187 185
 
186
+#define PACKET_SIZE_MAX 65536
187
+#define PACKET_SIZE_MIN 100
188
+
188 189
 typedef struct ASFPayload {
189 190
     uint8_t type;
190 191
     uint16_t size;
... ...
@@ -234,7 +236,7 @@ typedef struct ASFContext {
234 234
     int64_t packet_timestamp_start;
235 235
     int64_t packet_timestamp_end;
236 236
     unsigned int packet_nb_payloads;
237
-    uint8_t packet_buf[PACKET_SIZE];
237
+    uint8_t packet_buf[PACKET_SIZE_MAX];
238 238
     AVIOContext pb;
239 239
     /* only for reading */
240 240
     uint64_t data_offset;                ///< beginning of the first data packet
... ...
@@ -247,6 +249,7 @@ typedef struct ASFContext {
247 247
     uint64_t next_packet_offset;
248 248
     int      next_start_sec;
249 249
     int      end_sec;
250
+    int      packet_size;
250 251
 } ASFContext;
251 252
 
252 253
 static const AVCodecTag codec_asf_bmp_tags[] = {
... ...
@@ -755,7 +758,7 @@ static int asf_write_header(AVFormatContext *s)
755 755
 {
756 756
     ASFContext *asf = s->priv_data;
757 757
 
758
-    s->packet_size  = PACKET_SIZE;
758
+    s->packet_size  = asf->packet_size;
759 759
     s->max_interleave_delta = 0;
760 760
     asf->nb_packets = 0;
761 761
 
... ...
@@ -866,7 +869,7 @@ static void flush_packet(AVFormatContext *s)
866 866
                                                asf->packet_nb_payloads,
867 867
                                                asf->packet_size_left);
868 868
 
869
-    packet_filled_size = PACKET_SIZE - asf->packet_size_left;
869
+    packet_filled_size = asf->packet_size - asf->packet_size_left;
870 870
     av_assert0(packet_hdr_size <= asf->packet_size_left);
871 871
     memset(asf->packet_buf + packet_filled_size, 0, asf->packet_size_left);
872 872
 
... ...
@@ -923,13 +926,14 @@ static void put_frame(AVFormatContext *s, ASFStream *stream, AVStream *avst,
923 923
     while (m_obj_offset < m_obj_size) {
924 924
         payload_len = m_obj_size - m_obj_offset;
925 925
         if (asf->packet_timestamp_start == -1) {
926
-            asf->multi_payloads_present = (payload_len < MULTI_PAYLOAD_CONSTANT);
926
+            const int multi_payload_constant = (asf->packet_size - MULTI_PAYLOAD_HEADERS);
927
+            asf->multi_payloads_present = (payload_len < multi_payload_constant);
927 928
 
928
-            asf->packet_size_left = PACKET_SIZE;
929
+            asf->packet_size_left = asf->packet_size;
929 930
             if (asf->multi_payloads_present) {
930
-                frag_len1 = MULTI_PAYLOAD_CONSTANT - 1;
931
+                frag_len1 = multi_payload_constant - 1;
931 932
             } else {
932
-                frag_len1 = SINGLE_PAYLOAD_DATA_LENGTH;
933
+                frag_len1 = asf->packet_size - SINGLE_PAYLOAD_HEADERS;
933 934
             }
934 935
             asf->packet_timestamp_start = timestamp;
935 936
         } else {
... ...
@@ -1124,11 +1128,16 @@ static int asf_write_trailer(AVFormatContext *s)
1124 1124
     return 0;
1125 1125
 }
1126 1126
 
1127
+static const AVOption asf_options[] = {
1128
+    { "packet_size", "Packet size", offsetof(ASFContext, packet_size), AV_OPT_TYPE_INT, {.i64 = 3200}, PACKET_SIZE_MIN, PACKET_SIZE_MAX, AV_OPT_FLAG_ENCODING_PARAM },
1129
+    { NULL },
1130
+};
1131
+
1127 1132
 #if CONFIG_ASF_MUXER
1128 1133
 static const AVClass asf_muxer_class = {
1129 1134
     .class_name     = "ASF muxer",
1130 1135
     .item_name      = av_default_item_name,
1131
-    .option         = 0,
1136
+    .option         = asf_options,
1132 1137
     .version        = LIBAVUTIL_VERSION_INT,
1133 1138
 };
1134 1139
 
... ...
@@ -1155,7 +1164,7 @@ AVOutputFormat ff_asf_muxer = {
1155 1155
 static const AVClass asf_stream_muxer_class = {
1156 1156
     .class_name     = "ASF stream muxer",
1157 1157
     .item_name      = av_default_item_name,
1158
-    .option         = 0,
1158
+    .option         = asf_options,
1159 1159
     .version        = LIBAVUTIL_VERSION_INT,
1160 1160
 };
1161 1161
 
... ...
@@ -31,7 +31,7 @@
31 31
 
32 32
 #define LIBAVFORMAT_VERSION_MAJOR  57
33 33
 #define LIBAVFORMAT_VERSION_MINOR  24
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, \