You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

917 lines
31KB

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