|
33 | 33 | #include "avc.h" |
34 | 34 | #include "libavcodec/ac3_parser.h" |
35 | 35 | #include "libavcodec/dnxhddata.h" |
| 36 | +#include "libavcodec/flac.h" |
36 | 37 | #include "libavcodec/get_bits.h" |
37 | 38 | #include "libavcodec/put_bits.h" |
38 | 39 | #include "libavcodec/vc1_common.h" |
@@ -655,6 +656,26 @@ static int mov_write_wfex_tag(AVFormatContext *s, AVIOContext *pb, MOVTrack *tra |
655 | 656 | return update_size(pb, pos); |
656 | 657 | } |
657 | 658 |
|
| 659 | +static int mov_write_dfla_tag(AVIOContext *pb, MOVTrack *track) |
| 660 | +{ |
| 661 | + int64_t pos = avio_tell(pb); |
| 662 | + avio_wb32(pb, 0); |
| 663 | + ffio_wfourcc(pb, "dfLa"); |
| 664 | + avio_w8(pb, 0); /* version */ |
| 665 | + avio_wb24(pb, 0); /* flags */ |
| 666 | + |
| 667 | + /* Expect the encoder to pass a METADATA_BLOCK_TYPE_STREAMINFO. */ |
| 668 | + if (track->par->extradata_size != FLAC_STREAMINFO_SIZE) |
| 669 | + return AVERROR_INVALIDDATA; |
| 670 | + |
| 671 | + /* TODO: Write other METADATA_BLOCK_TYPEs if the encoder makes them available. */ |
| 672 | + avio_w8(pb, 1 << 7 | FLAC_METADATA_TYPE_STREAMINFO); /* LastMetadataBlockFlag << 7 | BlockType */ |
| 673 | + avio_wb24(pb, track->par->extradata_size); /* Length */ |
| 674 | + avio_write(pb, track->par->extradata, track->par->extradata_size); /* BlockData[Length] */ |
| 675 | + |
| 676 | + return update_size(pb, pos); |
| 677 | +} |
| 678 | + |
658 | 679 | static int mov_write_chan_tag(AVFormatContext *s, AVIOContext *pb, MOVTrack *track) |
659 | 680 | { |
660 | 681 | uint32_t layout_tag, bitmap; |
@@ -964,8 +985,13 @@ static int mov_write_audio_tag(AVFormatContext *s, AVIOContext *pb, MOVMuxContex |
964 | 985 | avio_wb16(pb, 16); |
965 | 986 | avio_wb16(pb, track->audio_vbr ? -2 : 0); /* compression ID */ |
966 | 987 | } else { /* reserved for mp4/3gp */ |
967 | | - avio_wb16(pb, 2); |
968 | | - avio_wb16(pb, 16); |
| 988 | + if (track->par->codec_id == AV_CODEC_ID_FLAC) { |
| 989 | + avio_wb16(pb, track->par->channels); |
| 990 | + avio_wb16(pb, track->par->bits_per_raw_sample); |
| 991 | + } else { |
| 992 | + avio_wb16(pb, 2); |
| 993 | + avio_wb16(pb, 16); |
| 994 | + } |
969 | 995 | avio_wb16(pb, 0); |
970 | 996 | } |
971 | 997 |
|
@@ -1010,6 +1036,8 @@ static int mov_write_audio_tag(AVFormatContext *s, AVIOContext *pb, MOVMuxContex |
1010 | 1036 | mov_write_extradata_tag(pb, track); |
1011 | 1037 | else if (track->par->codec_id == AV_CODEC_ID_WMAPRO) |
1012 | 1038 | mov_write_wfex_tag(s, pb, track); |
| 1039 | + else if (track->par->codec_id == AV_CODEC_ID_FLAC) |
| 1040 | + mov_write_dfla_tag(pb, track); |
1013 | 1041 | else if (track->vos_len > 0) |
1014 | 1042 | mov_write_glbl_tag(pb, track); |
1015 | 1043 |
|
@@ -1178,6 +1206,7 @@ static int mp4_get_codec_tag(AVFormatContext *s, MOVTrack *track) |
1178 | 1206 | else if (track->par->codec_id == AV_CODEC_ID_DIRAC) tag = MKTAG('d','r','a','c'); |
1179 | 1207 | else if (track->par->codec_id == AV_CODEC_ID_MOV_TEXT) tag = MKTAG('t','x','3','g'); |
1180 | 1208 | else if (track->par->codec_id == AV_CODEC_ID_VC1) tag = MKTAG('v','c','-','1'); |
| 1209 | + else if (track->par->codec_id == AV_CODEC_ID_FLAC) tag = MKTAG('f','L','a','C'); |
1181 | 1210 | else if (track->par->codec_type == AVMEDIA_TYPE_VIDEO) tag = MKTAG('m','p','4','v'); |
1182 | 1211 | else if (track->par->codec_type == AVMEDIA_TYPE_AUDIO) tag = MKTAG('m','p','4','a'); |
1183 | 1212 | else if (track->par->codec_id == AV_CODEC_ID_DVD_SUBTITLE) tag = MKTAG('m','p','4','s'); |
@@ -5043,7 +5072,8 @@ static int mov_write_single_packet(AVFormatContext *s, AVPacket *pkt) |
5043 | 5072 | trk->start_cts = 0; |
5044 | 5073 | } |
5045 | 5074 |
|
5046 | | - if (trk->par->codec_id == AV_CODEC_ID_MP4ALS) { |
| 5075 | + if (trk->par->codec_id == AV_CODEC_ID_MP4ALS || |
| 5076 | + trk->par->codec_id == AV_CODEC_ID_FLAC) { |
5047 | 5077 | int side_size = 0; |
5048 | 5078 | uint8_t *side = av_packet_get_side_data(pkt, AV_PKT_DATA_NEW_EXTRADATA, &side_size); |
5049 | 5079 | if (side && side_size > 0 && (side_size != par->extradata_size || memcmp(side, par->extradata, side_size))) { |
@@ -5757,6 +5787,19 @@ static int mov_init(AVFormatContext *s) |
5757 | 5787 | i, track->par->sample_rate); |
5758 | 5788 | } |
5759 | 5789 | } |
| 5790 | + if (track->par->codec_id == AV_CODEC_ID_FLAC) { |
| 5791 | + if (track->mode != MODE_MP4) { |
| 5792 | + av_log(s, AV_LOG_ERROR, "FLAC only supported in MP4.\n"); |
| 5793 | + return AVERROR(EINVAL); |
| 5794 | + } |
| 5795 | + if (s->strict_std_compliance > FF_COMPLIANCE_EXPERIMENTAL) { |
| 5796 | + av_log(s, AV_LOG_ERROR, |
| 5797 | + "FLAC in MP4 support is experimental, add " |
| 5798 | + "'-strict %d' if you want to use it.\n", |
| 5799 | + FF_COMPLIANCE_EXPERIMENTAL); |
| 5800 | + return AVERROR_EXPERIMENTAL; |
| 5801 | + } |
| 5802 | + } |
5760 | 5803 | } else if (st->codecpar->codec_type == AVMEDIA_TYPE_SUBTITLE) { |
5761 | 5804 | track->timescale = st->time_base.den; |
5762 | 5805 | } else if (st->codecpar->codec_type == AVMEDIA_TYPE_DATA) { |
|
0 commit comments