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.

909 lines
28KB

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