comparison movenc.c @ 3143:7f0f50bbfe23 libavformat

ipod/iphone compatible mp4 muxer
author bcoudurier
date Sun, 16 Mar 2008 13:36:36 +0000
parents 19de43025f0f
children 710917feb10a
comparison
equal deleted inserted replaced
3142:8891d470ada3 3143:7f0f50bbfe23
35 #define MODE_MOV 1 35 #define MODE_MOV 1
36 #define MODE_3GP 2 36 #define MODE_3GP 2
37 #define MODE_PSP 3 // example working PSP command line: 37 #define MODE_PSP 3 // example working PSP command line:
38 // ffmpeg -i testinput.avi -f psp -r 14.985 -s 320x240 -b 768 -ar 24000 -ab 32 M4V00001.MP4 38 // ffmpeg -i testinput.avi -f psp -r 14.985 -s 320x240 -b 768 -ar 24000 -ab 32 M4V00001.MP4
39 #define MODE_3G2 4 39 #define MODE_3G2 4
40 #define MODE_IPOD 5
40 41
41 typedef struct MOVIentry { 42 typedef struct MOVIentry {
42 unsigned int flags, size; 43 unsigned int flags, size;
43 uint64_t pos; 44 uint64_t pos;
44 unsigned int samplesInChunk; 45 unsigned int samplesInChunk;
492 }; 493 };
493 494
494 static int mov_find_codec_tag(AVFormatContext *s, MOVTrack *track) 495 static int mov_find_codec_tag(AVFormatContext *s, MOVTrack *track)
495 { 496 {
496 int tag = track->enc->codec_tag; 497 int tag = track->enc->codec_tag;
497 if (track->mode == MODE_MP4 || track->mode == MODE_PSP) { 498 if (track->mode == MODE_MP4 || track->mode == MODE_PSP || track->mode == MODE_IPOD) {
498 if (!codec_get_tag(ff_mp4_obj_type, track->enc->codec_id)) 499 if (!codec_get_tag(ff_mp4_obj_type, track->enc->codec_id))
499 return 0; 500 return 0;
500 if (track->enc->codec_id == CODEC_ID_H264) tag = MKTAG('a','v','c','1'); 501 if (track->enc->codec_id == CODEC_ID_H264) tag = MKTAG('a','v','c','1');
501 else if (track->enc->codec_type == CODEC_TYPE_VIDEO) tag = MKTAG('m','p','4','v'); 502 else if (track->enc->codec_type == CODEC_TYPE_VIDEO) tag = MKTAG('m','p','4','v');
502 else if (track->enc->codec_type == CODEC_TYPE_AUDIO) tag = MKTAG('m','p','4','a'); 503 else if (track->enc->codec_type == CODEC_TYPE_AUDIO) tag = MKTAG('m','p','4','a');
539 } 540 }
540 } 541 }
541 return tag; 542 return tag;
542 } 543 }
543 544
545 /** Write uuid atom.
546 * Needed to make file play in iPods running newest firmware
547 * goes after avcC atom in moov.trak.mdia.minf.stbl.stsd.avc1
548 */
549 static int mov_write_uuid_tag_ipod(ByteIOContext *pb)
550 {
551 put_be32(pb, 28);
552 put_tag(pb, "uuid");
553 put_be32(pb, 0x6b6840f2);
554 put_be32(pb, 0x5f244fc5);
555 put_be32(pb, 0xba39a51b);
556 put_be32(pb, 0xcf0323f3);
557 put_be32(pb, 0x0);
558 return 28;
559 }
560
544 static int mov_write_video_tag(ByteIOContext *pb, MOVTrack* track) 561 static int mov_write_video_tag(ByteIOContext *pb, MOVTrack* track)
545 { 562 {
546 offset_t pos = url_ftell(pb); 563 offset_t pos = url_ftell(pb);
547 char compressor_name[32]; 564 char compressor_name[32];
548 565
591 mov_write_esds_tag(pb, track); 608 mov_write_esds_tag(pb, track);
592 else if(track->enc->codec_id == CODEC_ID_H263) 609 else if(track->enc->codec_id == CODEC_ID_H263)
593 mov_write_d263_tag(pb); 610 mov_write_d263_tag(pb);
594 else if(track->enc->codec_id == CODEC_ID_SVQ3) 611 else if(track->enc->codec_id == CODEC_ID_SVQ3)
595 mov_write_svq3_tag(pb); 612 mov_write_svq3_tag(pb);
596 else if(track->enc->codec_id == CODEC_ID_H264) 613 else if(track->enc->codec_id == CODEC_ID_H264) {
597 mov_write_avcc_tag(pb, track); 614 mov_write_avcc_tag(pb, track);
615 if(track->mode == MODE_IPOD)
616 mov_write_uuid_tag_ipod(pb);
617 }
598 else if(track->enc->codec_id == CODEC_ID_DNXHD) 618 else if(track->enc->codec_id == CODEC_ID_DNXHD)
599 mov_write_avid_tag(pb, track); 619 mov_write_avid_tag(pb, track);
600 else if(track->vosLen > 0) 620 else if(track->vosLen > 0)
601 mov_write_glbl_tag(pb, track); 621 mov_write_glbl_tag(pb, track);
602 622
1353 put_tag(pb, "3gp4"); 1373 put_tag(pb, "3gp4");
1354 else if (mov->mode == MODE_3G2) 1374 else if (mov->mode == MODE_3G2)
1355 put_tag(pb, "3g2a"); 1375 put_tag(pb, "3g2a");
1356 else if (mov->mode == MODE_PSP) 1376 else if (mov->mode == MODE_PSP)
1357 put_tag(pb, "MSNV"); 1377 put_tag(pb, "MSNV");
1358 else if (mov->mode == MODE_MP4) 1378 else if (mov->mode == MODE_MP4 || mov->mode == MODE_IPOD)
1359 put_tag(pb, "isom"); 1379 put_tag(pb, "isom");
1360 else 1380 else
1361 put_tag(pb, "qt "); 1381 put_tag(pb, "qt ");
1362 1382
1363 put_be32(pb, 0x200); 1383 put_be32(pb, 0x200);
1366 put_tag(pb, "3gp4"); 1386 put_tag(pb, "3gp4");
1367 else if (mov->mode == MODE_3G2) 1387 else if (mov->mode == MODE_3G2)
1368 put_tag(pb, "3g2a"); 1388 put_tag(pb, "3g2a");
1369 else if (mov->mode == MODE_PSP) 1389 else if (mov->mode == MODE_PSP)
1370 put_tag(pb, "MSNV"); 1390 put_tag(pb, "MSNV");
1371 else if (mov->mode == MODE_MP4) 1391 else if (mov->mode == MODE_MP4 || mov->mode == MODE_IPOD)
1372 put_tag(pb, "mp41"); 1392 put_tag(pb, "mp41");
1373 else 1393 else
1374 put_tag(pb, "qt "); 1394 put_tag(pb, "qt ");
1375 } 1395 }
1376 1396
1452 if (s->oformat != NULL) { 1472 if (s->oformat != NULL) {
1453 if (!strcmp("3gp", s->oformat->name)) mov->mode = MODE_3GP; 1473 if (!strcmp("3gp", s->oformat->name)) mov->mode = MODE_3GP;
1454 else if (!strcmp("3g2", s->oformat->name)) mov->mode = MODE_3G2; 1474 else if (!strcmp("3g2", s->oformat->name)) mov->mode = MODE_3G2;
1455 else if (!strcmp("mov", s->oformat->name)) mov->mode = MODE_MOV; 1475 else if (!strcmp("mov", s->oformat->name)) mov->mode = MODE_MOV;
1456 else if (!strcmp("psp", s->oformat->name)) mov->mode = MODE_PSP; 1476 else if (!strcmp("psp", s->oformat->name)) mov->mode = MODE_PSP;
1477 else if (!strcmp("ipod",s->oformat->name)) mov->mode = MODE_IPOD;
1457 1478
1458 mov_write_ftyp_tag(pb,s); 1479 mov_write_ftyp_tag(pb,s);
1459 if (mov->mode == MODE_PSP) { 1480 if (mov->mode == MODE_PSP) {
1460 if (s->nb_streams != 2) { 1481 if (s->nb_streams != 2) {
1461 av_log(s, AV_LOG_ERROR, "PSP mode need one video and one audio stream\n"); 1482 av_log(s, AV_LOG_ERROR, "PSP mode need one video and one audio stream\n");
1708 mov_write_trailer, 1729 mov_write_trailer,
1709 .flags = AVFMT_GLOBALHEADER, 1730 .flags = AVFMT_GLOBALHEADER,
1710 .codec_tag = (const AVCodecTag*[]){codec_3gp_tags, 0}, 1731 .codec_tag = (const AVCodecTag*[]){codec_3gp_tags, 0},
1711 }; 1732 };
1712 #endif 1733 #endif
1734 #ifdef CONFIG_IPOD_MUXER
1735 AVOutputFormat ipod_muxer = {
1736 "ipod",
1737 "iPod H.264 mp4 format",
1738 "application/mp4",
1739 NULL,
1740 sizeof(MOVContext),
1741 CODEC_ID_AAC,
1742 CODEC_ID_H264,
1743 mov_write_header,
1744 mov_write_packet,
1745 mov_write_trailer,
1746 .flags = AVFMT_GLOBALHEADER,
1747 .codec_tag = (const AVCodecTag*[]){ff_mp4_obj_type, 0},
1748 };
1749 #endif