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.

1103 lines
31KB

  1. /*
  2. * ASF compatible encoder and decoder.
  3. * Copyright (c) 2000, 2001 Fabrice Bellard.
  4. *
  5. * This library is free software; you can redistribute it and/or
  6. * modify it under the terms of the GNU Lesser General Public
  7. * License as published by the Free Software Foundation; either
  8. * version 2 of the License, or (at your option) any later version.
  9. *
  10. * This library is distributed in the hope that it will be useful,
  11. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  13. * Lesser General Public License for more details.
  14. *
  15. * You should have received a copy of the GNU Lesser General Public
  16. * License along with this library; if not, write to the Free Software
  17. * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  18. */
  19. #include "avformat.h"
  20. #include "avi.h"
  21. #include "tick.h"
  22. #include "mpegaudio.h"
  23. #define PACKET_SIZE 3200
  24. #define PACKET_HEADER_SIZE 12
  25. #define FRAME_HEADER_SIZE 17
  26. typedef struct {
  27. int num;
  28. int seq;
  29. Ticker pts_ticker;
  30. /* use for reading */
  31. AVPacket pkt;
  32. int frag_offset;
  33. INT64 duration;
  34. } ASFStream;
  35. typedef struct {
  36. int seqno;
  37. int packet_size;
  38. int is_streamed;
  39. ASFStream streams[2];
  40. /* non streamed additonnal info */
  41. int data_offset;
  42. INT64 nb_packets;
  43. INT64 duration; /* in 100ns units */
  44. /* packet filling */
  45. int packet_size_left;
  46. int packet_timestamp_start;
  47. int packet_timestamp_end;
  48. int packet_nb_frames;
  49. UINT8 packet_buf[PACKET_SIZE];
  50. ByteIOContext pb;
  51. /* only for reading */
  52. int packet_padsize;
  53. } ASFContext;
  54. typedef struct {
  55. UINT32 v1;
  56. UINT16 v2;
  57. UINT16 v3;
  58. UINT8 v4[8];
  59. } GUID;
  60. static const GUID asf_header = {
  61. 0x75B22630, 0x668E, 0x11CF, { 0xA6, 0xD9, 0x00, 0xAA, 0x00, 0x62, 0xCE, 0x6C },
  62. };
  63. static const GUID file_header = {
  64. 0x8CABDCA1, 0xA947, 0x11CF, { 0x8E, 0xE4, 0x00, 0xC0, 0x0C, 0x20, 0x53, 0x65 },
  65. };
  66. static const GUID stream_header = {
  67. 0xB7DC0791, 0xA9B7, 0x11CF, { 0x8E, 0xE6, 0x00, 0xC0, 0x0C, 0x20, 0x53, 0x65 },
  68. };
  69. static const GUID audio_stream = {
  70. 0xF8699E40, 0x5B4D, 0x11CF, { 0xA8, 0xFD, 0x00, 0x80, 0x5F, 0x5C, 0x44, 0x2B },
  71. };
  72. static const GUID audio_conceal_none = {
  73. // 0x49f1a440, 0x4ece, 0x11d0, { 0xa3, 0xac, 0x00, 0xa0, 0xc9, 0x03, 0x48, 0xf6 },
  74. // New value lifted from avifile
  75. 0x20fb5700, 0x5b55, 0x11cf, { 0xa8, 0xfd, 0x00, 0x80, 0x5f, 0x5c, 0x44, 0x2b },
  76. };
  77. static const GUID video_stream = {
  78. 0xBC19EFC0, 0x5B4D, 0x11CF, { 0xA8, 0xFD, 0x00, 0x80, 0x5F, 0x5C, 0x44, 0x2B },
  79. };
  80. static const GUID video_conceal_none = {
  81. 0x20FB5700, 0x5B55, 0x11CF, { 0xA8, 0xFD, 0x00, 0x80, 0x5F, 0x5C, 0x44, 0x2B },
  82. };
  83. static const GUID comment_header = {
  84. 0x75b22633, 0x668e, 0x11cf, { 0xa6, 0xd9, 0x00, 0xaa, 0x00, 0x62, 0xce, 0x6c },
  85. };
  86. static const GUID codec_comment_header = {
  87. 0x86D15240, 0x311D, 0x11D0, { 0xA3, 0xA4, 0x00, 0xA0, 0xC9, 0x03, 0x48, 0xF6 },
  88. };
  89. static const GUID codec_comment1_header = {
  90. 0x86d15241, 0x311d, 0x11d0, { 0xa3, 0xa4, 0x00, 0xa0, 0xc9, 0x03, 0x48, 0xf6 },
  91. };
  92. static const GUID data_header = {
  93. 0x75b22636, 0x668e, 0x11cf, { 0xa6, 0xd9, 0x00, 0xaa, 0x00, 0x62, 0xce, 0x6c },
  94. };
  95. static const GUID index_guid = {
  96. 0x33000890, 0xe5b1, 0x11cf, { 0x89, 0xf4, 0x00, 0xa0, 0xc9, 0x03, 0x49, 0xcb },
  97. };
  98. static const GUID head1_guid = {
  99. 0x5fbf03b5, 0xa92e, 0x11cf, { 0x8e, 0xe3, 0x00, 0xc0, 0x0c, 0x20, 0x53, 0x65 },
  100. };
  101. static const GUID head2_guid = {
  102. 0xabd3d211, 0xa9ba, 0x11cf, { 0x8e, 0xe6, 0x00, 0xc0, 0x0c, 0x20, 0x53, 0x65 },
  103. };
  104. /* I am not a number !!! This GUID is the one found on the PC used to
  105. generate the stream */
  106. static const GUID my_guid = {
  107. 0, 0, 0, { 0, 0, 0, 0, 0, 0, 0, 0 },
  108. };
  109. CodecTag codec_asf_bmp_tags[] = {
  110. { CODEC_ID_H263, MKTAG('H', '2', '6', '3') },
  111. { CODEC_ID_H263P, MKTAG('H', '2', '6', '3') },
  112. { CODEC_ID_H263I, MKTAG('I', '2', '6', '3') }, /* intel h263 */
  113. { CODEC_ID_MJPEG, MKTAG('M', 'J', 'P', 'G') },
  114. { CODEC_ID_MPEG4, MKTAG('D', 'I', 'V', 'X') },
  115. { CODEC_ID_MPEG4, MKTAG('d', 'i', 'v', 'x') },
  116. { CODEC_ID_MPEG4, MKTAG('D', 'X', '5', '0') },
  117. { CODEC_ID_MPEG4, MKTAG('X', 'V', 'I', 'D') },
  118. { CODEC_ID_MPEG4, MKTAG('x', 'v', 'i', 'd') },
  119. { CODEC_ID_MPEG4, MKTAG('m', 'p', '4', 's') },
  120. { CODEC_ID_MPEG4, MKTAG('M', 'P', '4', 'S') },
  121. { CODEC_ID_MPEG4, MKTAG('M', '4', 'S', '2') },
  122. { CODEC_ID_MPEG4, MKTAG('m', '4', 's', '2') },
  123. { CODEC_ID_MPEG4, MKTAG(0x04, 0, 0, 0) }, /* some broken avi use this */
  124. { CODEC_ID_MSMPEG4V3, MKTAG('M', 'P', '4', '3') }, /* default signature when using MSMPEG4 */
  125. { CODEC_ID_MSMPEG4V3, MKTAG('D', 'I', 'V', '3') },
  126. { CODEC_ID_MSMPEG4V2, MKTAG('M', 'P', '4', '2') },
  127. { CODEC_ID_MSMPEG4V1, MKTAG('M', 'P', 'G', '4') },
  128. { CODEC_ID_WMV1, MKTAG('W', 'M', 'V', '1') },
  129. { 0, 0 },
  130. };
  131. static void put_guid(ByteIOContext *s, const GUID *g)
  132. {
  133. int i;
  134. put_le32(s, g->v1);
  135. put_le16(s, g->v2);
  136. put_le16(s, g->v3);
  137. for(i=0;i<8;i++)
  138. put_byte(s, g->v4[i]);
  139. }
  140. static void put_str16(ByteIOContext *s, const char *tag)
  141. {
  142. int c;
  143. put_le16(s,strlen(tag) + 1);
  144. for(;;) {
  145. c = (UINT8)*tag++;
  146. put_le16(s, c);
  147. if (c == '\0')
  148. break;
  149. }
  150. }
  151. static void put_str16_nolen(ByteIOContext *s, const char *tag)
  152. {
  153. int c;
  154. for(;;) {
  155. c = (UINT8)*tag++;
  156. put_le16(s, c);
  157. if (c == '\0')
  158. break;
  159. }
  160. }
  161. static INT64 put_header(ByteIOContext *pb, const GUID *g)
  162. {
  163. INT64 pos;
  164. pos = url_ftell(pb);
  165. put_guid(pb, g);
  166. put_le64(pb, 24);
  167. return pos;
  168. }
  169. /* update header size */
  170. static void end_header(ByteIOContext *pb, INT64 pos)
  171. {
  172. INT64 pos1;
  173. pos1 = url_ftell(pb);
  174. url_fseek(pb, pos + 16, SEEK_SET);
  175. put_le64(pb, pos1 - pos);
  176. url_fseek(pb, pos1, SEEK_SET);
  177. }
  178. /* write an asf chunk (only used in streaming case) */
  179. static void put_chunk(AVFormatContext *s, int type, int payload_length, int flags)
  180. {
  181. ASFContext *asf = s->priv_data;
  182. ByteIOContext *pb = &s->pb;
  183. int length;
  184. length = payload_length + 8;
  185. put_le16(pb, type);
  186. put_le16(pb, length);
  187. put_le32(pb, asf->seqno);
  188. put_le16(pb, flags); /* unknown bytes */
  189. put_le16(pb, length);
  190. asf->seqno++;
  191. }
  192. /* convert from unix to windows time */
  193. static INT64 unix_to_file_time(int ti)
  194. {
  195. INT64 t;
  196. t = ti * INT64_C(10000000);
  197. t += INT64_C(116444736000000000);
  198. return t;
  199. }
  200. /* write the header (used two times if non streamed) */
  201. static int asf_write_header1(AVFormatContext *s, INT64 file_size, INT64 data_chunk_size)
  202. {
  203. ASFContext *asf = s->priv_data;
  204. ByteIOContext *pb = &s->pb;
  205. int header_size, n, extra_size, extra_size2, wav_extra_size, file_time;
  206. int has_title;
  207. AVCodecContext *enc;
  208. INT64 header_offset, cur_pos, hpos;
  209. int bit_rate;
  210. has_title = (s->title[0] || s->author[0] || s->copyright[0] || s->comment[0]);
  211. bit_rate = 0;
  212. for(n=0;n<s->nb_streams;n++) {
  213. enc = &s->streams[n]->codec;
  214. bit_rate += enc->bit_rate;
  215. }
  216. if (asf->is_streamed) {
  217. put_chunk(s, 0x4824, 0, 0xc00); /* start of stream (length will be patched later) */
  218. }
  219. put_guid(pb, &asf_header);
  220. put_le64(pb, 0); /* header length, will be patched after */
  221. put_le32(pb, 3 + has_title + s->nb_streams); /* number of chunks in header */
  222. put_byte(pb, 1); /* ??? */
  223. put_byte(pb, 2); /* ??? */
  224. /* file header */
  225. header_offset = url_ftell(pb);
  226. hpos = put_header(pb, &file_header);
  227. put_guid(pb, &my_guid);
  228. put_le64(pb, file_size);
  229. file_time = 0;
  230. put_le64(pb, unix_to_file_time(file_time));
  231. put_le64(pb, asf->nb_packets); /* number of packets */
  232. put_le64(pb, asf->duration); /* end time stamp (in 100ns units) */
  233. put_le64(pb, asf->duration); /* duration (in 100ns units) */
  234. put_le32(pb, 0); /* start time stamp */
  235. put_le32(pb, 0); /* ??? */
  236. put_le32(pb, asf->is_streamed ? 1 : 0); /* ??? */
  237. put_le32(pb, asf->packet_size); /* packet size */
  238. put_le32(pb, asf->packet_size); /* packet size */
  239. put_le32(pb, bit_rate); /* Nominal data rate in bps */
  240. end_header(pb, hpos);
  241. /* unknown headers */
  242. hpos = put_header(pb, &head1_guid);
  243. put_guid(pb, &head2_guid);
  244. put_le32(pb, 6);
  245. put_le16(pb, 0);
  246. end_header(pb, hpos);
  247. /* title and other infos */
  248. if (has_title) {
  249. hpos = put_header(pb, &comment_header);
  250. put_le16(pb, 2 * (strlen(s->title) + 1));
  251. put_le16(pb, 2 * (strlen(s->author) + 1));
  252. put_le16(pb, 2 * (strlen(s->copyright) + 1));
  253. put_le16(pb, 2 * (strlen(s->comment) + 1));
  254. put_le16(pb, 0);
  255. put_str16_nolen(pb, s->title);
  256. put_str16_nolen(pb, s->author);
  257. put_str16_nolen(pb, s->copyright);
  258. put_str16_nolen(pb, s->comment);
  259. end_header(pb, hpos);
  260. }
  261. /* stream headers */
  262. for(n=0;n<s->nb_streams;n++) {
  263. INT64 es_pos;
  264. ASFStream *stream = &asf->streams[n];
  265. enc = &s->streams[n]->codec;
  266. asf->streams[n].num = n + 1;
  267. asf->streams[n].seq = 0;
  268. switch(enc->codec_type) {
  269. case CODEC_TYPE_AUDIO:
  270. wav_extra_size = 0;
  271. extra_size = 18 + wav_extra_size;
  272. extra_size2 = 0;
  273. /* Init the ticker */
  274. ticker_init(&stream->pts_ticker,
  275. enc->sample_rate,
  276. 1000 * enc->frame_size);
  277. break;
  278. default:
  279. case CODEC_TYPE_VIDEO:
  280. wav_extra_size = 0;
  281. extra_size = 0x33;
  282. extra_size2 = 0;
  283. /* Init the ticker */
  284. ticker_init(&stream->pts_ticker,
  285. enc->frame_rate,
  286. 1000 * FRAME_RATE_BASE);
  287. break;
  288. }
  289. hpos = put_header(pb, &stream_header);
  290. if (enc->codec_type == CODEC_TYPE_AUDIO) {
  291. put_guid(pb, &audio_stream);
  292. put_guid(pb, &audio_conceal_none);
  293. } else {
  294. put_guid(pb, &video_stream);
  295. put_guid(pb, &video_conceal_none);
  296. }
  297. put_le64(pb, 0); /* ??? */
  298. es_pos = url_ftell(pb);
  299. put_le32(pb, extra_size); /* wav header len */
  300. put_le32(pb, extra_size2); /* additional data len */
  301. put_le16(pb, n + 1); /* stream number */
  302. put_le32(pb, 0); /* ??? */
  303. if (enc->codec_type == CODEC_TYPE_AUDIO) {
  304. /* WAVEFORMATEX header */
  305. int wavsize = put_wav_header(pb, enc);
  306. if (wavsize < 0)
  307. return -1;
  308. if (wavsize != extra_size) {
  309. cur_pos = url_ftell(pb);
  310. url_fseek(pb, es_pos, SEEK_SET);
  311. put_le32(pb, wavsize); /* wav header len */
  312. url_fseek(pb, cur_pos, SEEK_SET);
  313. }
  314. } else {
  315. put_le32(pb, enc->width);
  316. put_le32(pb, enc->height);
  317. put_byte(pb, 2); /* ??? */
  318. put_le16(pb, 40); /* size */
  319. /* BITMAPINFOHEADER header */
  320. put_bmp_header(pb, enc, codec_asf_bmp_tags);
  321. }
  322. end_header(pb, hpos);
  323. }
  324. /* media comments */
  325. hpos = put_header(pb, &codec_comment_header);
  326. put_guid(pb, &codec_comment1_header);
  327. put_le32(pb, s->nb_streams);
  328. for(n=0;n<s->nb_streams;n++) {
  329. AVCodec *p;
  330. enc = &s->streams[n]->codec;
  331. p = avcodec_find_encoder(enc->codec_id);
  332. put_le16(pb, asf->streams[n].num);
  333. put_str16(pb, p ? p->name : enc->codec_name);
  334. put_le16(pb, 0); /* no parameters */
  335. /* id */
  336. if (enc->codec_type == CODEC_TYPE_AUDIO) {
  337. put_le16(pb, 2);
  338. put_le16(pb, codec_get_tag(codec_wav_tags, enc->codec_id));
  339. } else {
  340. put_le16(pb, 4);
  341. put_le32(pb, codec_get_tag(codec_asf_bmp_tags, enc->codec_id));
  342. }
  343. }
  344. end_header(pb, hpos);
  345. /* patch the header size fields */
  346. cur_pos = url_ftell(pb);
  347. header_size = cur_pos - header_offset;
  348. if (asf->is_streamed) {
  349. header_size += 8 + 30 + 50;
  350. url_fseek(pb, header_offset - 10 - 30, SEEK_SET);
  351. put_le16(pb, header_size);
  352. url_fseek(pb, header_offset - 2 - 30, SEEK_SET);
  353. put_le16(pb, header_size);
  354. header_size -= 8 + 30 + 50;
  355. }
  356. header_size += 24 + 6;
  357. url_fseek(pb, header_offset - 14, SEEK_SET);
  358. put_le64(pb, header_size);
  359. url_fseek(pb, cur_pos, SEEK_SET);
  360. /* movie chunk, followed by packets of packet_size */
  361. asf->data_offset = cur_pos;
  362. put_guid(pb, &data_header);
  363. put_le64(pb, data_chunk_size);
  364. put_guid(pb, &my_guid);
  365. put_le64(pb, asf->nb_packets); /* nb packets */
  366. put_byte(pb, 1); /* ??? */
  367. put_byte(pb, 1); /* ??? */
  368. return 0;
  369. }
  370. static int asf_write_header(AVFormatContext *s)
  371. {
  372. ASFContext *asf = s->priv_data;
  373. asf->packet_size = PACKET_SIZE;
  374. asf->nb_packets = 0;
  375. if (asf_write_header1(s, 0, 50) < 0) {
  376. //av_free(asf);
  377. return -1;
  378. }
  379. put_flush_packet(&s->pb);
  380. asf->packet_nb_frames = 0;
  381. asf->packet_timestamp_start = -1;
  382. asf->packet_timestamp_end = -1;
  383. asf->packet_size_left = asf->packet_size - PACKET_HEADER_SIZE;
  384. init_put_byte(&asf->pb, asf->packet_buf, asf->packet_size, 1,
  385. NULL, NULL, NULL, NULL);
  386. return 0;
  387. }
  388. static int asf_write_stream_header(AVFormatContext *s)
  389. {
  390. ASFContext *asf = s->priv_data;
  391. asf->is_streamed = 1;
  392. return asf_write_header(s);
  393. }
  394. /* write a fixed size packet */
  395. static int put_packet(AVFormatContext *s,
  396. unsigned int timestamp, unsigned int duration,
  397. int nb_frames, int padsize)
  398. {
  399. ASFContext *asf = s->priv_data;
  400. ByteIOContext *pb = &s->pb;
  401. int flags;
  402. if (asf->is_streamed) {
  403. put_chunk(s, 0x4424, asf->packet_size, 0);
  404. }
  405. put_byte(pb, 0x82);
  406. put_le16(pb, 0);
  407. flags = 0x01; /* nb segments present */
  408. if (padsize > 0) {
  409. if (padsize < 256)
  410. flags |= 0x08;
  411. else
  412. flags |= 0x10;
  413. }
  414. put_byte(pb, flags); /* flags */
  415. put_byte(pb, 0x5d);
  416. if (flags & 0x10)
  417. put_le16(pb, padsize - 2);
  418. if (flags & 0x08)
  419. put_byte(pb, padsize - 1);
  420. put_le32(pb, timestamp);
  421. put_le16(pb, duration);
  422. put_byte(pb, nb_frames | 0x80);
  423. return PACKET_HEADER_SIZE + ((flags & 0x18) >> 3);
  424. }
  425. static void flush_packet(AVFormatContext *s)
  426. {
  427. ASFContext *asf = s->priv_data;
  428. int hdr_size, ptr;
  429. hdr_size = put_packet(s, asf->packet_timestamp_start,
  430. asf->packet_timestamp_end - asf->packet_timestamp_start,
  431. asf->packet_nb_frames, asf->packet_size_left);
  432. /* Clear out the padding bytes */
  433. ptr = asf->packet_size - hdr_size - asf->packet_size_left;
  434. memset(asf->packet_buf + ptr, 0, asf->packet_size_left);
  435. put_buffer(&s->pb, asf->packet_buf, asf->packet_size - hdr_size);
  436. put_flush_packet(&s->pb);
  437. asf->nb_packets++;
  438. asf->packet_nb_frames = 0;
  439. asf->packet_timestamp_start = -1;
  440. asf->packet_timestamp_end = -1;
  441. asf->packet_size_left = asf->packet_size - PACKET_HEADER_SIZE;
  442. init_put_byte(&asf->pb, asf->packet_buf, asf->packet_size, 1,
  443. NULL, NULL, NULL, NULL);
  444. }
  445. static void put_frame_header(AVFormatContext *s, ASFStream *stream, int timestamp,
  446. int payload_size, int frag_offset, int frag_len)
  447. {
  448. ASFContext *asf = s->priv_data;
  449. ByteIOContext *pb = &asf->pb;
  450. int val;
  451. val = stream->num;
  452. if (s->streams[val - 1]->codec.key_frame /* && frag_offset == 0 */)
  453. val |= 0x80;
  454. put_byte(pb, val);
  455. put_byte(pb, stream->seq);
  456. put_le32(pb, frag_offset); /* fragment offset */
  457. put_byte(pb, 0x08); /* flags */
  458. put_le32(pb, payload_size);
  459. put_le32(pb, timestamp);
  460. put_le16(pb, frag_len);
  461. }
  462. /* Output a frame. We suppose that payload_size <= PACKET_SIZE.
  463. It is there that you understand that the ASF format is really
  464. crap. They have misread the MPEG Systems spec !
  465. */
  466. static void put_frame(AVFormatContext *s, ASFStream *stream, int timestamp,
  467. UINT8 *buf, int payload_size)
  468. {
  469. ASFContext *asf = s->priv_data;
  470. int frag_pos, frag_len, frag_len1;
  471. frag_pos = 0;
  472. while (frag_pos < payload_size) {
  473. frag_len = payload_size - frag_pos;
  474. frag_len1 = asf->packet_size_left - FRAME_HEADER_SIZE;
  475. if (frag_len1 > 0) {
  476. if (frag_len > frag_len1)
  477. frag_len = frag_len1;
  478. put_frame_header(s, stream, timestamp, payload_size, frag_pos, frag_len);
  479. put_buffer(&asf->pb, buf, frag_len);
  480. asf->packet_size_left -= (frag_len + FRAME_HEADER_SIZE);
  481. asf->packet_timestamp_end = timestamp;
  482. if (asf->packet_timestamp_start == -1)
  483. asf->packet_timestamp_start = timestamp;
  484. asf->packet_nb_frames++;
  485. } else {
  486. frag_len = 0;
  487. }
  488. frag_pos += frag_len;
  489. buf += frag_len;
  490. /* output the frame if filled */
  491. if (asf->packet_size_left <= FRAME_HEADER_SIZE)
  492. flush_packet(s);
  493. }
  494. stream->seq++;
  495. }
  496. static int asf_write_packet(AVFormatContext *s, int stream_index,
  497. UINT8 *buf, int size, int force_pts)
  498. {
  499. ASFContext *asf = s->priv_data;
  500. ASFStream *stream;
  501. int timestamp;
  502. INT64 duration;
  503. AVCodecContext *codec;
  504. stream = &asf->streams[stream_index];
  505. codec = &s->streams[stream_index]->codec;
  506. stream = &asf->streams[stream_index];
  507. if (codec->codec_type == CODEC_TYPE_AUDIO) {
  508. timestamp = (int)ticker_abs(&stream->pts_ticker, codec->frame_number);
  509. duration = (codec->frame_number * codec->frame_size * INT64_C(10000000)) /
  510. codec->sample_rate;
  511. } else {
  512. timestamp = (int)ticker_abs(&stream->pts_ticker, codec->frame_number);
  513. duration = codec->frame_number *
  514. ((INT64_C(10000000) * FRAME_RATE_BASE) / codec->frame_rate);
  515. }
  516. if (duration > asf->duration)
  517. asf->duration = duration;
  518. put_frame(s, stream, timestamp, buf, size);
  519. return 0;
  520. }
  521. static int asf_write_trailer(AVFormatContext *s)
  522. {
  523. ASFContext *asf = s->priv_data;
  524. INT64 file_size;
  525. /* flush the current packet */
  526. if (asf->pb.buf_ptr > asf->pb.buffer)
  527. flush_packet(s);
  528. if (asf->is_streamed) {
  529. put_chunk(s, 0x4524, 0, 0); /* end of stream */
  530. } else {
  531. /* rewrite an updated header */
  532. file_size = url_ftell(&s->pb);
  533. url_fseek(&s->pb, 0, SEEK_SET);
  534. asf_write_header1(s, file_size, file_size - asf->data_offset);
  535. }
  536. put_flush_packet(&s->pb);
  537. return 0;
  538. }
  539. /**********************************/
  540. /* decoding */
  541. //#define DEBUG
  542. #ifdef DEBUG
  543. static void print_guid(const GUID *g)
  544. {
  545. int i;
  546. printf("0x%08x, 0x%04x, 0x%04x, {", g->v1, g->v2, g->v3);
  547. for(i=0;i<8;i++)
  548. printf(" 0x%02x,", g->v4[i]);
  549. printf("}\n");
  550. }
  551. #endif
  552. static void get_guid(ByteIOContext *s, GUID *g)
  553. {
  554. int i;
  555. g->v1 = get_le32(s);
  556. g->v2 = get_le16(s);
  557. g->v3 = get_le16(s);
  558. for(i=0;i<8;i++)
  559. g->v4[i] = get_byte(s);
  560. }
  561. #if 0
  562. static void get_str16(ByteIOContext *pb, char *buf, int buf_size)
  563. {
  564. int len, c;
  565. char *q;
  566. len = get_le16(pb);
  567. q = buf;
  568. while (len > 0) {
  569. c = get_le16(pb);
  570. if ((q - buf) < buf_size - 1)
  571. *q++ = c;
  572. len--;
  573. }
  574. *q = '\0';
  575. }
  576. #endif
  577. static void get_str16_nolen(ByteIOContext *pb, int len, char *buf, int buf_size)
  578. {
  579. int c;
  580. char *q;
  581. q = buf;
  582. while (len > 0) {
  583. c = get_le16(pb);
  584. if ((q - buf) < buf_size - 1)
  585. *q++ = c;
  586. len-=2;
  587. }
  588. *q = '\0';
  589. }
  590. static int asf_probe(AVProbeData *pd)
  591. {
  592. GUID g;
  593. const unsigned char *p;
  594. int i;
  595. /* check file header */
  596. if (pd->buf_size <= 32)
  597. return 0;
  598. p = pd->buf;
  599. g.v1 = p[0] | (p[1] << 8) | (p[2] << 16) | (p[3] << 24);
  600. p += 4;
  601. g.v2 = p[0] | (p[1] << 8);
  602. p += 2;
  603. g.v3 = p[0] | (p[1] << 8);
  604. p += 2;
  605. for(i=0;i<8;i++)
  606. g.v4[i] = *p++;
  607. if (!memcmp(&g, &asf_header, sizeof(GUID)))
  608. return AVPROBE_SCORE_MAX;
  609. else
  610. return 0;
  611. }
  612. static int asf_read_header(AVFormatContext *s, AVFormatParameters *ap)
  613. {
  614. ASFContext *asf = s->priv_data;
  615. GUID g;
  616. ByteIOContext *pb = &s->pb;
  617. AVStream *st;
  618. ASFStream *asf_st;
  619. int size, i, bps;
  620. INT64 gsize;
  621. get_guid(pb, &g);
  622. if (memcmp(&g, &asf_header, sizeof(GUID)))
  623. goto fail;
  624. get_le64(pb);
  625. get_le32(pb);
  626. get_byte(pb);
  627. get_byte(pb);
  628. for(;;) {
  629. get_guid(pb, &g);
  630. gsize = get_le64(pb);
  631. #ifdef DEBUG
  632. printf("%08Lx: ", url_ftell(pb) - 24);
  633. print_guid(&g);
  634. printf(" size=0x%Lx\n", gsize);
  635. #endif
  636. if (gsize < 24)
  637. goto fail;
  638. if (!memcmp(&g, &file_header, sizeof(GUID))) {
  639. get_guid(pb, &g);
  640. get_le64(pb); /* file size */
  641. get_le64(pb); /* file time */
  642. get_le64(pb); /* nb_packets */
  643. get_le64(pb); /* length 0 in us */
  644. get_le64(pb); /* length 1 in us */
  645. get_le32(pb);
  646. get_le32(pb);
  647. get_le32(pb);
  648. asf->packet_size = get_le32(pb);
  649. get_le32(pb);
  650. get_le32(pb);
  651. } else if (!memcmp(&g, &stream_header, sizeof(GUID))) {
  652. int type, id, total_size;
  653. unsigned int tag1;
  654. INT64 pos1, pos2;
  655. pos1 = url_ftell(pb);
  656. st = av_mallocz(sizeof(AVStream));
  657. if (!st)
  658. goto fail;
  659. s->streams[s->nb_streams++] = st;
  660. asf_st = av_mallocz(sizeof(ASFStream));
  661. if (!asf_st)
  662. goto fail;
  663. st->priv_data = asf_st;
  664. get_guid(pb, &g);
  665. if (!memcmp(&g, &audio_stream, sizeof(GUID))) {
  666. type = CODEC_TYPE_AUDIO;
  667. } else if (!memcmp(&g, &video_stream, sizeof(GUID))) {
  668. type = CODEC_TYPE_VIDEO;
  669. } else {
  670. goto fail;
  671. }
  672. get_guid(pb, &g);
  673. total_size = get_le64(pb);
  674. get_le32(pb);
  675. get_le32(pb);
  676. st->id = get_le16(pb); /* stream id */
  677. get_le32(pb);
  678. st->codec.codec_type = type;
  679. if (type == CODEC_TYPE_AUDIO) {
  680. id = get_le16(pb);
  681. st->codec.codec_tag = id;
  682. st->codec.channels = get_le16(pb);
  683. st->codec.sample_rate = get_le32(pb);
  684. st->codec.bit_rate = get_le32(pb) * 8;
  685. get_le16(pb); /* block align */
  686. bps = get_le16(pb); /* bits per sample */
  687. st->codec.codec_id = wav_codec_get_id(id, bps);
  688. size = get_le16(pb);
  689. url_fskip(pb, size);
  690. /* We have to init the frame size at some point .... */
  691. switch (st->codec.codec_id) {
  692. case CODEC_ID_MP3LAME:
  693. st->codec.frame_size = MPA_FRAME_SIZE;
  694. break;
  695. case CODEC_ID_PCM_S16LE:
  696. case CODEC_ID_PCM_S16BE:
  697. case CODEC_ID_PCM_U16LE:
  698. case CODEC_ID_PCM_U16BE:
  699. case CODEC_ID_PCM_S8:
  700. case CODEC_ID_PCM_U8:
  701. case CODEC_ID_PCM_ALAW:
  702. case CODEC_ID_PCM_MULAW:
  703. st->codec.frame_size = 1;
  704. break;
  705. default:
  706. /* This is probably wrong, but it prevents a crash later */
  707. st->codec.frame_size = 1;
  708. break;
  709. }
  710. } else {
  711. get_le32(pb);
  712. get_le32(pb);
  713. get_byte(pb);
  714. size = get_le16(pb); /* size */
  715. get_le32(pb); /* size */
  716. st->codec.width = get_le32(pb);
  717. st->codec.height = get_le32(pb);
  718. st->codec.frame_rate = 25 * FRAME_RATE_BASE; /* XXX: find it */
  719. get_le16(pb); /* panes */
  720. get_le16(pb); /* depth */
  721. tag1 = get_le32(pb);
  722. st->codec.codec_tag = tag1;
  723. st->codec.codec_id = codec_get_id(codec_asf_bmp_tags, tag1);
  724. url_fskip(pb, size - 5 * 4);
  725. }
  726. pos2 = url_ftell(pb);
  727. url_fskip(pb, gsize - (pos2 - pos1 + 24));
  728. } else if (!memcmp(&g, &data_header, sizeof(GUID))) {
  729. break;
  730. } else if (!memcmp(&g, &comment_header, sizeof(GUID))) {
  731. int len1, len2, len3, len4, len5;
  732. len1 = get_le16(pb);
  733. len2 = get_le16(pb);
  734. len3 = get_le16(pb);
  735. len4 = get_le16(pb);
  736. len5 = get_le16(pb);
  737. get_str16_nolen(pb, len1, s->title, sizeof(s->title));
  738. get_str16_nolen(pb, len2, s->author, sizeof(s->author));
  739. get_str16_nolen(pb, len3, s->copyright, sizeof(s->copyright));
  740. get_str16_nolen(pb, len4, s->comment, sizeof(s->comment));
  741. url_fskip(pb, len5);
  742. #if 0
  743. } else if (!memcmp(&g, &head1_guid, sizeof(GUID))) {
  744. int v1, v2;
  745. get_guid(pb, &g);
  746. v1 = get_le32(pb);
  747. v2 = get_le16(pb);
  748. } else if (!memcmp(&g, &codec_comment_header, sizeof(GUID))) {
  749. int len, v1, n, num;
  750. char str[256], *q;
  751. char tag[16];
  752. get_guid(pb, &g);
  753. print_guid(&g);
  754. n = get_le32(pb);
  755. for(i=0;i<n;i++) {
  756. num = get_le16(pb); /* stream number */
  757. get_str16(pb, str, sizeof(str));
  758. get_str16(pb, str, sizeof(str));
  759. len = get_le16(pb);
  760. q = tag;
  761. while (len > 0) {
  762. v1 = get_byte(pb);
  763. if ((q - tag) < sizeof(tag) - 1)
  764. *q++ = v1;
  765. len--;
  766. }
  767. *q = '\0';
  768. }
  769. #endif
  770. } else if (url_feof(pb)) {
  771. goto fail;
  772. } else {
  773. url_fseek(pb, gsize - 24, SEEK_CUR);
  774. }
  775. }
  776. get_guid(pb, &g);
  777. get_le64(pb);
  778. get_byte(pb);
  779. get_byte(pb);
  780. asf->packet_size_left = 0;
  781. return 0;
  782. fail:
  783. for(i=0;i<s->nb_streams;i++) {
  784. AVStream *st = s->streams[i];
  785. if (st)
  786. av_free(st->priv_data);
  787. av_free(st);
  788. }
  789. //av_free(asf);
  790. return -1;
  791. }
  792. static int asf_get_packet(AVFormatContext *s)
  793. {
  794. ASFContext *asf = s->priv_data;
  795. ByteIOContext *pb = &s->pb;
  796. int c, flags, timestamp, hdr_size;
  797. hdr_size = 12;
  798. c = get_byte(pb);
  799. if (c != 0x82)
  800. return -EIO;
  801. get_le16(pb);
  802. flags = get_byte(pb);
  803. get_byte(pb);
  804. asf->packet_padsize = 0;
  805. if (flags & 0x10) {
  806. asf->packet_padsize = get_le16(pb);
  807. hdr_size += 2;
  808. } else if (flags & 0x08) {
  809. asf->packet_padsize = get_byte(pb);
  810. hdr_size++;
  811. }
  812. timestamp = get_le32(pb);
  813. get_le16(pb); /* duration */
  814. get_byte(pb); /* nb_frames */
  815. #ifdef DEBUG
  816. printf("packet: size=%d padsize=%d\n", asf->packet_size, asf->packet_padsize);
  817. #endif
  818. asf->packet_size_left = asf->packet_size - hdr_size;
  819. return 0;
  820. }
  821. static int asf_read_packet(AVFormatContext *s, AVPacket *pkt)
  822. {
  823. ASFContext *asf = s->priv_data;
  824. AVStream *st;
  825. ASFStream *asf_st;
  826. ByteIOContext *pb = &s->pb;
  827. int ret, num, seq, frag_offset, payload_size, frag_len;
  828. int key_frame;
  829. int timestamp, i;
  830. for(;;) {
  831. if (asf->packet_size_left < FRAME_HEADER_SIZE ||
  832. asf->packet_size_left <= asf->packet_padsize) {
  833. /* fail safe */
  834. if (asf->packet_size_left)
  835. url_fskip(pb, asf->packet_size_left);
  836. ret = asf_get_packet(s);
  837. if (ret < 0)
  838. return -EIO;
  839. }
  840. /* read frame header */
  841. num = get_byte(pb);
  842. if (num & 0x80)
  843. key_frame = 1;
  844. else
  845. key_frame = 0;
  846. num &= 0x7f;
  847. seq = get_byte(pb);
  848. frag_offset = get_le32(pb);
  849. get_byte(pb); /* flags */
  850. payload_size = get_le32(pb);
  851. timestamp = get_le32(pb);
  852. frag_len = get_le16(pb);
  853. #ifdef DEBUG
  854. printf("num=%d seq=%d totsize=%d frag_off=%d frag_size=%d\n",
  855. num, seq, payload_size, frag_offset, frag_len);
  856. #endif
  857. st = NULL;
  858. for(i=0;i<s->nb_streams;i++) {
  859. st = s->streams[i];
  860. if (st->id == num)
  861. break;
  862. }
  863. asf->packet_size_left -= FRAME_HEADER_SIZE + frag_len;
  864. if (i == s->nb_streams) {
  865. /* unhandled packet (should not happen) */
  866. url_fskip(pb, frag_len);
  867. } else {
  868. asf_st = st->priv_data;
  869. if (asf_st->frag_offset == 0) {
  870. /* new packet */
  871. av_new_packet(&asf_st->pkt, payload_size);
  872. asf_st->seq = seq;
  873. if (key_frame)
  874. asf_st->pkt.flags |= PKT_FLAG_KEY;
  875. asf_st->pkt.pts = timestamp;
  876. } else {
  877. if (seq == asf_st->seq &&
  878. frag_offset == asf_st->frag_offset) {
  879. /* continuing packet */
  880. } else {
  881. /* cannot continue current packet: free it */
  882. av_free_packet(&asf_st->pkt);
  883. asf_st->frag_offset = 0;
  884. if (frag_offset != 0) {
  885. /* cannot create new packet */
  886. url_fskip(pb, frag_len);
  887. goto next_frame;
  888. } else {
  889. /* create new packet */
  890. av_new_packet(&asf_st->pkt, payload_size);
  891. asf_st->seq = seq;
  892. }
  893. }
  894. }
  895. /* read data */
  896. get_buffer(pb, asf_st->pkt.data + frag_offset, frag_len);
  897. asf_st->frag_offset += frag_len;
  898. /* test if whole packet read */
  899. if (asf_st->frag_offset == asf_st->pkt.size) {
  900. /* return packet */
  901. asf_st->pkt.stream_index = i;
  902. asf_st->frag_offset = 0;
  903. memcpy(pkt, &asf_st->pkt, sizeof(AVPacket));
  904. break;
  905. }
  906. }
  907. next_frame:;
  908. }
  909. return 0;
  910. }
  911. static int asf_read_close(AVFormatContext *s)
  912. {
  913. //ASFContext *asf = s->priv_data;
  914. int i;
  915. for(i=0;i<s->nb_streams;i++) {
  916. AVStream *st = s->streams[i];
  917. av_free(st->priv_data);
  918. }
  919. //av_free(asf);
  920. return 0;
  921. }
  922. AVInputFormat asf_iformat = {
  923. "asf",
  924. "asf format",
  925. sizeof(ASFContext),
  926. asf_probe,
  927. asf_read_header,
  928. asf_read_packet,
  929. asf_read_close,
  930. };
  931. AVOutputFormat asf_oformat = {
  932. "asf",
  933. "asf format",
  934. "application/octet-stream",
  935. "asf,wmv",
  936. sizeof(ASFContext),
  937. #ifdef CONFIG_MP3LAME
  938. CODEC_ID_MP3LAME,
  939. #else
  940. CODEC_ID_MP2,
  941. #endif
  942. CODEC_ID_MSMPEG4,
  943. asf_write_header,
  944. asf_write_packet,
  945. asf_write_trailer,
  946. };
  947. AVOutputFormat asf_stream_oformat = {
  948. "asf_stream",
  949. "asf format",
  950. "application/octet-stream",
  951. "asf,wmv",
  952. sizeof(ASFContext),
  953. #ifdef CONFIG_MP3LAME
  954. CODEC_ID_MP3LAME,
  955. #else
  956. CODEC_ID_MP2,
  957. #endif
  958. CODEC_ID_MSMPEG4,
  959. asf_write_stream_header,
  960. asf_write_packet,
  961. asf_write_trailer,
  962. };
  963. int asf_init(void)
  964. {
  965. av_register_input_format(&asf_iformat);
  966. av_register_output_format(&asf_oformat);
  967. av_register_output_format(&asf_stream_oformat);
  968. return 0;
  969. }