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