FFmpeg
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
asfenc.c
Go to the documentation of this file.
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/dict.h"
23 #include "avformat.h"
24 #include "avio_internal.h"
25 #include "internal.h"
26 #include "riff.h"
27 #include "asf.h"
28 
29 #undef NDEBUG
30 #include <assert.h>
31 
32 
33 #define ASF_INDEXED_INTERVAL 10000000
34 #define ASF_INDEX_BLOCK (1<<9)
35 
36 #define ASF_PACKET_ERROR_CORRECTION_DATA_SIZE 0x2
37 #define ASF_PACKET_ERROR_CORRECTION_FLAGS \
38  (ASF_PACKET_FLAG_ERROR_CORRECTION_PRESENT | \
39  ASF_PACKET_ERROR_CORRECTION_DATA_SIZE)
40 
41 #if (ASF_PACKET_ERROR_CORRECTION_FLAGS != 0)
42 # define ASF_PACKET_ERROR_CORRECTION_FLAGS_FIELD_SIZE 1
43 #else
44 # define ASF_PACKET_ERROR_CORRECTION_FLAGS_FIELD_SIZE 0
45 #endif
46 
47 #define ASF_PPI_PROPERTY_FLAGS \
48  (ASF_PL_FLAG_REPLICATED_DATA_LENGTH_FIELD_IS_BYTE | \
49  ASF_PL_FLAG_OFFSET_INTO_MEDIA_OBJECT_LENGTH_FIELD_IS_DWORD | \
50  ASF_PL_FLAG_MEDIA_OBJECT_NUMBER_LENGTH_FIELD_IS_BYTE | \
51  ASF_PL_FLAG_STREAM_NUMBER_LENGTH_FIELD_IS_BYTE)
52 
53 #define ASF_PPI_LENGTH_TYPE_FLAGS 0
54 
55 #define ASF_PAYLOAD_FLAGS ASF_PL_FLAG_PAYLOAD_LENGTH_FIELD_IS_WORD
56 
57 #if (ASF_PPI_FLAG_SEQUENCE_FIELD_IS_BYTE == (ASF_PPI_LENGTH_TYPE_FLAGS & ASF_PPI_MASK_SEQUENCE_FIELD_SIZE))
58 # define ASF_PPI_SEQUENCE_FIELD_SIZE 1
59 #endif
60 #if (ASF_PPI_FLAG_SEQUENCE_FIELD_IS_WORD == (ASF_PPI_LENGTH_TYPE_FLAGS & ASF_PPI_MASK_SEQUENCE_FIELD_SIZE))
61 # define ASF_PPI_SEQUENCE_FIELD_SIZE 2
62 #endif
63 #if (ASF_PPI_FLAG_SEQUENCE_FIELD_IS_DWORD == (ASF_PPI_LENGTH_TYPE_FLAGS & ASF_PPI_MASK_SEQUENCE_FIELD_SIZE))
64 # define ASF_PPI_SEQUENCE_FIELD_SIZE 4
65 #endif
66 #ifndef ASF_PPI_SEQUENCE_FIELD_SIZE
67 # define ASF_PPI_SEQUENCE_FIELD_SIZE 0
68 #endif
69 
70 #if (ASF_PPI_FLAG_PACKET_LENGTH_FIELD_IS_BYTE == (ASF_PPI_LENGTH_TYPE_FLAGS & ASF_PPI_MASK_PACKET_LENGTH_FIELD_SIZE))
71 # define ASF_PPI_PACKET_LENGTH_FIELD_SIZE 1
72 #endif
73 #if (ASF_PPI_FLAG_PACKET_LENGTH_FIELD_IS_WORD == (ASF_PPI_LENGTH_TYPE_FLAGS & ASF_PPI_MASK_PACKET_LENGTH_FIELD_SIZE))
74 # define ASF_PPI_PACKET_LENGTH_FIELD_SIZE 2
75 #endif
76 #if (ASF_PPI_FLAG_PACKET_LENGTH_FIELD_IS_DWORD == (ASF_PPI_LENGTH_TYPE_FLAGS & ASF_PPI_MASK_PACKET_LENGTH_FIELD_SIZE))
77 # define ASF_PPI_PACKET_LENGTH_FIELD_SIZE 4
78 #endif
79 #ifndef ASF_PPI_PACKET_LENGTH_FIELD_SIZE
80 # define ASF_PPI_PACKET_LENGTH_FIELD_SIZE 0
81 #endif
82 
83 #if (ASF_PPI_FLAG_PADDING_LENGTH_FIELD_IS_BYTE == (ASF_PPI_LENGTH_TYPE_FLAGS & ASF_PPI_MASK_PADDING_LENGTH_FIELD_SIZE))
84 # define ASF_PPI_PADDING_LENGTH_FIELD_SIZE 1
85 #endif
86 #if (ASF_PPI_FLAG_PADDING_LENGTH_FIELD_IS_WORD == (ASF_PPI_LENGTH_TYPE_FLAGS & ASF_PPI_MASK_PADDING_LENGTH_FIELD_SIZE))
87 # define ASF_PPI_PADDING_LENGTH_FIELD_SIZE 2
88 #endif
89 #if (ASF_PPI_FLAG_PADDING_LENGTH_FIELD_IS_DWORD == (ASF_PPI_LENGTH_TYPE_FLAGS & ASF_PPI_MASK_PADDING_LENGTH_FIELD_SIZE))
90 # define ASF_PPI_PADDING_LENGTH_FIELD_SIZE 4
91 #endif
92 #ifndef ASF_PPI_PADDING_LENGTH_FIELD_SIZE
93 # define ASF_PPI_PADDING_LENGTH_FIELD_SIZE 0
94 #endif
95 
96 #if (ASF_PL_FLAG_REPLICATED_DATA_LENGTH_FIELD_IS_BYTE == (ASF_PPI_PROPERTY_FLAGS & ASF_PL_MASK_REPLICATED_DATA_LENGTH_FIELD_SIZE))
97 # define ASF_PAYLOAD_REPLICATED_DATA_LENGTH_FIELD_SIZE 1
98 #endif
99 #if (ASF_PL_FLAG_REPLICATED_DATA_LENGTH_FIELD_IS_WORD == (ASF_PPI_PROPERTY_FLAGS & ASF_PL_MASK_REPLICATED_DATA_LENGTH_FIELD_SIZE))
100 # define ASF_PAYLOAD_REPLICATED_DATA_LENGTH_FIELD_SIZE 2
101 #endif
102 #if (ASF_PL_FLAG_REPLICATED_DATA_LENGTH_FIELD_IS_DWORD == (ASF_PPI_PROPERTY_FLAGS & ASF_PL_MASK_REPLICATED_DATA_LENGTH_FIELD_SIZE))
103 # define ASF_PAYLOAD_REPLICATED_DATA_LENGTH_FIELD_SIZE 4
104 #endif
105 #ifndef ASF_PAYLOAD_REPLICATED_DATA_LENGTH_FIELD_SIZE
106 # define ASF_PAYLOAD_REPLICATED_DATA_LENGTH_FIELD_SIZE 0
107 #endif
108 
109 #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))
110 # define ASF_PAYLOAD_OFFSET_INTO_MEDIA_OBJECT_FIELD_SIZE 1
111 #endif
112 #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))
113 # define ASF_PAYLOAD_OFFSET_INTO_MEDIA_OBJECT_FIELD_SIZE 2
114 #endif
115 #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))
116 # define ASF_PAYLOAD_OFFSET_INTO_MEDIA_OBJECT_FIELD_SIZE 4
117 #endif
118 #ifndef ASF_PAYLOAD_OFFSET_INTO_MEDIA_OBJECT_FIELD_SIZE
119 # define ASF_PAYLOAD_OFFSET_INTO_MEDIA_OBJECT_FIELD_SIZE 0
120 #endif
121 
122 #if (ASF_PL_FLAG_MEDIA_OBJECT_NUMBER_LENGTH_FIELD_IS_BYTE == (ASF_PPI_PROPERTY_FLAGS & ASF_PL_MASK_MEDIA_OBJECT_NUMBER_LENGTH_FIELD_SIZE))
123 # define ASF_PAYLOAD_MEDIA_OBJECT_NUMBER_FIELD_SIZE 1
124 #endif
125 #if (ASF_PL_FLAG_MEDIA_OBJECT_NUMBER_LENGTH_FIELD_IS_WORD == (ASF_PPI_PROPERTY_FLAGS & ASF_PL_MASK_MEDIA_OBJECT_NUMBER_LENGTH_FIELD_SIZE))
126 # define ASF_PAYLOAD_MEDIA_OBJECT_NUMBER_FIELD_SIZE 2
127 #endif
128 #if (ASF_PL_FLAG_MEDIA_OBJECT_NUMBER_LENGTH_FIELD_IS_DWORD == (ASF_PPI_PROPERTY_FLAGS & ASF_PL_MASK_MEDIA_OBJECT_NUMBER_LENGTH_FIELD_SIZE))
129 # define ASF_PAYLOAD_MEDIA_OBJECT_NUMBER_FIELD_SIZE 4
130 #endif
131 #ifndef ASF_PAYLOAD_MEDIA_OBJECT_NUMBER_FIELD_SIZE
132 # define ASF_PAYLOAD_MEDIA_OBJECT_NUMBER_FIELD_SIZE 0
133 #endif
134 
135 #if (ASF_PL_FLAG_PAYLOAD_LENGTH_FIELD_IS_BYTE == (ASF_PAYLOAD_FLAGS & ASF_PL_MASK_PAYLOAD_LENGTH_FIELD_SIZE))
136 # define ASF_PAYLOAD_LENGTH_FIELD_SIZE 1
137 #endif
138 #if (ASF_PL_FLAG_PAYLOAD_LENGTH_FIELD_IS_WORD == (ASF_PAYLOAD_FLAGS & ASF_PL_MASK_PAYLOAD_LENGTH_FIELD_SIZE))
139 # define ASF_PAYLOAD_LENGTH_FIELD_SIZE 2
140 #endif
141 #ifndef ASF_PAYLOAD_LENGTH_FIELD_SIZE
142 # define ASF_PAYLOAD_LENGTH_FIELD_SIZE 0
143 #endif
144 
145 #define PACKET_HEADER_MIN_SIZE \
146  (ASF_PACKET_ERROR_CORRECTION_FLAGS_FIELD_SIZE + \
147  ASF_PACKET_ERROR_CORRECTION_DATA_SIZE + \
148  1 + /* Length Type Flags */ \
149  1 + /* Property Flags */ \
150  ASF_PPI_PACKET_LENGTH_FIELD_SIZE + \
151  ASF_PPI_SEQUENCE_FIELD_SIZE + \
152  ASF_PPI_PADDING_LENGTH_FIELD_SIZE + \
153  4 + /* Send Time Field */ \
154  2) /* Duration Field */
155 
156 // Replicated Data shall be at least 8 bytes long.
157 #define ASF_PAYLOAD_REPLICATED_DATA_LENGTH 0x08
158 
159 #define PAYLOAD_HEADER_SIZE_SINGLE_PAYLOAD \
160  (1 + /* Stream Number */ \
161  ASF_PAYLOAD_MEDIA_OBJECT_NUMBER_FIELD_SIZE + \
162  ASF_PAYLOAD_OFFSET_INTO_MEDIA_OBJECT_FIELD_SIZE + \
163  ASF_PAYLOAD_REPLICATED_DATA_LENGTH_FIELD_SIZE + \
164  ASF_PAYLOAD_REPLICATED_DATA_LENGTH)
165 
166 #define PAYLOAD_HEADER_SIZE_MULTIPLE_PAYLOADS \
167  (1 + /* Stream Number */ \
168  ASF_PAYLOAD_MEDIA_OBJECT_NUMBER_FIELD_SIZE + \
169  ASF_PAYLOAD_OFFSET_INTO_MEDIA_OBJECT_FIELD_SIZE + \
170  ASF_PAYLOAD_REPLICATED_DATA_LENGTH_FIELD_SIZE + \
171  ASF_PAYLOAD_REPLICATED_DATA_LENGTH + \
172  ASF_PAYLOAD_LENGTH_FIELD_SIZE)
173 
174 #define SINGLE_PAYLOAD_DATA_LENGTH \
175  (PACKET_SIZE - \
176  PACKET_HEADER_MIN_SIZE - \
177  PAYLOAD_HEADER_SIZE_SINGLE_PAYLOAD)
178 
179 #define MULTI_PAYLOAD_CONSTANT \
180  (PACKET_SIZE - \
181  PACKET_HEADER_MIN_SIZE - \
182  1 - /* Payload Flags */ \
183  2 * PAYLOAD_HEADER_SIZE_MULTIPLE_PAYLOADS)
184 
185 typedef struct {
186  uint32_t seqno;
188  ASFStream streams[128]; ///< it's max number and it's not that big
189  /* non streamed additonnal info */
190  uint64_t nb_packets; ///< how many packets are there in the file, invalid if broadcasting
191  int64_t duration; ///< in 100ns units
192  /* packet filling */
193  unsigned char multi_payloads_present;
194  int packet_size_left;
197  unsigned int packet_nb_payloads;
198  uint8_t packet_buf[PACKET_SIZE];
200  /* only for reading */
201  uint64_t data_offset; ///< beginning of the first data packet
202 
205  uint16_t maximum_packet;
209  int end_sec;
210 } ASFContext;
211 
212 static const AVCodecTag codec_asf_bmp_tags[] = {
213  { AV_CODEC_ID_MPEG4, MKTAG('M', '4', 'S', '2') },
214  { AV_CODEC_ID_MPEG4, MKTAG('M', 'P', '4', 'S') },
215  { AV_CODEC_ID_MSMPEG4V3, MKTAG('M', 'P', '4', '3') },
216  { AV_CODEC_ID_NONE, 0 },
217 };
218 
219 #define PREROLL_TIME 3100
220 
222 {
223  assert(sizeof(*g) == 16);
224  avio_write(s, *g, sizeof(*g));
225 }
226 
227 static void put_str16(AVIOContext *s, const char *tag)
228 {
229  int len;
230  uint8_t *pb;
231  AVIOContext *dyn_buf;
232  if (avio_open_dyn_buf(&dyn_buf) < 0)
233  return;
234 
235  avio_put_str16le(dyn_buf, tag);
236  len = avio_close_dyn_buf(dyn_buf, &pb);
237  avio_wl16(s, len);
238  avio_write(s, pb, len);
239  av_freep(&pb);
240 }
241 
242 static int64_t put_header(AVIOContext *pb, const ff_asf_guid *g)
243 {
244  int64_t pos;
245 
246  pos = avio_tell(pb);
247  ff_put_guid(pb, g);
248  avio_wl64(pb, 24);
249  return pos;
250 }
251 
252 /* update header size */
253 static void end_header(AVIOContext *pb, int64_t pos)
254 {
255  int64_t pos1;
256 
257  pos1 = avio_tell(pb);
258  avio_seek(pb, pos + 16, SEEK_SET);
259  avio_wl64(pb, pos1 - pos);
260  avio_seek(pb, pos1, SEEK_SET);
261 }
262 
263 /* write an asf chunk (only used in streaming case) */
264 static void put_chunk(AVFormatContext *s, int type,
265  int payload_length, int flags)
266 {
267  ASFContext *asf = s->priv_data;
268  AVIOContext *pb = s->pb;
269  int length;
270 
271  length = payload_length + 8;
272  avio_wl16(pb, type);
273  avio_wl16(pb, length); // size
274  avio_wl32(pb, asf->seqno); // sequence number
275  avio_wl16(pb, flags); // unknown bytes
276  avio_wl16(pb, length); // size_confirm
277  asf->seqno++;
278 }
279 
280 /* convert from unix to windows time */
281 static int64_t unix_to_file_time(int ti)
282 {
283  int64_t t;
284 
285  t = ti * INT64_C(10000000);
286  t += INT64_C(116444736000000000);
287  return t;
288 }
289 
290 /* write the header (used two times if non streamed) */
291 static int asf_write_header1(AVFormatContext *s, int64_t file_size,
292  int64_t data_chunk_size)
293 {
294  ASFContext *asf = s->priv_data;
295  AVIOContext *pb = s->pb;
296  AVDictionaryEntry *tags[5];
297  int header_size, n, extra_size, extra_size2, wav_extra_size, file_time;
298  int has_title;
299  int metadata_count;
300  AVCodecContext *enc;
301  int64_t header_offset, cur_pos, hpos;
302  int bit_rate;
303  int64_t duration;
304 
306 
307  tags[0] = av_dict_get(s->metadata, "title", NULL, 0);
308  tags[1] = av_dict_get(s->metadata, "author", NULL, 0);
309  tags[2] = av_dict_get(s->metadata, "copyright", NULL, 0);
310  tags[3] = av_dict_get(s->metadata, "comment", NULL, 0);
311  tags[4] = av_dict_get(s->metadata, "rating", NULL, 0);
312 
313  duration = asf->duration + PREROLL_TIME * 10000;
314  has_title = tags[0] || tags[1] || tags[2] || tags[3] || tags[4];
315  metadata_count = av_dict_count(s->metadata);
316 
317  bit_rate = 0;
318  for (n = 0; n < s->nb_streams; n++) {
319  enc = s->streams[n]->codec;
320 
321  avpriv_set_pts_info(s->streams[n], 32, 1, 1000); /* 32 bit pts in ms */
322 
323  bit_rate += enc->bit_rate;
324  }
325 
326  if (asf->is_streamed) {
327  put_chunk(s, 0x4824, 0, 0xc00); /* start of stream (length will be patched later) */
328  }
329 
331  avio_wl64(pb, -1); /* header length, will be patched after */
332  avio_wl32(pb, 3 + has_title + !!metadata_count + s->nb_streams); /* number of chunks in header */
333  avio_w8(pb, 1); /* ??? */
334  avio_w8(pb, 2); /* ??? */
335 
336  /* file header */
337  header_offset = avio_tell(pb);
338  hpos = put_header(pb, &ff_asf_file_header);
340  avio_wl64(pb, file_size);
341  file_time = 0;
342  avio_wl64(pb, unix_to_file_time(file_time));
343  avio_wl64(pb, asf->nb_packets); /* number of packets */
344  avio_wl64(pb, duration); /* end time stamp (in 100ns units) */
345  avio_wl64(pb, asf->duration); /* duration (in 100ns units) */
346  avio_wl64(pb, PREROLL_TIME); /* start time stamp */
347  avio_wl32(pb, (asf->is_streamed || !pb->seekable) ? 3 : 2); /* ??? */
348  avio_wl32(pb, s->packet_size); /* packet size */
349  avio_wl32(pb, s->packet_size); /* packet size */
350  avio_wl32(pb, bit_rate); /* Nominal data rate in bps */
351  end_header(pb, hpos);
352 
353  /* unknown headers */
354  hpos = put_header(pb, &ff_asf_head1_guid);
356  avio_wl32(pb, 6);
357  avio_wl16(pb, 0);
358  end_header(pb, hpos);
359 
360  /* title and other infos */
361  if (has_title) {
362  int len;
363  uint8_t *buf;
364  AVIOContext *dyn_buf;
365 
366  if (avio_open_dyn_buf(&dyn_buf) < 0)
367  return AVERROR(ENOMEM);
368 
369  hpos = put_header(pb, &ff_asf_comment_header);
370 
371  for (n = 0; n < FF_ARRAY_ELEMS(tags); n++) {
372  len = tags[n] ? avio_put_str16le(dyn_buf, tags[n]->value) : 0;
373  avio_wl16(pb, len);
374  }
375  len = avio_close_dyn_buf(dyn_buf, &buf);
376  avio_write(pb, buf, len);
377  av_freep(&buf);
378  end_header(pb, hpos);
379  }
380  if (metadata_count) {
383  avio_wl16(pb, metadata_count);
384  while ((tag = av_dict_get(s->metadata, "", tag, AV_DICT_IGNORE_SUFFIX))) {
385  put_str16(pb, tag->key);
386  avio_wl16(pb, 0);
387  put_str16(pb, tag->value);
388  }
389  end_header(pb, hpos);
390  }
391 
392  /* stream headers */
393  for (n = 0; n < s->nb_streams; n++) {
394  int64_t es_pos;
395  // ASFStream *stream = &asf->streams[n];
396 
397  enc = s->streams[n]->codec;
398  asf->streams[n].num = n + 1;
399  asf->streams[n].seq = 1;
400 
401  switch (enc->codec_type) {
402  case AVMEDIA_TYPE_AUDIO:
403  wav_extra_size = 0;
404  extra_size = 18 + wav_extra_size;
405  extra_size2 = 8;
406  break;
407  default:
408  case AVMEDIA_TYPE_VIDEO:
409  wav_extra_size = enc->extradata_size;
410  extra_size = 0x33 + wav_extra_size;
411  extra_size2 = 0;
412  break;
413  }
414 
415  hpos = put_header(pb, &ff_asf_stream_header);
416  if (enc->codec_type == AVMEDIA_TYPE_AUDIO) {
419  } else {
422  }
423  avio_wl64(pb, 0); /* ??? */
424  es_pos = avio_tell(pb);
425  avio_wl32(pb, extra_size); /* wav header len */
426  avio_wl32(pb, extra_size2); /* additional data len */
427  avio_wl16(pb, n + 1); /* stream number */
428  avio_wl32(pb, 0); /* ??? */
429 
430  if (enc->codec_type == AVMEDIA_TYPE_AUDIO) {
431  /* WAVEFORMATEX header */
432  int wavsize = ff_put_wav_header(pb, enc);
433 
434  if (wavsize < 0)
435  return -1;
436  if (wavsize != extra_size) {
437  cur_pos = avio_tell(pb);
438  avio_seek(pb, es_pos, SEEK_SET);
439  avio_wl32(pb, wavsize); /* wav header len */
440  avio_seek(pb, cur_pos, SEEK_SET);
441  }
442  /* ERROR Correction */
443  avio_w8(pb, 0x01);
444  if (enc->codec_id == AV_CODEC_ID_ADPCM_G726 || !enc->block_align) {
445  avio_wl16(pb, 0x0190);
446  avio_wl16(pb, 0x0190);
447  } else {
448  avio_wl16(pb, enc->block_align);
449  avio_wl16(pb, enc->block_align);
450  }
451  avio_wl16(pb, 0x01);
452  avio_w8(pb, 0x00);
453  } else {
454  avio_wl32(pb, enc->width);
455  avio_wl32(pb, enc->height);
456  avio_w8(pb, 2); /* ??? */
457  avio_wl16(pb, 40 + enc->extradata_size); /* size */
458 
459  /* BITMAPINFOHEADER header */
461  }
462  end_header(pb, hpos);
463  }
464 
465  /* media comments */
466 
469  avio_wl32(pb, s->nb_streams);
470  for (n = 0; n < s->nb_streams; n++) {
471  AVCodec *p;
472  const char *desc;
473  int len;
474  uint8_t *buf;
475  AVIOContext *dyn_buf;
476 
477  enc = s->streams[n]->codec;
478  p = avcodec_find_encoder(enc->codec_id);
479 
480  if (enc->codec_type == AVMEDIA_TYPE_AUDIO)
481  avio_wl16(pb, 2);
482  else if (enc->codec_type == AVMEDIA_TYPE_VIDEO)
483  avio_wl16(pb, 1);
484  else
485  avio_wl16(pb, -1);
486 
487  if (enc->codec_id == AV_CODEC_ID_WMAV2)
488  desc = "Windows Media Audio V8";
489  else
490  desc = p ? p->name : enc->codec_name;
491 
492  if (avio_open_dyn_buf(&dyn_buf) < 0)
493  return AVERROR(ENOMEM);
494 
495  avio_put_str16le(dyn_buf, desc);
496  len = avio_close_dyn_buf(dyn_buf, &buf);
497  avio_wl16(pb, len / 2); // "number of characters" = length in bytes / 2
498 
499  avio_write(pb, buf, len);
500  av_freep(&buf);
501 
502  avio_wl16(pb, 0); /* no parameters */
503 
504  /* id */
505  if (enc->codec_type == AVMEDIA_TYPE_AUDIO) {
506  avio_wl16(pb, 2);
507  avio_wl16(pb, enc->codec_tag);
508  } else {
509  avio_wl16(pb, 4);
510  avio_wl32(pb, enc->codec_tag);
511  }
512  if (!enc->codec_tag)
513  return -1;
514  }
515  end_header(pb, hpos);
516 
517  /* patch the header size fields */
518 
519  cur_pos = avio_tell(pb);
520  header_size = cur_pos - header_offset;
521  if (asf->is_streamed) {
522  header_size += 8 + 30 + 50;
523 
524  avio_seek(pb, header_offset - 10 - 30, SEEK_SET);
525  avio_wl16(pb, header_size);
526  avio_seek(pb, header_offset - 2 - 30, SEEK_SET);
527  avio_wl16(pb, header_size);
528 
529  header_size -= 8 + 30 + 50;
530  }
531  header_size += 24 + 6;
532  avio_seek(pb, header_offset - 14, SEEK_SET);
533  avio_wl64(pb, header_size);
534  avio_seek(pb, cur_pos, SEEK_SET);
535 
536  /* movie chunk, followed by packets of packet_size */
537  asf->data_offset = cur_pos;
539  avio_wl64(pb, data_chunk_size);
541  avio_wl64(pb, asf->nb_packets); /* nb packets */
542  avio_w8(pb, 1); /* ??? */
543  avio_w8(pb, 1); /* ??? */
544  return 0;
545 }
546 
548 {
549  ASFContext *asf = s->priv_data;
550 
552  asf->nb_packets = 0;
553 
554  asf->index_ptr = av_malloc(sizeof(ASFIndex) * ASF_INDEX_BLOCK);
556  asf->maximum_packet = 0;
557 
558  /* the data-chunk-size has to be 50, which is data_size - asf->data_offset
559  * at the moment this function is done. It is needed to use asf as
560  * streamable format. */
561  if (asf_write_header1(s, 0, 50) < 0) {
562  //av_free(asf);
563  return -1;
564  }
565 
566  avio_flush(s->pb);
567 
568  asf->packet_nb_payloads = 0;
569  asf->packet_timestamp_start = -1;
570  asf->packet_timestamp_end = -1;
571  ffio_init_context(&asf->pb, asf->packet_buf, s->packet_size, 1,
572  NULL, NULL, NULL, NULL);
573 
574  if (s->avoid_negative_ts < 0)
575  s->avoid_negative_ts = 1;
576 
577  return 0;
578 }
579 
581 {
582  ASFContext *asf = s->priv_data;
583 
584  asf->is_streamed = 1;
585 
586  return asf_write_header(s);
587 }
588 
590  unsigned sendtime, unsigned duration,
591  int nb_payloads, int padsize)
592 {
593  ASFContext *asf = s->priv_data;
594  AVIOContext *pb = s->pb;
595  int ppi_size, i;
596  int64_t start = avio_tell(pb);
597 
598  int iLengthTypeFlags = ASF_PPI_LENGTH_TYPE_FLAGS;
599 
600  padsize -= PACKET_HEADER_MIN_SIZE;
601  if (asf->multi_payloads_present)
602  padsize--;
603  assert(padsize >= 0);
604 
606  for (i = 0; i < ASF_PACKET_ERROR_CORRECTION_DATA_SIZE; i++)
607  avio_w8(pb, 0x0);
608 
609  if (asf->multi_payloads_present)
610  iLengthTypeFlags |= ASF_PPI_FLAG_MULTIPLE_PAYLOADS_PRESENT;
611 
612  if (padsize > 0) {
613  if (padsize < 256)
614  iLengthTypeFlags |= ASF_PPI_FLAG_PADDING_LENGTH_FIELD_IS_BYTE;
615  else
616  iLengthTypeFlags |= ASF_PPI_FLAG_PADDING_LENGTH_FIELD_IS_WORD;
617  }
618  avio_w8(pb, iLengthTypeFlags);
619 
621 
622  if (iLengthTypeFlags & ASF_PPI_FLAG_PADDING_LENGTH_FIELD_IS_WORD)
623  avio_wl16(pb, padsize - 2);
624  if (iLengthTypeFlags & ASF_PPI_FLAG_PADDING_LENGTH_FIELD_IS_BYTE)
625  avio_w8(pb, padsize - 1);
626 
627  avio_wl32(pb, sendtime);
628  avio_wl16(pb, duration);
629  if (asf->multi_payloads_present)
630  avio_w8(pb, nb_payloads | ASF_PAYLOAD_FLAGS);
631 
632  ppi_size = avio_tell(pb) - start;
633 
634  return ppi_size;
635 }
636 
638 {
639  ASFContext *asf = s->priv_data;
640  int packet_hdr_size, packet_filled_size;
641 
642  assert(asf->packet_timestamp_end >= asf->packet_timestamp_start);
643 
644  if (asf->is_streamed)
645  put_chunk(s, 0x4424, s->packet_size, 0);
646 
647  packet_hdr_size = put_payload_parsing_info(s,
650  asf->packet_nb_payloads,
651  asf->packet_size_left);
652 
653  packet_filled_size = PACKET_SIZE - asf->packet_size_left;
654  assert(packet_hdr_size <= asf->packet_size_left);
655  memset(asf->packet_buf + packet_filled_size, 0, asf->packet_size_left);
656 
657  avio_write(s->pb, asf->packet_buf, s->packet_size - packet_hdr_size);
658 
659  avio_flush(s->pb);
660  asf->nb_packets++;
661  asf->packet_nb_payloads = 0;
662  asf->packet_timestamp_start = -1;
663  asf->packet_timestamp_end = -1;
664  ffio_init_context(&asf->pb, asf->packet_buf, s->packet_size, 1,
665  NULL, NULL, NULL, NULL);
666 }
667 
669  int64_t presentation_time, int m_obj_size,
670  int m_obj_offset, int payload_len, int flags)
671 {
672  ASFContext *asf = s->priv_data;
673  AVIOContext *pb = &asf->pb;
674  int val;
675 
676  val = stream->num;
677  if (flags & AV_PKT_FLAG_KEY)
678  val |= ASF_PL_FLAG_KEY_FRAME;
679  avio_w8(pb, val);
680 
681  avio_w8(pb, stream->seq); // Media object number
682  avio_wl32(pb, m_obj_offset); // Offset Into Media Object
683 
684  // Replicated Data shall be at least 8 bytes long.
685  // The first 4 bytes of data shall contain the
686  // Size of the Media Object that the payload belongs to.
687  // The next 4 bytes of data shall contain the
688  // Presentation Time for the media object that the payload belongs to.
690 
691  avio_wl32(pb, m_obj_size); // Replicated Data - Media Object Size
692  avio_wl32(pb, (uint32_t) presentation_time); // Replicated Data - Presentation Time
693 
694  if (asf->multi_payloads_present) {
695  avio_wl16(pb, payload_len); // payload length
696  }
697 }
698 
699 static void put_frame(AVFormatContext *s, ASFStream *stream, AVStream *avst,
700  int64_t timestamp, const uint8_t *buf,
701  int m_obj_size, int flags)
702 {
703  ASFContext *asf = s->priv_data;
704  int m_obj_offset, payload_len, frag_len1;
705 
706  m_obj_offset = 0;
707  while (m_obj_offset < m_obj_size) {
708  payload_len = m_obj_size - m_obj_offset;
709  if (asf->packet_timestamp_start == -1) {
710  asf->multi_payloads_present = (payload_len < MULTI_PAYLOAD_CONSTANT);
711 
713  if (asf->multi_payloads_present) {
714  frag_len1 = MULTI_PAYLOAD_CONSTANT - 1;
715  } else {
716  frag_len1 = SINGLE_PAYLOAD_DATA_LENGTH;
717  }
718  asf->packet_timestamp_start = timestamp;
719  } else {
720  // multi payloads
721  frag_len1 = asf->packet_size_left -
724 
725  if (frag_len1 < payload_len &&
726  avst->codec->codec_type == AVMEDIA_TYPE_AUDIO) {
727  flush_packet(s);
728  continue;
729  }
730  }
731  if (frag_len1 > 0) {
732  if (payload_len > frag_len1)
733  payload_len = frag_len1;
734  else if (payload_len == (frag_len1 - 1))
735  payload_len = frag_len1 - 2; // additional byte need to put padding length
736 
737  put_payload_header(s, stream, timestamp + PREROLL_TIME,
738  m_obj_size, m_obj_offset, payload_len, flags);
739  avio_write(&asf->pb, buf, payload_len);
740 
741  if (asf->multi_payloads_present)
743  else
745  asf->packet_timestamp_end = timestamp;
746 
747  asf->packet_nb_payloads++;
748  } else {
749  payload_len = 0;
750  }
751  m_obj_offset += payload_len;
752  buf += payload_len;
753 
754  if (!asf->multi_payloads_present)
755  flush_packet(s);
757  flush_packet(s);
758  }
759  stream->seq++;
760 }
761 
762 static void update_index(AVFormatContext *s, int start_sec,
763  uint32_t packet_number, uint16_t packet_count)
764 {
765  ASFContext *asf = s->priv_data;
766 
767  if (start_sec > asf->next_start_sec) {
768  int i;
769 
770  if (!asf->next_start_sec) {
771  asf->next_packet_number = packet_number;
772  asf->next_packet_count = packet_count;
773  }
774 
775  if (start_sec > asf->nb_index_memory_alloc) {
776  asf->nb_index_memory_alloc = (start_sec + ASF_INDEX_BLOCK) & ~(ASF_INDEX_BLOCK - 1);
777  asf->index_ptr = av_realloc( asf->index_ptr, sizeof(ASFIndex) * asf->nb_index_memory_alloc );
778  }
779  for (i = asf->next_start_sec; i < start_sec; i++) {
782  }
783  }
784  asf->maximum_packet = FFMAX(asf->maximum_packet, packet_count);
785  asf->next_packet_number = packet_number;
786  asf->next_packet_count = packet_count;
787  asf->next_start_sec = start_sec;
788 }
789 
791 {
792  ASFContext *asf = s->priv_data;
793  ASFStream *stream;
794  AVCodecContext *codec;
795  uint32_t packet_number;
796  int64_t pts;
797  int start_sec;
798  int flags = pkt->flags;
799 
800  codec = s->streams[pkt->stream_index]->codec;
801  stream = &asf->streams[pkt->stream_index];
802 
803  if (codec->codec_type == AVMEDIA_TYPE_AUDIO)
804  flags &= ~AV_PKT_FLAG_KEY;
805 
806  pts = (pkt->pts != AV_NOPTS_VALUE) ? pkt->pts : pkt->dts;
807  assert(pts != AV_NOPTS_VALUE);
808  pts *= 10000;
809  asf->duration = FFMAX(asf->duration, pts + pkt->duration * 10000);
810 
811  packet_number = asf->nb_packets;
812  put_frame(s, stream, s->streams[pkt->stream_index],
813  pkt->dts, pkt->data, pkt->size, flags);
814 
815  start_sec = (int)((PREROLL_TIME * 10000 + pts + ASF_INDEXED_INTERVAL - 1)
817 
818  /* check index */
819  if ((!asf->is_streamed) && (flags & AV_PKT_FLAG_KEY)) {
820  uint16_t packet_count = asf->nb_packets - packet_number;
821  update_index(s, start_sec, packet_number, packet_count);
822  }
823  asf->end_sec = start_sec;
824 
825  return 0;
826 }
827 
829  uint16_t max, uint32_t count)
830 {
831  AVIOContext *pb = s->pb;
832  int i;
833 
835  avio_wl64(pb, 24 + 16 + 8 + 4 + 4 + (4 + 2) * count);
838  avio_wl32(pb, max);
839  avio_wl32(pb, count);
840  for (i = 0; i < count; i++) {
841  avio_wl32(pb, index[i].packet_number);
842  avio_wl16(pb, index[i].packet_count);
843  }
844 
845  return 0;
846 }
847 
849 {
850  ASFContext *asf = s->priv_data;
851  int64_t file_size, data_size;
852 
853  /* flush the current packet */
854  if (asf->pb.buf_ptr > asf->pb.buffer)
855  flush_packet(s);
856 
857  /* write index */
858  data_size = avio_tell(s->pb);
859  if (!asf->is_streamed && asf->next_start_sec) {
860  update_index(s, asf->end_sec + 1, 0, 0);
862  }
863  avio_flush(s->pb);
864 
865  if (asf->is_streamed || !s->pb->seekable) {
866  put_chunk(s, 0x4524, 0, 0); /* end of stream */
867  } else {
868  /* rewrite an updated header */
869  file_size = avio_tell(s->pb);
870  avio_seek(s->pb, 0, SEEK_SET);
871  asf_write_header1(s, file_size, data_size - asf->data_offset);
872  }
873 
874  av_free(asf->index_ptr);
875  return 0;
876 }
877 
878 #if CONFIG_ASF_MUXER
879 AVOutputFormat ff_asf_muxer = {
880  .name = "asf",
881  .long_name = NULL_IF_CONFIG_SMALL("ASF (Advanced / Active Streaming Format)"),
882  .mime_type = "video/x-ms-asf",
883  .extensions = "asf,wmv,wma",
884  .priv_data_size = sizeof(ASFContext),
885  .audio_codec = AV_CODEC_ID_WMAV2,
886  .video_codec = AV_CODEC_ID_MSMPEG4V3,
891  .codec_tag = (const AVCodecTag * const []) {
893  },
894 };
895 #endif /* CONFIG_ASF_MUXER */
896 
897 #if CONFIG_ASF_STREAM_MUXER
898 AVOutputFormat ff_asf_stream_muxer = {
899  .name = "asf_stream",
900  .long_name = NULL_IF_CONFIG_SMALL("ASF (Advanced / Active Streaming Format)"),
901  .mime_type = "video/x-ms-asf",
902  .extensions = "asf,wmv,wma",
903  .priv_data_size = sizeof(ASFContext),
904  .audio_codec = AV_CODEC_ID_WMAV2,
905  .video_codec = AV_CODEC_ID_MSMPEG4V3,
910  .codec_tag = (const AVCodecTag * const []) {
912  },
913 };
914 #endif /* CONFIG_ASF_STREAM_MUXER */