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.

859 lines
25KB

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