| 145 | } |
| 146 | |
| 147 | static int caf_write_header(AVFormatContext *s) |
| 148 | { |
| 149 | AVIOContext *pb = s->pb; |
| 150 | AVCodecParameters *par = s->streams[0]->codecpar; |
| 151 | CAFContext *caf = s->priv_data; |
| 152 | const AVDictionaryEntry *t = NULL; |
| 153 | unsigned int codec_tag = ff_codec_get_tag(ff_codec_caf_tags, par->codec_id); |
| 154 | int64_t chunk_size = 0; |
| 155 | int sample_rate = par->sample_rate; |
| 156 | |
| 157 | if (!par->block_align && !(pb->seekable & AVIO_SEEKABLE_NORMAL)) { |
| 158 | av_log(s, AV_LOG_ERROR, "Muxing variable packet size not supported on non seekable output\n"); |
| 159 | return AVERROR_INVALIDDATA; |
| 160 | } |
| 161 | |
| 162 | caf->frame_size = par->frame_size; |
| 163 | if (par->codec_id != AV_CODEC_ID_MP3 || caf->frame_size != 576) |
| 164 | caf->frame_size = samples_per_packet(par); |
| 165 | |
| 166 | if (!caf->frame_size && !(pb->seekable & AVIO_SEEKABLE_NORMAL)) { |
| 167 | av_log(s, AV_LOG_ERROR, "Muxing variable frame size not supported on non seekable output\n"); |
| 168 | return AVERROR_INVALIDDATA; |
| 169 | } |
| 170 | |
| 171 | if (par->codec_id == AV_CODEC_ID_OPUS) |
| 172 | sample_rate = 48000; |
| 173 | |
| 174 | ffio_wfourcc(pb, "caff"); //< mFileType |
| 175 | avio_wb16(pb, 1); //< mFileVersion |
| 176 | avio_wb16(pb, 0); //< mFileFlags |
| 177 | |
| 178 | ffio_wfourcc(pb, "desc"); //< Audio Description chunk |
| 179 | avio_wb64(pb, 32); //< mChunkSize |
| 180 | avio_wb64(pb, av_double2int(sample_rate)); //< mSampleRate |
| 181 | avio_wl32(pb, codec_tag); //< mFormatID |
| 182 | avio_wb32(pb, codec_flags(par->codec_id)); //< mFormatFlags |
| 183 | avio_wb32(pb, par->block_align); //< mBytesPerPacket |
| 184 | avio_wb32(pb, caf->frame_size); //< mFramesPerPacket |
| 185 | avio_wb32(pb, par->ch_layout.nb_channels); //< mChannelsPerFrame |
| 186 | avio_wb32(pb, av_get_bits_per_sample(par->codec_id)); //< mBitsPerChannel |
| 187 | |
| 188 | if (par->ch_layout.order == AV_CHANNEL_ORDER_NATIVE) { |
| 189 | ffio_wfourcc(pb, "chan"); |
| 190 | avio_wb64(pb, 12); |
| 191 | ff_mov_write_chan(pb, par->ch_layout.u.mask); |
| 192 | } |
| 193 | |
| 194 | if (par->codec_id == AV_CODEC_ID_ALAC) { |
| 195 | ffio_wfourcc(pb, "kuki"); |
| 196 | avio_wb64(pb, 12 + par->extradata_size); |
| 197 | avio_write(pb, "\0\0\0\14frmaalac", 12); |
| 198 | avio_write(pb, par->extradata, par->extradata_size); |
| 199 | } else if (par->codec_id == AV_CODEC_ID_AMR_NB) { |
| 200 | ffio_wfourcc(pb, "kuki"); |
| 201 | avio_wb64(pb, 29); |
| 202 | avio_write(pb, "\0\0\0\14frmasamr", 12); |
| 203 | avio_wb32(pb, 0x11); /* size */ |
| 204 | avio_write(pb, "samrFFMP", 8); |
nothing calls this directly
no test coverage detected