• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * ASF muxer
3  * Copyright (c) 2000, 2001 Fabrice Bellard
4  *
5  * This file is part of FFmpeg.
6  *
7  * FFmpeg is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public
9  * License as published by the Free Software Foundation; either
10  * version 2.1 of the License, or (at your option) any later version.
11  *
12  * FFmpeg is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with FFmpeg; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20  */
21 
22 #include "config_components.h"
23 
24 #include "libavutil/avassert.h"
25 #include "libavutil/dict.h"
26 #include "libavutil/mathematics.h"
27 #include "libavutil/opt.h"
28 #include "avformat.h"
29 #include "avlanguage.h"
30 #include "avio_internal.h"
31 #include "internal.h"
32 #include "mux.h"
33 #include "riff.h"
34 #include "asf.h"
35 
36 #define ASF_INDEXED_INTERVAL    10000000
37 #define ASF_INDEX_BLOCK         (1<<9)
38 #define ASF_PAYLOADS_PER_PACKET 63
39 
40 #define ASF_PACKET_ERROR_CORRECTION_DATA_SIZE 0x2
41 #define ASF_PACKET_ERROR_CORRECTION_FLAGS          \
42     (ASF_PACKET_FLAG_ERROR_CORRECTION_PRESENT |    \
43      ASF_PACKET_ERROR_CORRECTION_DATA_SIZE)
44 
45 #if (ASF_PACKET_ERROR_CORRECTION_FLAGS != 0)
46 #   define ASF_PACKET_ERROR_CORRECTION_FLAGS_FIELD_SIZE 1
47 #else
48 #   define ASF_PACKET_ERROR_CORRECTION_FLAGS_FIELD_SIZE 0
49 #endif
50 
51 #define ASF_PPI_PROPERTY_FLAGS                                       \
52     (ASF_PL_FLAG_REPLICATED_DATA_LENGTH_FIELD_IS_BYTE           |    \
53      ASF_PL_FLAG_OFFSET_INTO_MEDIA_OBJECT_LENGTH_FIELD_IS_DWORD |    \
54      ASF_PL_FLAG_MEDIA_OBJECT_NUMBER_LENGTH_FIELD_IS_BYTE       |    \
55      ASF_PL_FLAG_STREAM_NUMBER_LENGTH_FIELD_IS_BYTE)
56 
57 #define ASF_PPI_LENGTH_TYPE_FLAGS 0
58 
59 #define ASF_PAYLOAD_FLAGS ASF_PL_FLAG_PAYLOAD_LENGTH_FIELD_IS_WORD
60 
61 #if (ASF_PPI_FLAG_SEQUENCE_FIELD_IS_BYTE == (ASF_PPI_LENGTH_TYPE_FLAGS & ASF_PPI_MASK_SEQUENCE_FIELD_SIZE))
62 #   define ASF_PPI_SEQUENCE_FIELD_SIZE 1
63 #endif
64 #if (ASF_PPI_FLAG_SEQUENCE_FIELD_IS_WORD == (ASF_PPI_LENGTH_TYPE_FLAGS & ASF_PPI_MASK_SEQUENCE_FIELD_SIZE))
65 #   define ASF_PPI_SEQUENCE_FIELD_SIZE 2
66 #endif
67 #if (ASF_PPI_FLAG_SEQUENCE_FIELD_IS_DWORD == (ASF_PPI_LENGTH_TYPE_FLAGS & ASF_PPI_MASK_SEQUENCE_FIELD_SIZE))
68 #   define ASF_PPI_SEQUENCE_FIELD_SIZE 4
69 #endif
70 #ifndef ASF_PPI_SEQUENCE_FIELD_SIZE
71 #   define ASF_PPI_SEQUENCE_FIELD_SIZE 0
72 #endif
73 
74 #if (ASF_PPI_FLAG_PACKET_LENGTH_FIELD_IS_BYTE == (ASF_PPI_LENGTH_TYPE_FLAGS & ASF_PPI_MASK_PACKET_LENGTH_FIELD_SIZE))
75 #   define ASF_PPI_PACKET_LENGTH_FIELD_SIZE 1
76 #endif
77 #if (ASF_PPI_FLAG_PACKET_LENGTH_FIELD_IS_WORD == (ASF_PPI_LENGTH_TYPE_FLAGS & ASF_PPI_MASK_PACKET_LENGTH_FIELD_SIZE))
78 #   define ASF_PPI_PACKET_LENGTH_FIELD_SIZE 2
79 #endif
80 #if (ASF_PPI_FLAG_PACKET_LENGTH_FIELD_IS_DWORD == (ASF_PPI_LENGTH_TYPE_FLAGS & ASF_PPI_MASK_PACKET_LENGTH_FIELD_SIZE))
81 #   define ASF_PPI_PACKET_LENGTH_FIELD_SIZE 4
82 #endif
83 #ifndef ASF_PPI_PACKET_LENGTH_FIELD_SIZE
84 #   define ASF_PPI_PACKET_LENGTH_FIELD_SIZE 0
85 #endif
86 
87 #if (ASF_PPI_FLAG_PADDING_LENGTH_FIELD_IS_BYTE == (ASF_PPI_LENGTH_TYPE_FLAGS & ASF_PPI_MASK_PADDING_LENGTH_FIELD_SIZE))
88 #   define ASF_PPI_PADDING_LENGTH_FIELD_SIZE 1
89 #endif
90 #if (ASF_PPI_FLAG_PADDING_LENGTH_FIELD_IS_WORD == (ASF_PPI_LENGTH_TYPE_FLAGS & ASF_PPI_MASK_PADDING_LENGTH_FIELD_SIZE))
91 #   define ASF_PPI_PADDING_LENGTH_FIELD_SIZE 2
92 #endif
93 #if (ASF_PPI_FLAG_PADDING_LENGTH_FIELD_IS_DWORD == (ASF_PPI_LENGTH_TYPE_FLAGS & ASF_PPI_MASK_PADDING_LENGTH_FIELD_SIZE))
94 #   define ASF_PPI_PADDING_LENGTH_FIELD_SIZE 4
95 #endif
96 #ifndef ASF_PPI_PADDING_LENGTH_FIELD_SIZE
97 #   define ASF_PPI_PADDING_LENGTH_FIELD_SIZE 0
98 #endif
99 
100 #if (ASF_PL_FLAG_REPLICATED_DATA_LENGTH_FIELD_IS_BYTE == (ASF_PPI_PROPERTY_FLAGS & ASF_PL_MASK_REPLICATED_DATA_LENGTH_FIELD_SIZE))
101 #   define ASF_PAYLOAD_REPLICATED_DATA_LENGTH_FIELD_SIZE 1
102 #endif
103 #if (ASF_PL_FLAG_REPLICATED_DATA_LENGTH_FIELD_IS_WORD == (ASF_PPI_PROPERTY_FLAGS & ASF_PL_MASK_REPLICATED_DATA_LENGTH_FIELD_SIZE))
104 #   define ASF_PAYLOAD_REPLICATED_DATA_LENGTH_FIELD_SIZE 2
105 #endif
106 #if (ASF_PL_FLAG_REPLICATED_DATA_LENGTH_FIELD_IS_DWORD == (ASF_PPI_PROPERTY_FLAGS & ASF_PL_MASK_REPLICATED_DATA_LENGTH_FIELD_SIZE))
107 #   define ASF_PAYLOAD_REPLICATED_DATA_LENGTH_FIELD_SIZE 4
108 #endif
109 #ifndef ASF_PAYLOAD_REPLICATED_DATA_LENGTH_FIELD_SIZE
110 #   define ASF_PAYLOAD_REPLICATED_DATA_LENGTH_FIELD_SIZE 0
111 #endif
112 
113 #if (ASF_PL_FLAG_OFFSET_INTO_MEDIA_OBJECT_LENGTH_FIELD_IS_BYTE == (ASF_PPI_PROPERTY_FLAGS & ASF_PL_MASK_OFFSET_INTO_MEDIA_OBJECT_LENGTH_FIELD_SIZE))
114 #   define ASF_PAYLOAD_OFFSET_INTO_MEDIA_OBJECT_FIELD_SIZE 1
115 #endif
116 #if (ASF_PL_FLAG_OFFSET_INTO_MEDIA_OBJECT_LENGTH_FIELD_IS_WORD == (ASF_PPI_PROPERTY_FLAGS & ASF_PL_MASK_OFFSET_INTO_MEDIA_OBJECT_LENGTH_FIELD_SIZE))
117 #   define ASF_PAYLOAD_OFFSET_INTO_MEDIA_OBJECT_FIELD_SIZE 2
118 #endif
119 #if (ASF_PL_FLAG_OFFSET_INTO_MEDIA_OBJECT_LENGTH_FIELD_IS_DWORD == (ASF_PPI_PROPERTY_FLAGS & ASF_PL_MASK_OFFSET_INTO_MEDIA_OBJECT_LENGTH_FIELD_SIZE))
120 #   define ASF_PAYLOAD_OFFSET_INTO_MEDIA_OBJECT_FIELD_SIZE 4
121 #endif
122 #ifndef ASF_PAYLOAD_OFFSET_INTO_MEDIA_OBJECT_FIELD_SIZE
123 #   define ASF_PAYLOAD_OFFSET_INTO_MEDIA_OBJECT_FIELD_SIZE 0
124 #endif
125 
126 #if (ASF_PL_FLAG_MEDIA_OBJECT_NUMBER_LENGTH_FIELD_IS_BYTE == (ASF_PPI_PROPERTY_FLAGS & ASF_PL_MASK_MEDIA_OBJECT_NUMBER_LENGTH_FIELD_SIZE))
127 #   define ASF_PAYLOAD_MEDIA_OBJECT_NUMBER_FIELD_SIZE 1
128 #endif
129 #if (ASF_PL_FLAG_MEDIA_OBJECT_NUMBER_LENGTH_FIELD_IS_WORD == (ASF_PPI_PROPERTY_FLAGS & ASF_PL_MASK_MEDIA_OBJECT_NUMBER_LENGTH_FIELD_SIZE))
130 #   define ASF_PAYLOAD_MEDIA_OBJECT_NUMBER_FIELD_SIZE 2
131 #endif
132 #if (ASF_PL_FLAG_MEDIA_OBJECT_NUMBER_LENGTH_FIELD_IS_DWORD == (ASF_PPI_PROPERTY_FLAGS & ASF_PL_MASK_MEDIA_OBJECT_NUMBER_LENGTH_FIELD_SIZE))
133 #   define ASF_PAYLOAD_MEDIA_OBJECT_NUMBER_FIELD_SIZE 4
134 #endif
135 #ifndef ASF_PAYLOAD_MEDIA_OBJECT_NUMBER_FIELD_SIZE
136 #   define ASF_PAYLOAD_MEDIA_OBJECT_NUMBER_FIELD_SIZE 0
137 #endif
138 
139 #if (ASF_PL_FLAG_PAYLOAD_LENGTH_FIELD_IS_BYTE == (ASF_PAYLOAD_FLAGS & ASF_PL_MASK_PAYLOAD_LENGTH_FIELD_SIZE))
140 #   define ASF_PAYLOAD_LENGTH_FIELD_SIZE 1
141 #endif
142 #if (ASF_PL_FLAG_PAYLOAD_LENGTH_FIELD_IS_WORD == (ASF_PAYLOAD_FLAGS & ASF_PL_MASK_PAYLOAD_LENGTH_FIELD_SIZE))
143 #   define ASF_PAYLOAD_LENGTH_FIELD_SIZE 2
144 #endif
145 #ifndef ASF_PAYLOAD_LENGTH_FIELD_SIZE
146 #   define ASF_PAYLOAD_LENGTH_FIELD_SIZE 0
147 #endif
148 
149 #define PACKET_HEADER_MIN_SIZE \
150     (ASF_PACKET_ERROR_CORRECTION_FLAGS_FIELD_SIZE +       \
151      ASF_PACKET_ERROR_CORRECTION_DATA_SIZE +              \
152      1 +        /* Length Type Flags */                   \
153      1 +        /* Property Flags */                      \
154      ASF_PPI_PACKET_LENGTH_FIELD_SIZE +                   \
155      ASF_PPI_SEQUENCE_FIELD_SIZE +                        \
156      ASF_PPI_PADDING_LENGTH_FIELD_SIZE +                  \
157      4 +        /* Send Time Field */                     \
158      2)         /* Duration Field */
159 
160 // Replicated Data shall be at least 8 bytes long.
161 #define ASF_PAYLOAD_REPLICATED_DATA_LENGTH 0x08
162 
163 #define PAYLOAD_HEADER_SIZE_SINGLE_PAYLOAD                \
164     (1 +     /* Stream Number */                          \
165      ASF_PAYLOAD_MEDIA_OBJECT_NUMBER_FIELD_SIZE +         \
166      ASF_PAYLOAD_OFFSET_INTO_MEDIA_OBJECT_FIELD_SIZE +    \
167      ASF_PAYLOAD_REPLICATED_DATA_LENGTH_FIELD_SIZE +      \
168      ASF_PAYLOAD_REPLICATED_DATA_LENGTH)
169 
170 #define PAYLOAD_HEADER_SIZE_MULTIPLE_PAYLOADS             \
171     (1 +        /* Stream Number */                       \
172      ASF_PAYLOAD_MEDIA_OBJECT_NUMBER_FIELD_SIZE +         \
173      ASF_PAYLOAD_OFFSET_INTO_MEDIA_OBJECT_FIELD_SIZE +    \
174      ASF_PAYLOAD_REPLICATED_DATA_LENGTH_FIELD_SIZE +      \
175      ASF_PAYLOAD_REPLICATED_DATA_LENGTH +                 \
176      ASF_PAYLOAD_LENGTH_FIELD_SIZE)
177 
178 #define SINGLE_PAYLOAD_HEADERS                            \
179     (PACKET_HEADER_MIN_SIZE +                             \
180      PAYLOAD_HEADER_SIZE_SINGLE_PAYLOAD)
181 
182 #define MULTI_PAYLOAD_HEADERS                             \
183     (PACKET_HEADER_MIN_SIZE +                             \
184      1 +         /* Payload Flags */                      \
185      2 * PAYLOAD_HEADER_SIZE_MULTIPLE_PAYLOADS)
186 
187 #define DATA_HEADER_SIZE 50
188 
189 #define PACKET_SIZE_MAX 65536
190 #define PACKET_SIZE_MIN 100
191 
192 typedef struct ASFStream {
193     int num;
194     unsigned char seq;
195 
196     uint16_t stream_language_index;
197 } ASFStream;
198 
199 typedef struct ASFContext {
200     AVClass *av_class;
201     uint32_t seqno;
202     int is_streamed;
203     ASFStream streams[128];              ///< it's max number and it's not that big
204     const char *languages[128];
205     int nb_languages;
206     int64_t creation_time;
207     /* non-streamed additional info */
208     uint64_t nb_packets;                 ///< how many packets are there in the file, invalid if broadcasting
209     int64_t duration;                    ///< in 100ns units
210     /* packet filling */
211     unsigned char multi_payloads_present;
212     int packet_size_left;
213     int64_t packet_timestamp_start;
214     int64_t packet_timestamp_end;
215     unsigned int packet_nb_payloads;
216     uint8_t packet_buf[PACKET_SIZE_MAX];
217     FFIOContext pb;
218     /* only for reading */
219     uint64_t data_offset;                ///< beginning of the first data packet
220 
221     ASFIndex *index_ptr;
222     uint32_t nb_index_memory_alloc;
223     uint16_t maximum_packet;
224     uint32_t next_packet_number;
225     uint16_t next_packet_count;
226     uint64_t next_packet_offset;
227     int      next_start_sec;
228     int      end_sec;
229     int      packet_size;
230 } ASFContext;
231 
232 static const AVCodecTag codec_asf_bmp_tags[] = {
233     { AV_CODEC_ID_MPEG4,     MKTAG('M', '4', 'S', '2') },
234     { AV_CODEC_ID_MPEG4,     MKTAG('M', 'P', '4', 'S') },
235     { AV_CODEC_ID_MSMPEG4V3, MKTAG('M', 'P', '4', '3') },
236     { AV_CODEC_ID_NONE,      0 },
237 };
238 
239 static const AVCodecTag *const asf_codec_tags[] = {
240         codec_asf_bmp_tags, ff_codec_bmp_tags, ff_codec_wav_tags, NULL
241 };
242 
243 #define PREROLL_TIME 3100
244 
put_str16(AVIOContext * s,AVIOContext * dyn_buf,const char * tag)245 static void put_str16(AVIOContext *s, AVIOContext *dyn_buf, const char *tag)
246 {
247     uint8_t *buf;
248     int len;
249 
250     avio_put_str16le(dyn_buf, tag);
251     len = avio_get_dyn_buf(dyn_buf, &buf);
252     avio_wl16(s, len);
253     avio_write(s, buf, len);
254     ffio_reset_dyn_buf(dyn_buf);
255 }
256 
put_header(AVIOContext * pb,const ff_asf_guid * g)257 static int64_t put_header(AVIOContext *pb, const ff_asf_guid *g)
258 {
259     int64_t pos;
260 
261     pos = avio_tell(pb);
262     ff_put_guid(pb, g);
263     avio_wl64(pb, 24);
264     return pos;
265 }
266 
267 /* update header size */
end_header(AVIOContext * pb,int64_t pos)268 static void end_header(AVIOContext *pb, int64_t pos)
269 {
270     int64_t pos1;
271 
272     pos1 = avio_tell(pb);
273     avio_seek(pb, pos + 16, SEEK_SET);
274     avio_wl64(pb, pos1 - pos);
275     avio_seek(pb, pos1, SEEK_SET);
276 }
277 
278 /* write an asf chunk (only used in streaming case) */
put_chunk(AVFormatContext * s,int type,int payload_length,int flags)279 static void put_chunk(AVFormatContext *s, int type,
280                       int payload_length, int flags)
281 {
282     ASFContext *asf = s->priv_data;
283     AVIOContext *pb = s->pb;
284     int length;
285 
286     length = payload_length + 8;
287     avio_wl16(pb, type);
288     avio_wl16(pb, length);      // size
289     avio_wl32(pb, asf->seqno);  // sequence number
290     avio_wl16(pb, flags);       // unknown bytes
291     avio_wl16(pb, length);      // size_confirm
292     asf->seqno++;
293 }
294 
295 /* convert from av time to windows time */
unix_to_file_time(int64_t ti)296 static int64_t unix_to_file_time(int64_t ti)
297 {
298     int64_t t;
299 
300     t  = ti * INT64_C(10);
301     t += INT64_C(116444736000000000);
302     return t;
303 }
304 
get_send_time(ASFContext * asf,int64_t pres_time,uint64_t * offset)305 static int32_t get_send_time(ASFContext *asf, int64_t pres_time, uint64_t *offset)
306 {
307     int32_t send_time = 0;
308     *offset = asf->data_offset + DATA_HEADER_SIZE;
309     for (int i = 0; i < asf->next_start_sec; i++) {
310         if (pres_time <= asf->index_ptr[i].send_time)
311             break;
312         send_time = asf->index_ptr[i].send_time;
313         *offset   = asf->index_ptr[i].offset;
314     }
315 
316     return send_time / 10000;
317 }
318 
asf_write_markers(AVFormatContext * s,AVIOContext * dyn_buf)319 static void asf_write_markers(AVFormatContext *s, AVIOContext *dyn_buf)
320 {
321     ASFContext *asf = s->priv_data;
322     AVIOContext *pb = s->pb;
323     AVRational scale = {1, 10000000};
324     int64_t hpos = put_header(pb, &ff_asf_marker_header);
325 
326     ff_put_guid(pb, &ff_asf_reserved_4);// ASF spec mandates this reserved value
327     avio_wl32(pb, s->nb_chapters);     // markers count
328     avio_wl16(pb, 0);                  // ASF spec mandates 0 for this
329     avio_wl16(pb, 0);                  // name length 0, no name given
330 
331     for (unsigned i = 0; i < s->nb_chapters; i++) {
332         AVChapter *c = s->chapters[i];
333         AVDictionaryEntry *t = av_dict_get(c->metadata, "title", NULL, 0);
334         int64_t pres_time = av_rescale_q(c->start, c->time_base, scale);
335         uint64_t offset;
336         int32_t send_time = get_send_time(asf, pres_time, &offset);
337         int len = 0;
338         uint8_t *buf;
339         if (t) {
340             avio_put_str16le(dyn_buf, t->value);
341             len = avio_get_dyn_buf(dyn_buf, &buf);
342         }
343         avio_wl64(pb, offset);            // offset of the packet with send_time
344         avio_wl64(pb, pres_time + PREROLL_TIME * 10000); // presentation time
345         avio_wl16(pb, 12 + len);          // entry length
346         avio_wl32(pb, send_time);         // send time
347         avio_wl32(pb, 0);                 // flags, should be 0
348         avio_wl32(pb, len / 2);           // marker desc length in WCHARS!
349         if (t) {
350             avio_write(pb, buf, len);     // marker desc
351             ffio_reset_dyn_buf(dyn_buf);
352         }
353     }
354     end_header(pb, hpos);
355 }
356 
357 /* write the header (used two times if non streamed) */
asf_write_header1(AVFormatContext * s,int64_t file_size,int64_t data_chunk_size)358 static int asf_write_header1(AVFormatContext *s, int64_t file_size,
359                              int64_t data_chunk_size)
360 {
361     ASFContext *asf = s->priv_data;
362     AVIOContext *pb = s->pb, *dyn_buf;
363     AVDictionaryEntry *tags[5];
364     int header_size, extra_size, extra_size2, wav_extra_size;
365     int has_title, has_aspect_ratio = 0;
366     int metadata_count;
367     int64_t header_offset, cur_pos, hpos;
368     int bit_rate, ret;
369     int64_t duration;
370     int audio_language_counts[128] = { 0 };
371 
372     ff_metadata_conv(&s->metadata, ff_asf_metadata_conv, NULL);
373 
374     tags[0] = av_dict_get(s->metadata, "title", NULL, 0);
375     tags[1] = av_dict_get(s->metadata, "author", NULL, 0);
376     tags[2] = av_dict_get(s->metadata, "copyright", NULL, 0);
377     tags[3] = av_dict_get(s->metadata, "comment", NULL, 0);
378     tags[4] = av_dict_get(s->metadata, "rating", NULL, 0);
379 
380     duration       = asf->duration + PREROLL_TIME * 10000;
381     has_title      = tags[0] || tags[1] || tags[2] || tags[3] || tags[4];
382 
383     if (!file_size) {
384         if (ff_parse_creation_time_metadata(s, &asf->creation_time, 0) != 0)
385             av_dict_set(&s->metadata, "creation_time", NULL, 0);
386     }
387 
388     metadata_count = av_dict_count(s->metadata);
389 
390     bit_rate = 0;
391     for (unsigned n = 0; n < s->nb_streams; n++) {
392         AVStream *const st = s->streams[n];
393         AVCodecParameters *const par = st->codecpar;
394         AVDictionaryEntry *entry;
395 
396         avpriv_set_pts_info(s->streams[n], 32, 1, 1000); /* 32 bit pts in ms */
397 
398         bit_rate += par->bit_rate;
399         if (   par->codec_type == AVMEDIA_TYPE_VIDEO
400             && par->sample_aspect_ratio.num > 0
401             && par->sample_aspect_ratio.den > 0)
402             has_aspect_ratio++;
403 
404         entry = av_dict_get(s->streams[n]->metadata, "language", NULL, 0);
405         if (entry) {
406             const char *iso6391lang = ff_convert_lang_to(entry->value, AV_LANG_ISO639_1);
407             if (iso6391lang) {
408                 int i;
409                 for (i = 0; i < asf->nb_languages; i++) {
410                     if (!strcmp(asf->languages[i], iso6391lang)) {
411                         asf->streams[n].stream_language_index = i;
412                         break;
413                     }
414                 }
415                 if (i >= asf->nb_languages) {
416                     asf->languages[asf->nb_languages] = iso6391lang;
417                     asf->streams[n].stream_language_index = asf->nb_languages;
418                     asf->nb_languages++;
419                 }
420                 if (par->codec_type == AVMEDIA_TYPE_AUDIO)
421                     audio_language_counts[asf->streams[n].stream_language_index]++;
422             }
423         } else {
424             asf->streams[n].stream_language_index = 128;
425         }
426     }
427 
428     if (asf->is_streamed) {
429         put_chunk(s, 0x4824, 0, 0xc00); /* start of stream (length will be patched later) */
430     }
431 
432     ff_put_guid(pb, &ff_asf_header);
433     avio_wl64(pb, -1); /* header length, will be patched after */
434     avio_wl32(pb, 3 + has_title + !!metadata_count + s->nb_streams); /* number of chunks in header */
435     avio_w8(pb, 1); /* ??? */
436     avio_w8(pb, 2); /* ??? */
437 
438     /* file header */
439     header_offset = avio_tell(pb);
440     hpos          = put_header(pb, &ff_asf_file_header);
441     ff_put_guid(pb, &ff_asf_my_guid);
442     avio_wl64(pb, file_size);
443     avio_wl64(pb, unix_to_file_time(asf->creation_time));
444     avio_wl64(pb, asf->nb_packets); /* number of packets */
445     avio_wl64(pb, duration); /* end time stamp (in 100ns units) */
446     avio_wl64(pb, asf->duration); /* duration (in 100ns units) */
447     avio_wl64(pb, PREROLL_TIME); /* start time stamp */
448     avio_wl32(pb, (asf->is_streamed || !(pb->seekable & AVIO_SEEKABLE_NORMAL)) ? 3 : 2);  /* ??? */
449     avio_wl32(pb, s->packet_size); /* packet size */
450     avio_wl32(pb, s->packet_size); /* packet size */
451     avio_wl32(pb, bit_rate ? bit_rate : -1); /* Maximum data rate in bps */
452     end_header(pb, hpos);
453 
454     /* header_extension */
455     hpos = put_header(pb, &ff_asf_head1_guid);
456     ff_put_guid(pb, &ff_asf_head2_guid);
457     avio_wl16(pb, 6);
458     avio_wl32(pb, 0); /* length, to be filled later */
459     if (asf->nb_languages) {
460         int64_t hpos2;
461         int nb_audio_languages = 0;
462 
463         hpos2 = put_header(pb, &ff_asf_language_guid);
464         avio_wl16(pb, asf->nb_languages);
465         for (int i = 0; i < asf->nb_languages; i++) {
466             avio_w8(pb, 6);
467             avio_put_str16le(pb, asf->languages[i]);
468         }
469         end_header(pb, hpos2);
470 
471         for (int i = 0; i < asf->nb_languages; i++)
472             if (audio_language_counts[i])
473                 nb_audio_languages++;
474 
475         if (nb_audio_languages > 1) {
476             hpos2 = put_header(pb, &ff_asf_group_mutual_exclusion_object);
477             ff_put_guid(pb, &ff_asf_mutex_language);
478             avio_wl16(pb, nb_audio_languages);
479             for (int i = 0; i < asf->nb_languages; i++) {
480                 if (audio_language_counts[i]) {
481                     avio_wl16(pb, audio_language_counts[i]);
482                     for (unsigned n = 0; n < s->nb_streams; n++)
483                         if (asf->streams[n].stream_language_index == i && s->streams[n]->codecpar->codec_type == AVMEDIA_TYPE_AUDIO)
484                             avio_wl16(pb, n + 1);
485                 }
486             }
487             end_header(pb, hpos2);
488         }
489 
490         for (unsigned n = 0; n < s->nb_streams; n++) {
491             int64_t es_pos;
492             if (asf->streams[n].stream_language_index > 127)
493                 continue;
494             es_pos = put_header(pb, &ff_asf_extended_stream_properties_object);
495             avio_wl64(pb, 0); /* start time */
496             avio_wl64(pb, 0); /* end time */
497             avio_wl32(pb, s->streams[n]->codecpar->bit_rate); /* data bitrate bps */
498             avio_wl32(pb, 5000); /* buffer size ms */
499             avio_wl32(pb, 0); /* initial buffer fullness */
500             avio_wl32(pb, s->streams[n]->codecpar->bit_rate); /* peak data bitrate */
501             avio_wl32(pb, 5000); /* maximum buffer size ms */
502             avio_wl32(pb, 0); /* max initial buffer fullness */
503             avio_wl32(pb, 0); /* max object size */
504             avio_wl32(pb, (!asf->is_streamed && (pb->seekable & AVIO_SEEKABLE_NORMAL)) << 1); /* flags - seekable */
505             avio_wl16(pb, n + 1); /* stream number */
506             avio_wl16(pb, asf->streams[n].stream_language_index); /* language id index */
507             avio_wl64(pb, 0); /* avg time per frame */
508             avio_wl16(pb, 0); /* stream name count */
509             avio_wl16(pb, 0); /* payload extension system count */
510             end_header(pb, es_pos);
511         }
512     }
513     if (has_aspect_ratio) {
514         int64_t hpos2;
515         hpos2 = put_header(pb, &ff_asf_metadata_header);
516         avio_wl16(pb, 2 * has_aspect_ratio);
517         for (unsigned n = 0; n < s->nb_streams; n++) {
518             AVCodecParameters *const par = s->streams[n]->codecpar;
519             if (   par->codec_type == AVMEDIA_TYPE_VIDEO
520                 && par->sample_aspect_ratio.num > 0
521                 && par->sample_aspect_ratio.den > 0) {
522                 AVRational sar = par->sample_aspect_ratio;
523                 avio_wl16(pb, 0);
524                 // the stream number is set like this below
525                 avio_wl16(pb, n + 1);
526                 avio_wl16(pb, 26); // name_len
527                 avio_wl16(pb,  3); // value_type
528                 avio_wl32(pb,  4); // value_len
529                 avio_put_str16le(pb, "AspectRatioX");
530                 avio_wl32(pb, sar.num);
531                 avio_wl16(pb, 0);
532                 // the stream number is set like this below
533                 avio_wl16(pb, n + 1);
534                 avio_wl16(pb, 26); // name_len
535                 avio_wl16(pb,  3); // value_type
536                 avio_wl32(pb,  4); // value_len
537                 avio_put_str16le(pb, "AspectRatioY");
538                 avio_wl32(pb, sar.den);
539             }
540         }
541         end_header(pb, hpos2);
542     }
543     {
544         int64_t pos1;
545         pos1 = avio_tell(pb);
546         avio_seek(pb, hpos + 42, SEEK_SET);
547         avio_wl32(pb, pos1 - hpos - 46);
548         avio_seek(pb, pos1, SEEK_SET);
549     }
550     end_header(pb, hpos);
551 
552     if ((ret = avio_open_dyn_buf(&dyn_buf)) < 0)
553         return ret;
554 
555     /* title and other info */
556     if (has_title) {
557         uint8_t *buf;
558         int len;
559 
560         hpos = put_header(pb, &ff_asf_comment_header);
561 
562         for (size_t n = 0; n < FF_ARRAY_ELEMS(tags); n++) {
563             len = tags[n] ? avio_put_str16le(dyn_buf, tags[n]->value) : 0;
564             avio_wl16(pb, len);
565         }
566         len = avio_get_dyn_buf(dyn_buf, &buf);
567         avio_write(pb, buf, len);
568         ffio_reset_dyn_buf(dyn_buf);
569         end_header(pb, hpos);
570     }
571     if (metadata_count) {
572         AVDictionaryEntry *tag = NULL;
573         hpos = put_header(pb, &ff_asf_extended_content_header);
574         avio_wl16(pb, metadata_count);
575         while ((tag = av_dict_get(s->metadata, "", tag, AV_DICT_IGNORE_SUFFIX))) {
576             put_str16(pb, dyn_buf, tag->key);
577             avio_wl16(pb, 0);
578             put_str16(pb, dyn_buf, tag->value);
579         }
580         end_header(pb, hpos);
581     }
582     /* chapters using ASF markers */
583     if (!asf->is_streamed && s->nb_chapters) {
584         asf_write_markers(s, dyn_buf);
585     }
586     /* stream headers */
587     for (unsigned n = 0; n < s->nb_streams; n++) {
588         AVCodecParameters *const par = s->streams[n]->codecpar;
589         int64_t es_pos;
590         //        ASFStream *stream = &asf->streams[n];
591 
592         asf->streams[n].num = n + 1;
593         asf->streams[n].seq = 1;
594 
595         switch (par->codec_type) {
596         case AVMEDIA_TYPE_AUDIO:
597             wav_extra_size = 0;
598             extra_size     = 18 + wav_extra_size;
599             extra_size2    = 8;
600             break;
601         default:
602         case AVMEDIA_TYPE_VIDEO:
603             wav_extra_size = par->extradata_size;
604             extra_size     = 0x33 + wav_extra_size;
605             extra_size2    = 0;
606             break;
607         }
608 
609         hpos = put_header(pb, &ff_asf_stream_header);
610         if (par->codec_type == AVMEDIA_TYPE_AUDIO) {
611             ff_put_guid(pb, &ff_asf_audio_stream);
612             ff_put_guid(pb, &ff_asf_audio_conceal_spread);
613         } else {
614             ff_put_guid(pb, &ff_asf_video_stream);
615             ff_put_guid(pb, &ff_asf_video_conceal_none);
616         }
617         avio_wl64(pb, 0); /* ??? */
618         es_pos = avio_tell(pb);
619         avio_wl32(pb, extra_size); /* wav header len */
620         avio_wl32(pb, extra_size2); /* additional data len */
621         avio_wl16(pb, n + 1); /* stream number */
622         avio_wl32(pb, 0); /* ??? */
623 
624         if (par->codec_type == AVMEDIA_TYPE_AUDIO) {
625             /* WAVEFORMATEX header */
626             int wavsize = ff_put_wav_header(s, pb, par, FF_PUT_WAV_HEADER_FORCE_WAVEFORMATEX);
627 
628             if (wavsize < 0) {
629                 ret = wavsize;
630                 goto fail;
631             }
632             if (wavsize != extra_size) {
633                 cur_pos = avio_tell(pb);
634                 avio_seek(pb, es_pos, SEEK_SET);
635                 avio_wl32(pb, wavsize); /* wav header len */
636                 avio_seek(pb, cur_pos, SEEK_SET);
637             }
638             /* ERROR Correction */
639             avio_w8(pb, 0x01);
640             if (par->codec_id == AV_CODEC_ID_ADPCM_G726 || !par->block_align) {
641                 avio_wl16(pb, 0x0190);
642                 avio_wl16(pb, 0x0190);
643             } else {
644                 avio_wl16(pb, par->block_align);
645                 avio_wl16(pb, par->block_align);
646             }
647             avio_wl16(pb, 0x01);
648             avio_w8(pb, 0x00);
649         } else {
650             avio_wl32(pb, par->width);
651             avio_wl32(pb, par->height);
652             avio_w8(pb, 2); /* ??? */
653             avio_wl16(pb, 40 + par->extradata_size); /* size */
654 
655             /* BITMAPINFOHEADER header */
656             ff_put_bmp_header(pb, par, 1, 0, 0);
657         }
658         end_header(pb, hpos);
659     }
660 
661     /* media comments */
662 
663     hpos = put_header(pb, &ff_asf_codec_comment_header);
664     ff_put_guid(pb, &ff_asf_codec_comment1_header);
665     avio_wl32(pb, s->nb_streams);
666     for (unsigned n = 0; n < s->nb_streams; n++) {
667         AVCodecParameters *const par = s->streams[n]->codecpar;
668         const AVCodecDescriptor *const codec_desc = avcodec_descriptor_get(par->codec_id);
669         const char *desc;
670 
671         if (par->codec_type == AVMEDIA_TYPE_AUDIO)
672             avio_wl16(pb, 2);
673         else if (par->codec_type == AVMEDIA_TYPE_VIDEO)
674             avio_wl16(pb, 1);
675         else
676             avio_wl16(pb, -1);
677 
678         if (par->codec_id == AV_CODEC_ID_WMAV2)
679             desc = "Windows Media Audio V8";
680         else
681             desc = codec_desc ? codec_desc->name : NULL;
682 
683         if (desc) {
684             uint8_t *buf;
685             int len;
686 
687             avio_put_str16le(dyn_buf, desc);
688             len = avio_get_dyn_buf(dyn_buf, &buf);
689             avio_wl16(pb, len / 2); // "number of characters" = length in bytes / 2
690 
691             avio_write(pb, buf, len);
692             ffio_reset_dyn_buf(dyn_buf);
693         } else
694             avio_wl16(pb, 0);
695 
696         avio_wl16(pb, 0); /* no parameters */
697 
698         /* id */
699         if (par->codec_type == AVMEDIA_TYPE_AUDIO) {
700             avio_wl16(pb, 2);
701             avio_wl16(pb, par->codec_tag);
702         } else {
703             avio_wl16(pb, 4);
704             avio_wl32(pb, par->codec_tag);
705         }
706         if (!par->codec_tag) {
707             ret = AVERROR(EINVAL);
708             goto fail;
709         }
710     }
711     end_header(pb, hpos);
712 
713     /* patch the header size fields */
714 
715     cur_pos     = avio_tell(pb);
716     header_size = cur_pos - header_offset;
717     if (asf->is_streamed) {
718         header_size += 8 + 30 + DATA_HEADER_SIZE;
719 
720         avio_seek(pb, header_offset - 10 - 30, SEEK_SET);
721         avio_wl16(pb, header_size);
722         avio_seek(pb, header_offset - 2 - 30, SEEK_SET);
723         avio_wl16(pb, header_size);
724 
725         header_size -= 8 + 30 + DATA_HEADER_SIZE;
726     }
727     header_size += 24 + 6;
728     avio_seek(pb, header_offset - 14, SEEK_SET);
729     avio_wl64(pb, header_size);
730     avio_seek(pb, cur_pos, SEEK_SET);
731 
732     /* movie chunk, followed by packets of packet_size */
733     asf->data_offset = cur_pos;
734     ff_put_guid(pb, &ff_asf_data_header);
735     avio_wl64(pb, data_chunk_size);
736     ff_put_guid(pb, &ff_asf_my_guid);
737     avio_wl64(pb, asf->nb_packets); /* nb packets */
738     avio_w8(pb, 1); /* ??? */
739     avio_w8(pb, 1); /* ??? */
740     ret = 0;
741 fail:
742     ffio_free_dyn_buf(&dyn_buf);
743     return ret;
744 }
745 
asf_write_header(AVFormatContext * s)746 static int asf_write_header(AVFormatContext *s)
747 {
748     ASFContext *asf = s->priv_data;
749     int ret;
750 
751     s->packet_size  = asf->packet_size;
752     s->max_interleave_delta = 0;
753     asf->nb_packets = 0;
754 
755     if (s->nb_streams > 127) {
756         av_log(s, AV_LOG_ERROR, "ASF can only handle 127 streams\n");
757         return AVERROR(EINVAL);
758     }
759 
760     asf->index_ptr             = av_malloc(sizeof(ASFIndex) * ASF_INDEX_BLOCK);
761     if (!asf->index_ptr)
762         return AVERROR(ENOMEM);
763     asf->nb_index_memory_alloc = ASF_INDEX_BLOCK;
764     asf->maximum_packet        = 0;
765 
766     /* the data-chunk-size has to be 50 (DATA_HEADER_SIZE), which is
767      * data_size - asf->data_offset at the moment this function is done.
768      * It is needed to use asf as a streamable format. */
769     if ((ret = asf_write_header1(s, 0, DATA_HEADER_SIZE)) < 0)
770         return ret;
771 
772     asf->packet_nb_payloads     = 0;
773     asf->packet_timestamp_start = -1;
774     asf->packet_timestamp_end   = -1;
775     ffio_init_context(&asf->pb, asf->packet_buf, s->packet_size, 1,
776                       NULL, NULL, NULL, NULL);
777 
778     if (s->avoid_negative_ts < 0)
779         s->avoid_negative_ts = 1;
780 
781     return 0;
782 }
783 
asf_write_stream_header(AVFormatContext * s)784 static int asf_write_stream_header(AVFormatContext *s)
785 {
786     ASFContext *asf = s->priv_data;
787 
788     asf->is_streamed = 1;
789 
790     return asf_write_header(s);
791 }
792 
put_payload_parsing_info(AVFormatContext * s,unsigned sendtime,unsigned duration,int nb_payloads,int padsize)793 static int put_payload_parsing_info(AVFormatContext *s,
794                                     unsigned sendtime, unsigned duration,
795                                     int nb_payloads, int padsize)
796 {
797     ASFContext *asf = s->priv_data;
798     AVIOContext *pb = s->pb;
799     int ppi_size;
800     int64_t start = avio_tell(pb);
801 
802     int iLengthTypeFlags = ASF_PPI_LENGTH_TYPE_FLAGS;
803 
804     padsize -= PACKET_HEADER_MIN_SIZE;
805     if (asf->multi_payloads_present)
806         padsize--;
807     av_assert0(padsize >= 0);
808 
809     avio_w8(pb, ASF_PACKET_ERROR_CORRECTION_FLAGS);
810     ffio_fill(pb, 0x0, ASF_PACKET_ERROR_CORRECTION_DATA_SIZE);
811 
812     if (asf->multi_payloads_present)
813         iLengthTypeFlags |= ASF_PPI_FLAG_MULTIPLE_PAYLOADS_PRESENT;
814 
815     if (padsize > 0) {
816         if (padsize < 256)
817             iLengthTypeFlags |= ASF_PPI_FLAG_PADDING_LENGTH_FIELD_IS_BYTE;
818         else
819             iLengthTypeFlags |= ASF_PPI_FLAG_PADDING_LENGTH_FIELD_IS_WORD;
820     }
821     avio_w8(pb, iLengthTypeFlags);
822 
823     avio_w8(pb, ASF_PPI_PROPERTY_FLAGS);
824 
825     if (iLengthTypeFlags & ASF_PPI_FLAG_PADDING_LENGTH_FIELD_IS_WORD)
826         avio_wl16(pb, padsize - 2);
827     if (iLengthTypeFlags & ASF_PPI_FLAG_PADDING_LENGTH_FIELD_IS_BYTE)
828         avio_w8(pb, padsize - 1);
829 
830     avio_wl32(pb, sendtime);
831     avio_wl16(pb, duration);
832     if (asf->multi_payloads_present)
833         avio_w8(pb, nb_payloads | ASF_PAYLOAD_FLAGS);
834 
835     ppi_size = avio_tell(pb) - start;
836 
837     return ppi_size;
838 }
839 
flush_packet(AVFormatContext * s)840 static void flush_packet(AVFormatContext *s)
841 {
842     ASFContext *asf = s->priv_data;
843     int packet_hdr_size, packet_filled_size;
844 
845     av_assert0(asf->packet_timestamp_end >= asf->packet_timestamp_start);
846 
847     if (asf->is_streamed)
848         put_chunk(s, 0x4424, s->packet_size, 0);
849 
850     packet_hdr_size = put_payload_parsing_info(s,
851                                                asf->packet_timestamp_start,
852                                                asf->packet_timestamp_end - asf->packet_timestamp_start,
853                                                asf->packet_nb_payloads,
854                                                asf->packet_size_left);
855 
856     packet_filled_size = asf->packet_size - asf->packet_size_left;
857     av_assert0(packet_hdr_size <= asf->packet_size_left);
858     memset(asf->packet_buf + packet_filled_size, 0, asf->packet_size_left);
859 
860     avio_write(s->pb, asf->packet_buf, s->packet_size - packet_hdr_size);
861 
862     avio_write_marker(s->pb, AV_NOPTS_VALUE, AVIO_DATA_MARKER_FLUSH_POINT);
863 
864     asf->nb_packets++;
865     asf->packet_nb_payloads     = 0;
866     asf->packet_timestamp_start = -1;
867     asf->packet_timestamp_end   = -1;
868     ffio_init_context(&asf->pb, asf->packet_buf, s->packet_size, 1,
869                       NULL, NULL, NULL, NULL);
870 }
871 
put_payload_header(AVFormatContext * s,ASFStream * stream,int64_t presentation_time,int m_obj_size,int m_obj_offset,int payload_len,int flags)872 static void put_payload_header(AVFormatContext *s, ASFStream *stream,
873                                int64_t presentation_time, int m_obj_size,
874                                int m_obj_offset, int payload_len, int flags)
875 {
876     ASFContext *asf = s->priv_data;
877     AVIOContext *const pb = &asf->pb.pub;
878     int val;
879 
880     val = stream->num;
881     if (flags & AV_PKT_FLAG_KEY)
882         val |= ASF_PL_FLAG_KEY_FRAME;
883     avio_w8(pb, val);
884 
885     avio_w8(pb, stream->seq);     // Media object number
886     avio_wl32(pb, m_obj_offset);  // Offset Into Media Object
887 
888     // Replicated Data shall be at least 8 bytes long.
889     // The first 4 bytes of data shall contain the
890     // Size of the Media Object that the payload belongs to.
891     // The next 4 bytes of data shall contain the
892     // Presentation Time for the media object that the payload belongs to.
893     avio_w8(pb, ASF_PAYLOAD_REPLICATED_DATA_LENGTH);
894 
895     avio_wl32(pb, m_obj_size);        // Replicated Data - Media Object Size
896     avio_wl32(pb, (uint32_t) presentation_time); // Replicated Data - Presentation Time
897 
898     if (asf->multi_payloads_present) {
899         avio_wl16(pb, payload_len);   // payload length
900     }
901 }
902 
put_frame(AVFormatContext * s,ASFStream * stream,AVStream * avst,int64_t timestamp,const uint8_t * buf,int m_obj_size,int flags)903 static void put_frame(AVFormatContext *s, ASFStream *stream, AVStream *avst,
904                       int64_t timestamp, const uint8_t *buf,
905                       int m_obj_size, int flags)
906 {
907     ASFContext *asf = s->priv_data;
908     int m_obj_offset, payload_len, frag_len1;
909 
910     m_obj_offset = 0;
911     while (m_obj_offset < m_obj_size) {
912         payload_len = m_obj_size - m_obj_offset;
913         if (asf->packet_timestamp_start == -1) {
914             const int multi_payload_constant = (asf->packet_size - MULTI_PAYLOAD_HEADERS);
915             asf->multi_payloads_present = (payload_len < multi_payload_constant);
916 
917             asf->packet_size_left = asf->packet_size;
918             if (asf->multi_payloads_present) {
919                 frag_len1 = multi_payload_constant - 1;
920             } else {
921                 frag_len1 = asf->packet_size - SINGLE_PAYLOAD_HEADERS;
922             }
923             asf->packet_timestamp_start = timestamp;
924         } else {
925             // multi payloads
926             frag_len1 = asf->packet_size_left -
927                         PAYLOAD_HEADER_SIZE_MULTIPLE_PAYLOADS -
928                         PACKET_HEADER_MIN_SIZE - 1;
929 
930             if (frag_len1 < payload_len &&
931                 avst->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) {
932                 flush_packet(s);
933                 continue;
934             }
935             if (asf->packet_timestamp_start > INT64_MAX - UINT16_MAX ||
936                 timestamp > asf->packet_timestamp_start + UINT16_MAX) {
937                 flush_packet(s);
938                 continue;
939             }
940         }
941         if (frag_len1 > 0) {
942             if (payload_len > frag_len1)
943                 payload_len = frag_len1;
944             else if (payload_len == (frag_len1 - 1))
945                 payload_len = frag_len1 - 2;  // additional byte need to put padding length
946 
947             put_payload_header(s, stream, timestamp + PREROLL_TIME,
948                                m_obj_size, m_obj_offset, payload_len, flags);
949             avio_write(&asf->pb.pub, buf, payload_len);
950 
951             if (asf->multi_payloads_present)
952                 asf->packet_size_left -= (payload_len + PAYLOAD_HEADER_SIZE_MULTIPLE_PAYLOADS);
953             else
954                 asf->packet_size_left -= (payload_len + PAYLOAD_HEADER_SIZE_SINGLE_PAYLOAD);
955             asf->packet_timestamp_end = timestamp;
956 
957             asf->packet_nb_payloads++;
958         } else {
959             payload_len = 0;
960         }
961         m_obj_offset += payload_len;
962         buf          += payload_len;
963 
964         if (!asf->multi_payloads_present)
965             flush_packet(s);
966         else if (asf->packet_size_left <= (PAYLOAD_HEADER_SIZE_MULTIPLE_PAYLOADS + PACKET_HEADER_MIN_SIZE + 1))
967             flush_packet(s);
968         else if (asf->packet_nb_payloads == ASF_PAYLOADS_PER_PACKET)
969             flush_packet(s);
970     }
971     stream->seq++;
972 }
973 
update_index(AVFormatContext * s,int start_sec,uint32_t packet_number,uint16_t packet_count,uint64_t packet_offset)974 static int update_index(AVFormatContext *s, int start_sec,
975                          uint32_t packet_number, uint16_t packet_count,
976                          uint64_t packet_offset)
977 {
978     ASFContext *asf = s->priv_data;
979 
980     if (start_sec > asf->next_start_sec) {
981         if (!asf->next_start_sec) {
982             asf->next_packet_number = packet_number;
983             asf->next_packet_count  = packet_count;
984             asf->next_packet_offset = packet_offset;
985         }
986 
987         if (start_sec > asf->nb_index_memory_alloc) {
988             int err;
989             asf->nb_index_memory_alloc = (start_sec + ASF_INDEX_BLOCK) & ~(ASF_INDEX_BLOCK - 1);
990             if ((err = av_reallocp_array(&asf->index_ptr,
991                                          asf->nb_index_memory_alloc,
992                                          sizeof(*asf->index_ptr))) < 0) {
993                 asf->nb_index_memory_alloc = 0;
994                 return err;
995             }
996         }
997         for (int i = asf->next_start_sec; i < start_sec; i++) {
998             asf->index_ptr[i].packet_number = asf->next_packet_number;
999             asf->index_ptr[i].packet_count  = asf->next_packet_count;
1000             asf->index_ptr[i].send_time     = asf->next_start_sec * INT64_C(10000000);
1001             asf->index_ptr[i].offset        = asf->next_packet_offset;
1002 
1003         }
1004     }
1005     asf->maximum_packet     = FFMAX(asf->maximum_packet, packet_count);
1006     asf->next_packet_number = packet_number;
1007     asf->next_packet_count  = packet_count;
1008     asf->next_packet_offset = packet_offset;
1009     asf->next_start_sec     = start_sec;
1010 
1011     return 0;
1012 }
1013 
asf_write_packet(AVFormatContext * s,AVPacket * pkt)1014 static int asf_write_packet(AVFormatContext *s, AVPacket *pkt)
1015 {
1016     ASFContext *asf = s->priv_data;
1017     AVIOContext *pb = s->pb;
1018     ASFStream *stream;
1019     AVCodecParameters *par;
1020     uint32_t packet_number;
1021     int64_t pts;
1022     int start_sec;
1023     int flags = pkt->flags;
1024     int ret;
1025     uint64_t offset = avio_tell(pb);
1026 
1027     par  = s->streams[pkt->stream_index]->codecpar;
1028     stream = &asf->streams[pkt->stream_index];
1029 
1030     if (par->codec_type == AVMEDIA_TYPE_AUDIO)
1031         flags &= ~AV_PKT_FLAG_KEY;
1032 
1033     pts = (pkt->pts != AV_NOPTS_VALUE) ? pkt->pts : pkt->dts;
1034     av_assert0(pts != AV_NOPTS_VALUE);
1035     if (   pts < - PREROLL_TIME
1036         || pts > (INT_MAX-3)/10000LL * ASF_INDEXED_INTERVAL - PREROLL_TIME) {
1037         av_log(s, AV_LOG_ERROR, "input pts %"PRId64" is invalid\n", pts);
1038         return AVERROR(EINVAL);
1039     }
1040     pts *= 10000;
1041     asf->duration = FFMAX(asf->duration, pts + pkt->duration * 10000);
1042 
1043     packet_number = asf->nb_packets;
1044     put_frame(s, stream, s->streams[pkt->stream_index],
1045               pkt->dts, pkt->data, pkt->size, flags);
1046 
1047     start_sec = (int)((PREROLL_TIME * 10000 + pts + ASF_INDEXED_INTERVAL - 1)
1048               / ASF_INDEXED_INTERVAL);
1049 
1050     /* check index */
1051     if ((!asf->is_streamed) && (flags & AV_PKT_FLAG_KEY)) {
1052         uint16_t packet_count = asf->nb_packets - packet_number;
1053         ret = update_index(s, start_sec, packet_number, packet_count, offset);
1054         if (ret < 0)
1055             return ret;
1056     }
1057     asf->end_sec = start_sec;
1058 
1059     return 0;
1060 }
1061 
asf_write_index(AVFormatContext * s,const ASFIndex * index,uint16_t max,uint32_t count)1062 static int asf_write_index(AVFormatContext *s, const ASFIndex *index,
1063                            uint16_t max, uint32_t count)
1064 {
1065     AVIOContext *pb = s->pb;
1066 
1067     ff_put_guid(pb, &ff_asf_simple_index_header);
1068     avio_wl64(pb, 24 + 16 + 8 + 4 + 4 + (4 + 2) * count);
1069     ff_put_guid(pb, &ff_asf_my_guid);
1070     avio_wl64(pb, ASF_INDEXED_INTERVAL);
1071     avio_wl32(pb, max);
1072     avio_wl32(pb, count);
1073     for (uint32_t i = 0; i < count; i++) {
1074         avio_wl32(pb, index[i].packet_number);
1075         avio_wl16(pb, index[i].packet_count);
1076     }
1077 
1078     return 0;
1079 }
1080 
asf_write_trailer(AVFormatContext * s)1081 static int asf_write_trailer(AVFormatContext *s)
1082 {
1083     ASFContext *asf = s->priv_data;
1084     int64_t file_size, data_size;
1085     int ret;
1086 
1087     /* flush the current packet */
1088     if (asf->pb.pub.buf_ptr > asf->pb.pub.buffer)
1089         flush_packet(s);
1090 
1091     /* write index */
1092     data_size = avio_tell(s->pb);
1093     if (!asf->is_streamed && asf->next_start_sec) {
1094         if ((ret = update_index(s, asf->end_sec + 1, 0, 0, 0)) < 0)
1095             return ret;
1096         asf_write_index(s, asf->index_ptr, asf->maximum_packet, asf->next_start_sec);
1097     }
1098 
1099     if (asf->is_streamed || !(s->pb->seekable & AVIO_SEEKABLE_NORMAL)) {
1100         put_chunk(s, 0x4524, 0, 0); /* end of stream */
1101     } else {
1102         /* rewrite an updated header */
1103         file_size = avio_tell(s->pb);
1104         avio_seek(s->pb, 0, SEEK_SET);
1105         asf_write_header1(s, file_size, data_size - asf->data_offset);
1106     }
1107 
1108     return 0;
1109 }
1110 
asf_deinit(AVFormatContext * s)1111 static void asf_deinit(AVFormatContext *s)
1112 {
1113     ASFContext *const asf = s->priv_data;
1114 
1115     av_freep(&asf->index_ptr);
1116 }
1117 
1118 static const AVOption asf_options[] = {
1119     { "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 },
1120     { NULL },
1121 };
1122 
1123 static const AVClass asf_muxer_class = {
1124     .class_name     = "ASF (stream) muxer",
1125     .item_name      = av_default_item_name,
1126     .option         = asf_options,
1127     .version        = LIBAVUTIL_VERSION_INT,
1128 };
1129 
1130 #if CONFIG_ASF_MUXER
1131 const AVOutputFormat ff_asf_muxer = {
1132     .name           = "asf",
1133     .long_name      = NULL_IF_CONFIG_SMALL("ASF (Advanced / Active Streaming Format)"),
1134     .mime_type      = "video/x-ms-asf",
1135     .extensions     = "asf,wmv,wma",
1136     .priv_data_size = sizeof(ASFContext),
1137     .audio_codec    = AV_CODEC_ID_WMAV2,
1138     .video_codec    = AV_CODEC_ID_MSMPEG4V3,
1139     .write_header   = asf_write_header,
1140     .write_packet   = asf_write_packet,
1141     .write_trailer  = asf_write_trailer,
1142     .flags          = AVFMT_GLOBALHEADER,
1143     .codec_tag      = asf_codec_tags,
1144     .priv_class        = &asf_muxer_class,
1145     .deinit         = asf_deinit,
1146 };
1147 #endif /* CONFIG_ASF_MUXER */
1148 
1149 #if CONFIG_ASF_STREAM_MUXER
1150 const AVOutputFormat ff_asf_stream_muxer = {
1151     .name           = "asf_stream",
1152     .long_name      = NULL_IF_CONFIG_SMALL("ASF (Advanced / Active Streaming Format)"),
1153     .mime_type      = "video/x-ms-asf",
1154     .extensions     = "asf,wmv,wma",
1155     .priv_data_size = sizeof(ASFContext),
1156     .audio_codec    = AV_CODEC_ID_WMAV2,
1157     .video_codec    = AV_CODEC_ID_MSMPEG4V3,
1158     .write_header   = asf_write_stream_header,
1159     .write_packet   = asf_write_packet,
1160     .write_trailer  = asf_write_trailer,
1161     .flags          = AVFMT_GLOBALHEADER,
1162     .codec_tag      = asf_codec_tags,
1163     .priv_class     = &asf_muxer_class,
1164     .deinit         = asf_deinit,
1165 };
1166 #endif /* CONFIG_ASF_STREAM_MUXER */
1167