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.

827 lines
24KB

  1. /*
  2. * MOV, 3GP, MP4 encoder.
  3. * Copyright (c) 2003 Thomas Raivio.
  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 "avio.h"
  21. #include <time.h>
  22. #undef NDEBUG
  23. #include <assert.h>
  24. /*
  25. * Limitations
  26. * - Currently supports h.263, MPEG4 video codecs, and AMR audio codec.
  27. */
  28. #define MOV_INDEX_CLUSTER_SIZE 16384
  29. #define globalTimescale 1000
  30. typedef struct MOVIentry {
  31. unsigned int flags, pos, len;
  32. unsigned int entries;
  33. } MOVIentry;
  34. typedef struct MOVIndex {
  35. int entry;
  36. int samples;
  37. int mdat_size;
  38. offset_t mdat_pos;
  39. int ents_allocated;
  40. long timescale;
  41. long time;
  42. long frameDuration;
  43. long sampleDelta;
  44. int trackID;
  45. AVCodecContext *enc;
  46. int vosLen;
  47. uint8_t *vosData;
  48. MOVIentry** cluster;
  49. } MOVTrack;
  50. typedef struct {
  51. long time;
  52. int nb_streams;
  53. offset_t movi_list;
  54. long timescale;
  55. MOVTrack tracks[MAX_STREAMS];
  56. } MOVContext;
  57. //FIXME supprt 64bit varaint with wide placeholders
  58. static int updateSize (ByteIOContext *pb, int pos)
  59. {
  60. long curpos = url_ftell(pb);
  61. url_fseek(pb, pos, SEEK_SET);
  62. put_be32(pb, curpos - pos); /* rewrite size */
  63. url_fseek(pb, curpos, SEEK_SET);
  64. return curpos - pos;
  65. }
  66. static int mov_write_stco_tag(ByteIOContext *pb, MOVTrack* track)
  67. {
  68. int i;
  69. put_be32(pb, 16+track->entry*4); /* size */
  70. put_tag(pb, "stco");
  71. put_be32(pb, 0); /* version & flags */
  72. put_be32(pb, track->entry); /* entry count */
  73. for (i=0; i<track->entry; i++) {
  74. int cl = i / MOV_INDEX_CLUSTER_SIZE;
  75. int id = i % MOV_INDEX_CLUSTER_SIZE;
  76. put_be32(pb, track->cluster[cl][id].pos);
  77. }
  78. return 16+track->entry*4;
  79. }
  80. static int mov_write_stsz_tag(ByteIOContext *pb, MOVTrack* track)
  81. {
  82. int i, size;
  83. if(track->cluster[0][0].entries != 0)
  84. size = 20;
  85. else
  86. size = 20+track->samples*4;
  87. put_be32(pb, size); /* size */
  88. put_tag(pb, "stsz");
  89. put_be32(pb, 0); /* version & flags */
  90. /* TODO: Ugly (and false) assumption: if we have a chunk of samples, assume
  91. * all sizes are same */
  92. if(track->cluster[0][0].entries != 0) {
  93. int sSize = track->cluster[0][0].len/track->cluster[0][0].entries;
  94. put_be32(pb, sSize); /* sample size */
  95. put_be32(pb, track->samples); /* sample count */
  96. }
  97. else
  98. {
  99. put_be32(pb, 0); /* sample size */
  100. put_be32(pb, track->samples); /* sample count */
  101. for (i=0; i<track->samples; i++) {
  102. int cl = i / MOV_INDEX_CLUSTER_SIZE;
  103. int id = i % MOV_INDEX_CLUSTER_SIZE;
  104. put_be32(pb, track->cluster[cl][id].len);
  105. }
  106. }
  107. return size;
  108. }
  109. static int mov_write_stsc_tag(ByteIOContext *pb, MOVTrack* track)
  110. {
  111. int size;
  112. if(track->cluster[0][0].entries != 0)
  113. size = 16+track->entry*4*3;
  114. else
  115. size = 0x1c;
  116. put_be32(pb, size); // size
  117. put_tag(pb, "stsc");
  118. put_be32(pb, 0); // version & flags
  119. if(track->cluster[0][0].entries != 0) {
  120. int i;
  121. put_be32(pb, track->entry); // entry count
  122. for (i=0; i<track->entry; i++) {
  123. int cl = i / MOV_INDEX_CLUSTER_SIZE;
  124. int id = i % MOV_INDEX_CLUSTER_SIZE;
  125. put_be32(pb, i+1); // first chunk
  126. put_be32(pb, track->cluster[cl][id].entries);
  127. put_be32(pb, 0x1); // sample description index
  128. }
  129. }
  130. else {
  131. put_be32(pb, 1); // entry count
  132. put_be32(pb, 0x1); // first chunk
  133. put_be32(pb, 0x1); // samples per chunk
  134. put_be32(pb, 0x1); // sample description index
  135. }
  136. return size;
  137. }
  138. //FIXME keyframes?
  139. static int mov_write_stss_tag(ByteIOContext *pb) //TRA OK
  140. {
  141. put_be32(pb, 0x14); /* size */
  142. put_tag(pb, "stss");
  143. put_be32(pb, 0); /* version & flags */
  144. put_be32(pb, 1); /* entry count */
  145. put_be32(pb, 0x1); /* sample number */
  146. return 0x14;
  147. }
  148. static int mov_write_damr_tag(ByteIOContext *pb)
  149. {
  150. put_be32(pb, 0x11); /* size */
  151. put_tag(pb, "damr");
  152. put_tag(pb, "FFMP");
  153. put_byte(pb, 0);
  154. put_be16(pb, 0x81ff); /* Mode set (all modes for AMR_NB) */
  155. put_be16(pb, 1); /* Mode change period (no restriction) */
  156. return 0x11;
  157. }
  158. static int mov_write_samr_tag(ByteIOContext *pb, MOVTrack* track)
  159. {
  160. int pos = url_ftell(pb);
  161. put_be32(pb, 0); /* size */
  162. /* "samr" for AMR NB, "sawb" for AMR WB */
  163. put_tag(pb, "samr");
  164. put_be32(pb, 0); /* Reserved */
  165. put_be16(pb, 0); /* Reserved */
  166. put_be16(pb, 1); /* Data-reference index, XXX == 1 */
  167. put_be32(pb, 0); /* Reserved */
  168. put_be32(pb, 0); /* Reserved */
  169. put_be16(pb, 2); /* Reserved */
  170. put_be16(pb, 0x10); /* Reserved */
  171. put_be32(pb, 0); /* Reserved */
  172. put_be16(pb, track->timescale); /* Time scale */
  173. put_be16(pb, 0); /* Reserved */
  174. mov_write_damr_tag(pb);
  175. return updateSize (pb, pos);
  176. }
  177. static int mov_write_d263_tag(ByteIOContext *pb)
  178. {
  179. put_be32(pb, 0xf); /* size */
  180. put_tag(pb, "d263");
  181. put_tag(pb, "FFMP");
  182. put_be16(pb, 0x0a);
  183. put_byte(pb, 0);
  184. return 0xf;
  185. }
  186. static int mov_write_s263_tag(ByteIOContext *pb, MOVTrack* track)
  187. {
  188. int pos = url_ftell(pb);
  189. put_be32(pb, 0); /* size */
  190. put_tag(pb, "s263");
  191. put_be32(pb, 0); /* Reserved */
  192. put_be16(pb, 0); /* Reserved */
  193. put_be16(pb, 1); /* Data-reference index */
  194. put_be32(pb, 0); /* Reserved */
  195. put_be32(pb, 0); /* Reserved */
  196. put_be32(pb, 0); /* Reserved */
  197. put_be32(pb, 0); /* Reserved */
  198. put_be16(pb, track->enc->width); /* Video width */
  199. put_be16(pb, track->enc->height); /* Video height */
  200. put_be32(pb, 0x00480000); /* Reserved */
  201. put_be32(pb, 0x00480000); /* Reserved */
  202. put_be32(pb, 0); /* Reserved */
  203. put_be16(pb, 1); /* Reserved */
  204. put_be32(pb, 0); /* Reserved */
  205. put_be32(pb, 0); /* Reserved */
  206. put_be32(pb, 0); /* Reserved */
  207. put_be32(pb, 0); /* Reserved */
  208. put_be32(pb, 0); /* Reserved */
  209. put_be32(pb, 0); /* Reserved */
  210. put_be32(pb, 0); /* Reserved */
  211. put_be32(pb, 0); /* Reserved */
  212. put_be16(pb, 0x18); /* Reserved */
  213. put_be16(pb, 0xffff); /* Reserved */
  214. mov_write_d263_tag(pb);
  215. return updateSize (pb, pos);
  216. }
  217. static unsigned int esdsLength(unsigned int len)
  218. {
  219. unsigned int result = 0;
  220. unsigned char b = len & 0x7f;
  221. result += b;
  222. b = (len >> 8) & 0x7f;
  223. result += (b + 0x80) << 8;
  224. b = (len >> 16) & 0x7f;
  225. result += (b + 0x80) << 16;
  226. b = (len >> 24) & 0x7f;
  227. result += (b + 0x80) << 24;
  228. return result;
  229. }
  230. static int mov_write_esds_tag(ByteIOContext *pb, MOVTrack* track) // Basic
  231. {
  232. put_be32(pb, track->vosLen+18+14+17);
  233. put_tag(pb, "esds");
  234. put_be32(pb, 0); // Version
  235. put_byte(pb, 0x03); // tag = ES_DescriptorTag
  236. put_be32(pb, esdsLength(track->vosLen+18+14)); // Length
  237. put_be16(pb, 0x0001); // ID (= 1)
  238. put_byte(pb, 0x00); // flags (= no flags)
  239. // Decoderconfigdescriptor = 4
  240. put_byte(pb, 0x04); // tag = DecoderConfigDescriptor
  241. put_be32(pb, esdsLength(track->vosLen+18)); // Length
  242. put_byte(pb, 0x20); // Object type indication (Visual 14496-2)
  243. put_byte(pb, 0x11); // flags (= Visualstream)
  244. put_byte(pb, 0x0); // Buffersize DB (24 bits)
  245. put_be16(pb, 0x0dd2); // Buffersize DB
  246. // TODO: find real values for these
  247. put_be32(pb, 0x0002e918); // maxbitrate
  248. put_be32(pb, 0x00017e6b); // avg bitrate
  249. // Decoderspecific info Tag = 5
  250. put_byte(pb, 0x05); // tag = Decoderspecific info
  251. put_be32(pb, esdsLength(track->vosLen)); // length
  252. put_buffer(pb, track->vosData, track->vosLen);
  253. put_byte(pb, 0x06);
  254. put_be32(pb, esdsLength(1)); // length
  255. put_byte(pb, 0x02);
  256. return track->vosLen+18+14+17;
  257. }
  258. static int mov_write_mp4v_tag(ByteIOContext *pb, MOVTrack* track) // Basic
  259. {
  260. int pos = url_ftell(pb);
  261. put_be32(pb, 0);
  262. put_tag(pb, "mp4v");
  263. put_be32(pb, 0); // Reserved
  264. put_be16(pb, 0); // Reserved
  265. put_be16(pb, 1); // Data-reference index
  266. put_be32(pb, 0); // Reserved
  267. put_be32(pb, 0); // Reserved
  268. put_be32(pb, 0); // Reserved
  269. put_be32(pb, 0); // Reserved
  270. put_be16(pb, track->enc->width); // Width
  271. put_be16(pb, track->enc->height); // Height
  272. put_be32(pb, 0x00480000); // Reserved
  273. put_be32(pb, 0x00480000); // Reserved
  274. put_be32(pb, 0); // Reserved
  275. put_be16(pb, 1); // Reserved
  276. put_be32(pb, 0); // Reserved
  277. put_be32(pb, 0); // Reserved
  278. put_be32(pb, 0); // Reserved
  279. put_be32(pb, 0); // Reserved
  280. put_be32(pb, 0); // Reserved
  281. put_be32(pb, 0); // Reserved
  282. put_be32(pb, 0); // Reserved
  283. put_be32(pb, 0); // Reserved
  284. put_be16(pb, 24); // Reserved
  285. put_be16(pb, 0xFFFF); // Reserved
  286. mov_write_esds_tag(pb, track);
  287. return updateSize(pb, pos);
  288. }
  289. static int mov_write_stsd_tag(ByteIOContext *pb, MOVTrack* track)
  290. {
  291. int pos = url_ftell(pb);
  292. put_be32(pb, 0); /* size */
  293. put_tag(pb, "stsd");
  294. put_be32(pb, 0); /* version & flags */
  295. put_be32(pb, 1); /* entry count */
  296. if (track->enc->codec_type == CODEC_TYPE_VIDEO) {
  297. if (track->enc->codec_id == CODEC_ID_H263)
  298. mov_write_s263_tag(pb, track);
  299. else if (track->enc->codec_id == CODEC_ID_MPEG4)
  300. mov_write_mp4v_tag(pb, track);
  301. }
  302. else if (track->enc->codec_type == CODEC_TYPE_AUDIO) {
  303. if (track->enc->codec_id == CODEC_ID_AMR_NB)
  304. mov_write_samr_tag(pb, track);
  305. }
  306. return updateSize(pb, pos);
  307. }
  308. static int mov_write_stts_tag(ByteIOContext *pb, MOVTrack* track)
  309. {
  310. put_be32(pb, 0x18); /* size */
  311. put_tag(pb, "stts");
  312. put_be32(pb, 0); /* version & flags */
  313. put_be32(pb, 1); /* entry count */
  314. put_be32(pb, track->samples); /* sample count */
  315. put_be32(pb, track->sampleDelta); /* sample delta */
  316. return 0x18;
  317. }
  318. static int mov_write_dref_tag(ByteIOContext *pb)
  319. {
  320. put_be32(pb, 28); /* size */
  321. put_tag(pb, "dref");
  322. put_be32(pb, 0); /* version & flags */
  323. put_be32(pb, 1); /* entry count */
  324. put_be32(pb, 0xc); /* size */
  325. put_tag(pb, "url ");
  326. put_be32(pb, 1); /* version & flags */
  327. return 28;
  328. }
  329. static int mov_write_stbl_tag(ByteIOContext *pb, MOVTrack* track)
  330. {
  331. int pos = url_ftell(pb);
  332. put_be32(pb, 0); /* size */
  333. put_tag(pb, "stbl");
  334. mov_write_stsd_tag(pb, track);
  335. mov_write_stts_tag(pb, track);
  336. if (track->enc->codec_type == CODEC_TYPE_VIDEO)
  337. mov_write_stss_tag(pb);
  338. mov_write_stsc_tag(pb, track);
  339. mov_write_stsz_tag(pb, track);
  340. mov_write_stco_tag(pb, track);
  341. return updateSize(pb, pos);
  342. }
  343. static int mov_write_dinf_tag(ByteIOContext *pb)
  344. {
  345. int pos = url_ftell(pb);
  346. put_be32(pb, 0); /* size */
  347. put_tag(pb, "dinf");
  348. mov_write_dref_tag(pb);
  349. return updateSize(pb, pos);
  350. }
  351. static int mov_write_smhd_tag(ByteIOContext *pb)
  352. {
  353. put_be32(pb, 16); /* size */
  354. put_tag(pb, "smhd");
  355. put_be32(pb, 0); /* version & flags */
  356. put_be16(pb, 0); /* reserved (balance, normally = 0) */
  357. put_be16(pb, 0); /* reserved */
  358. return 16;
  359. }
  360. static int mov_write_vmhd_tag(ByteIOContext *pb)
  361. {
  362. put_be32(pb, 0x14); /* size (always 0x14) */
  363. put_tag(pb, "vmhd");
  364. put_be32(pb, 0x01); /* version & flags */
  365. put_be64(pb, 0); /* reserved (graphics mode = copy) */
  366. return 0x14;
  367. }
  368. static int mov_write_minf_tag(ByteIOContext *pb, MOVTrack* track)
  369. {
  370. int pos = url_ftell(pb);
  371. put_be32(pb, 0); /* size */
  372. put_tag(pb, "minf");
  373. if(track->enc->codec_type == CODEC_TYPE_VIDEO)
  374. mov_write_vmhd_tag(pb);
  375. else
  376. mov_write_smhd_tag(pb);
  377. mov_write_dinf_tag(pb);
  378. mov_write_stbl_tag(pb, track);
  379. return updateSize(pb, pos);
  380. }
  381. static int mov_write_hdlr_tag(ByteIOContext *pb, MOVTrack* track)
  382. {
  383. int size = 0;
  384. size = 45;
  385. put_be32(pb, size); /* size */
  386. put_tag(pb, "hdlr");
  387. put_be32(pb, 0); /* Version & flags */
  388. put_be32(pb, 0); /* reserved */
  389. if(track->enc->codec_type == CODEC_TYPE_VIDEO)
  390. put_tag(pb, "vide"); /* handler type */
  391. else
  392. put_tag(pb, "soun"); /* handler type */
  393. put_byte(pb, 0); /* reserved */
  394. put_byte(pb, 0); /* reserved */
  395. put_byte(pb, 0); /* reserved */
  396. put_byte(pb, 0); /* reserved */
  397. put_byte(pb, 0); /* reserved */
  398. put_byte(pb, 0); /* reserved */
  399. put_byte(pb, 0); /* reserved */
  400. put_byte(pb, 0); /* reserved */
  401. put_byte(pb, 0); /* reserved */
  402. put_byte(pb, 0); /* reserved */
  403. put_byte(pb, 0); /* reserved */
  404. put_byte(pb, 0); /* reserved */
  405. if(track->enc->codec_type == CODEC_TYPE_VIDEO)
  406. put_buffer(pb, "VideoHandler", 13);
  407. else
  408. put_buffer(pb, "SoundHandler", 13);
  409. return size;
  410. }
  411. static int mov_write_mdhd_tag(ByteIOContext *pb, MOVTrack* track)
  412. {
  413. put_be32(pb, 32); /* size */
  414. put_tag(pb, "mdhd");
  415. put_be32(pb, 0); /* Version & flags */
  416. put_be32(pb, track->time); /* creation time */
  417. put_be32(pb, track->time); /* modification time */
  418. put_be32(pb, track->timescale); /* time scale */
  419. put_be32(pb, track->timescale*track->entry*track->frameDuration/globalTimescale); /* duration */
  420. put_be16(pb, 0); /* language, 0 = english */
  421. put_be16(pb, 0); /* reserved (quality) */
  422. return 32;
  423. }
  424. static int mov_write_mdia_tag(ByteIOContext *pb, MOVTrack* track)
  425. {
  426. int pos = url_ftell(pb);
  427. put_be32(pb, 0); /* size */
  428. put_tag(pb, "mdia");
  429. mov_write_mdhd_tag(pb, track);
  430. mov_write_hdlr_tag(pb, track);
  431. mov_write_minf_tag(pb, track);
  432. return updateSize(pb, pos);
  433. }
  434. static int mov_write_tkhd_tag(ByteIOContext *pb, MOVTrack* track)
  435. {
  436. put_be32(pb, 0x5c); /* size (always 0x5c) */
  437. put_tag(pb, "tkhd");
  438. put_be32(pb, 1); /* version & flags (track enabled) */
  439. put_be32(pb, track->time); /* creation time */
  440. put_be32(pb, track->time); /* modification time */
  441. put_be32(pb, track->trackID); /* track-id */
  442. put_be32(pb, 0); /* reserved */
  443. put_be32(pb, track->entry*track->frameDuration); /* duration */
  444. put_be32(pb, 0); /* reserved */
  445. put_be32(pb, 0); /* reserved */
  446. put_be32(pb, 0x0); /* reserved (Layer & Alternate group) */
  447. /* Volume, only for audio */
  448. if(track->enc->codec_type == CODEC_TYPE_AUDIO)
  449. put_be16(pb, 0x0100);
  450. else
  451. put_be16(pb, 0);
  452. put_be16(pb, 0); /* reserved */
  453. /* Matrix structure */
  454. put_be32(pb, 0x00010000); /* reserved */
  455. put_be32(pb, 0x0); /* reserved */
  456. put_be32(pb, 0x0); /* reserved */
  457. put_be32(pb, 0x0); /* reserved */
  458. put_be32(pb, 0x00010000); /* reserved */
  459. put_be32(pb, 0x0); /* reserved */
  460. put_be32(pb, 0x0); /* reserved */
  461. put_be32(pb, 0x0); /* reserved */
  462. put_be32(pb, 0x40000000); /* reserved */
  463. /* Track width and height, for visual only */
  464. if(track->enc->codec_type == CODEC_TYPE_VIDEO) {
  465. put_be32(pb, 0x01400000);
  466. put_be32(pb, 0x00f00000);
  467. }
  468. else {
  469. put_be32(pb, 0);
  470. put_be32(pb, 0);
  471. }
  472. return 0x5c;
  473. }
  474. static int mov_write_trak_tag(ByteIOContext *pb, MOVTrack* track)
  475. {
  476. int pos = url_ftell(pb);
  477. put_be32(pb, 0); /* size */
  478. put_tag(pb, "trak");
  479. mov_write_tkhd_tag(pb, track);
  480. mov_write_mdia_tag(pb, track);
  481. return updateSize(pb, pos);
  482. }
  483. /* TODO: Not sorted out, but not necessary either */
  484. static int mov_write_iods_tag(ByteIOContext *pb, MOVContext *mov)
  485. {
  486. put_be32(pb, 0x15); /* size */
  487. put_tag(pb, "iods");
  488. put_be32(pb, 0); /* version & flags */
  489. put_be16(pb, 0x1007);
  490. put_byte(pb, 0);
  491. put_be16(pb, 0x4fff);
  492. put_be16(pb, 0xfffe);
  493. put_be16(pb, 0x01ff);
  494. return 0x15;
  495. }
  496. static int mov_write_mvhd_tag(ByteIOContext *pb, MOVContext *mov)
  497. {
  498. int maxTrackID = 1, maxTrackLen = 0, i;
  499. put_be32(pb, 0x6c); /* size (always 0x6c) */
  500. put_tag(pb, "mvhd");
  501. put_be32(pb, 0); /* version & flags */
  502. put_be32(pb, mov->time); /* creation time */
  503. put_be32(pb, mov->time); /* modification time */
  504. put_be32(pb, mov->timescale); /* timescale */
  505. for (i=0; i<MAX_STREAMS; i++) {
  506. if(mov->tracks[i].entry > 0) {
  507. if(maxTrackLen < mov->tracks[i].entry*mov->tracks[i].frameDuration)
  508. maxTrackLen = mov->tracks[i].entry*mov->tracks[i].frameDuration;
  509. if(maxTrackID < mov->tracks[i].trackID)
  510. maxTrackID = mov->tracks[i].trackID;
  511. }
  512. }
  513. put_be32(pb, maxTrackLen); /* duration of longest track */
  514. put_be32(pb, 0x00010000); /* reserved (preferred rate) 1.0 = normal */
  515. put_be16(pb, 0x0100); /* reserved (preferred volume) 1.0 = normal */
  516. put_be16(pb, 0); /* reserved */
  517. put_be32(pb, 0); /* reserved */
  518. put_be32(pb, 0); /* reserved */
  519. /* Matrix structure */
  520. put_be32(pb, 0x00010000); /* reserved */
  521. put_be32(pb, 0x0); /* reserved */
  522. put_be32(pb, 0x0); /* reserved */
  523. put_be32(pb, 0x0); /* reserved */
  524. put_be32(pb, 0x00010000); /* reserved */
  525. put_be32(pb, 0x0); /* reserved */
  526. put_be32(pb, 0x0); /* reserved */
  527. put_be32(pb, 0x0); /* reserved */
  528. put_be32(pb, 0x40000000); /* reserved */
  529. put_be32(pb, 0); /* reserved (preview time) */
  530. put_be32(pb, 0); /* reserved (preview duration) */
  531. put_be32(pb, 0); /* reserved (poster time) */
  532. put_be32(pb, 0); /* reserved (selection time) */
  533. put_be32(pb, 0); /* reserved (selection duration) */
  534. put_be32(pb, 0); /* reserved (current time) */
  535. put_be32(pb, maxTrackID+1); /* Next track id */
  536. return 0x6c;
  537. }
  538. static int mov_write_moov_tag(ByteIOContext *pb, MOVContext *mov)
  539. {
  540. int pos, i;
  541. pos = url_ftell(pb);
  542. put_be32(pb, 0); /* size placeholder*/
  543. put_tag(pb, "moov");
  544. mov->timescale = globalTimescale;
  545. for (i=0; i<MAX_STREAMS; i++) {
  546. if(mov->tracks[i].entry > 0) {
  547. if(mov->tracks[i].enc->codec_type == CODEC_TYPE_VIDEO) {
  548. mov->tracks[i].timescale = globalTimescale;
  549. mov->tracks[i].sampleDelta = mov->tracks[i].frameDuration =
  550. globalTimescale*mov->tracks[i].enc->frame_rate_base/mov->tracks[i].enc->frame_rate;
  551. }
  552. else if(mov->tracks[i].enc->codec_type == CODEC_TYPE_AUDIO) {
  553. /* If AMR, track timescale = 8000, AMR_WB = 16000 */
  554. if(mov->tracks[i].enc->codec_id == CODEC_ID_AMR_NB) {
  555. mov->tracks[i].frameDuration = 20;
  556. mov->tracks[i].sampleDelta = 160;
  557. mov->tracks[i].timescale = 8000;
  558. }
  559. else {
  560. mov->tracks[i].timescale = globalTimescale;
  561. mov->tracks[i].frameDuration =
  562. globalTimescale*mov->tracks[i].enc->frame_rate_base/mov->tracks[i].enc->frame_rate;
  563. }
  564. }
  565. mov->tracks[i].time = mov->time;
  566. mov->tracks[i].trackID = i+1;
  567. }
  568. }
  569. mov_write_mvhd_tag(pb, mov);
  570. //mov_write_iods_tag(pb, mov);
  571. for (i=0; i<MAX_STREAMS; i++) {
  572. if(mov->tracks[i].entry > 0) {
  573. mov_write_trak_tag(pb, &(mov->tracks[i]));
  574. }
  575. }
  576. return updateSize(pb, pos);
  577. }
  578. int mov_write_mdat_tag(ByteIOContext *pb, MOVTrack* track)
  579. {
  580. track->mdat_pos = url_ftell(pb);
  581. put_be32(pb, 0); /* size placeholder*/
  582. put_tag(pb, "mdat");
  583. return 0;
  584. }
  585. /* TODO: This needs to be more general */
  586. int mov_write_ftyp_tag(ByteIOContext *pb)
  587. {
  588. put_be32(pb, 0x14 ); /* size */
  589. put_tag(pb, "ftyp");
  590. put_tag(pb, "3gp4");
  591. put_be32(pb, 0x200 );
  592. put_tag(pb, "3gp4");
  593. return 0x14;
  594. }
  595. static int mov_write_header(AVFormatContext *s)
  596. {
  597. ByteIOContext *pb = &s->pb;
  598. /* write ftyp */
  599. mov_write_ftyp_tag(pb);
  600. put_flush_packet(pb);
  601. return 0;
  602. }
  603. static int Timestamp() {
  604. time_t ltime;
  605. time ( &ltime );
  606. return ltime+(24107*86400);
  607. }
  608. static int mov_write_packet(AVFormatContext *s, int stream_index,
  609. const uint8_t *buf, int size, int64_t pts)
  610. {
  611. MOVContext *mov = s->priv_data;
  612. ByteIOContext *pb = &s->pb;
  613. AVCodecContext *enc;
  614. int cl, id;
  615. enc = &s->streams[stream_index]->codec;
  616. if (!url_is_streamed(&s->pb)) {
  617. MOVTrack* trk = &mov->tracks[stream_index];
  618. int sampleCount = 0;
  619. /* We must find out how many AMR blocks there are in one packet */
  620. if(enc->codec_id == CODEC_ID_AMR_NB) {
  621. static uint16_t packed_size[16] = {13, 14, 16, 18, 20, 21, 27, 32, 6, 0, 0, 0, 0, 0, 0, 0};
  622. int len = 0;
  623. while(len < size && sampleCount < 100) {
  624. len += packed_size[(buf[len] >> 3) & 0x0F];
  625. sampleCount++;
  626. }
  627. }
  628. if(enc->codec_id == CODEC_ID_MPEG4 &&
  629. trk->vosLen == 0)
  630. {
  631. assert(enc->extradata_size);
  632. trk->vosLen = enc->extradata_size;
  633. trk->vosData = av_malloc(trk->vosLen);
  634. memcpy(trk->vosData, enc->extradata, trk->vosLen);
  635. }
  636. cl = trk->entry / MOV_INDEX_CLUSTER_SIZE;
  637. id = trk->entry % MOV_INDEX_CLUSTER_SIZE;
  638. if (trk->ents_allocated <= trk->entry) {
  639. trk->cluster = av_realloc(trk->cluster, (cl+1)*sizeof(void*));
  640. if (!trk->cluster)
  641. return -1;
  642. trk->cluster[cl] = av_malloc(MOV_INDEX_CLUSTER_SIZE*sizeof(MOVIentry));
  643. if (!trk->cluster[cl])
  644. return -1;
  645. trk->ents_allocated += MOV_INDEX_CLUSTER_SIZE;
  646. }
  647. if(stream_index == 0 && trk->entry == 0) {
  648. mov_write_mdat_tag(pb, trk);
  649. mov->time = Timestamp();
  650. }
  651. trk->cluster[cl][id].pos = url_ftell(pb) - mov->movi_list;
  652. trk->cluster[cl][id].len = size;
  653. trk->cluster[cl][id].entries = sampleCount;
  654. trk->enc = enc;
  655. trk->entry++;
  656. if(sampleCount == 0)
  657. trk->samples++;
  658. else
  659. trk->samples += sampleCount;
  660. trk->mdat_size += size;
  661. }
  662. put_buffer(pb, buf, size);
  663. put_flush_packet(pb);
  664. return 0;
  665. }
  666. static int mov_write_trailer(AVFormatContext *s)
  667. {
  668. MOVContext *mov = s->priv_data;
  669. ByteIOContext *pb = &s->pb;
  670. int res = 0;
  671. int i, j;
  672. offset_t file_size;
  673. file_size = url_ftell(pb);
  674. j = 0;
  675. /* Write size of mdat tag */
  676. for (i=0; i<MAX_STREAMS; i++) {
  677. if(mov->tracks[i].ents_allocated > 0) {
  678. j += mov->tracks[i].mdat_size;
  679. }
  680. }
  681. url_fseek(pb, mov->tracks[0].mdat_pos, SEEK_SET);
  682. put_be32(pb, j+8);
  683. url_fseek(pb, file_size, SEEK_SET);
  684. mov_write_moov_tag(pb, mov);
  685. for (i=0; i<MAX_STREAMS; i++) {
  686. for (j=0; j<mov->tracks[i].ents_allocated/MOV_INDEX_CLUSTER_SIZE; j++) {
  687. av_free(mov->tracks[i].cluster[j]);
  688. }
  689. av_free(mov->tracks[i].cluster);
  690. mov->tracks[i].cluster = NULL;
  691. mov->tracks[i].ents_allocated = mov->tracks[i].entry = 0;
  692. }
  693. put_flush_packet(pb);
  694. return res;
  695. }
  696. static AVOutputFormat mov_oformat = {
  697. "mov",
  698. "mov format",
  699. NULL,
  700. "mov",
  701. sizeof(MOVContext),
  702. CODEC_ID_MP2,
  703. CODEC_ID_MPEG4,
  704. mov_write_header,
  705. mov_write_packet,
  706. mov_write_trailer,
  707. };
  708. static AVOutputFormat _3gp_oformat = {
  709. "3gp",
  710. "3gp format",
  711. NULL,
  712. "3gp",
  713. sizeof(MOVContext),
  714. CODEC_ID_AMR_NB,
  715. CODEC_ID_H263,
  716. mov_write_header,
  717. mov_write_packet,
  718. mov_write_trailer,
  719. };
  720. static AVOutputFormat mp4_oformat = {
  721. "mp4",
  722. "mp4 format",
  723. NULL,
  724. "mp4",
  725. sizeof(MOVContext),
  726. CODEC_ID_AAC,
  727. CODEC_ID_MPEG4,
  728. mov_write_header,
  729. mov_write_packet,
  730. mov_write_trailer,
  731. };
  732. int movenc_init(void)
  733. {
  734. av_register_output_format(&mov_oformat);
  735. av_register_output_format(&_3gp_oformat);
  736. av_register_output_format(&mp4_oformat);
  737. return 0;
  738. }