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.

989 lines
28KB

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