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