Mercurial > libavformat.hg
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 |