@ -53,7 +53,11 @@ static uint32_t codec_flags(enum AVCodecID codec_id) {
}
}
}
}
static uint32_t samples_per_packet ( enum AVCodecID codec_id , int channels , int block_align ) {
static uint32_t samples_per_packet ( const AVCodecParameters * par ) {
enum AVCodecID codec_id = par - > codec_id ;
int channels = par - > ch_layout . nb_channels , block_align = par - > block_align ;
int frame_size = par - > frame_size , sample_rate = par - > sample_rate ;
switch ( codec_id ) {
switch ( codec_id ) {
case AV_CODEC_ID_PCM_S8 :
case AV_CODEC_ID_PCM_S8 :
case AV_CODEC_ID_PCM_S16LE :
case AV_CODEC_ID_PCM_S16LE :
@ -83,6 +87,8 @@ static uint32_t samples_per_packet(enum AVCodecID codec_id, int channels, int bl
return 320 ;
return 320 ;
case AV_CODEC_ID_MP1 :
case AV_CODEC_ID_MP1 :
return 384 ;
return 384 ;
case AV_CODEC_ID_OPUS :
return frame_size * 48000 / sample_rate ;
case AV_CODEC_ID_MP2 :
case AV_CODEC_ID_MP2 :
case AV_CODEC_ID_MP3 :
case AV_CODEC_ID_MP3 :
return 1152 ;
return 1152 ;
@ -110,7 +116,7 @@ static int caf_write_header(AVFormatContext *s)
AVDictionaryEntry * t = NULL ;
AVDictionaryEntry * t = NULL ;
unsigned int codec_tag = ff_codec_get_tag ( ff_codec_caf_tags , par - > codec_id ) ;
unsigned int codec_tag = ff_codec_get_tag ( ff_codec_caf_tags , par - > codec_id ) ;
int64_t chunk_size = 0 ;
int64_t chunk_size = 0 ;
int frame_size = par - > frame_size ;
int frame_size = par - > frame_size , sample_rate = par - > sample_rate ;
if ( s - > nb_streams ! = 1 ) {
if ( s - > nb_streams ! = 1 ) {
av_log ( s , AV_LOG_ERROR , " CAF files have exactly one stream \n " ) ;
av_log ( s , AV_LOG_ERROR , " CAF files have exactly one stream \n " ) ;
@ -139,7 +145,10 @@ static int caf_write_header(AVFormatContext *s)
}
}
if ( par - > codec_id ! = AV_CODEC_ID_MP3 | | frame_size ! = 576 )
if ( par - > codec_id ! = AV_CODEC_ID_MP3 | | frame_size ! = 576 )
frame_size = samples_per_packet ( par - > codec_id , par - > ch_layout . nb_channels , par - > block_align ) ;
frame_size = samples_per_packet ( par ) ;
if ( par - > codec_id = = AV_CODEC_ID_OPUS )
sample_rate = 48000 ;
ffio_wfourcc ( pb , " caff " ) ; //< mFileType
ffio_wfourcc ( pb , " caff " ) ; //< mFileType
avio_wb16 ( pb , 1 ) ; //< mFileVersion
avio_wb16 ( pb , 1 ) ; //< mFileVersion
@ -147,7 +156,7 @@ static int caf_write_header(AVFormatContext *s)
ffio_wfourcc ( pb , " desc " ) ; //< Audio Description chunk
ffio_wfourcc ( pb , " desc " ) ; //< Audio Description chunk
avio_wb64 ( pb , 32 ) ; //< mChunkSize
avio_wb64 ( pb , 32 ) ; //< mChunkSize
avio_wb64 ( pb , av_double2int ( par - > sample_rate ) ) ; //< mSampleRate
avio_wb64 ( pb , av_double2int ( sample_rate ) ) ; //< mSampleRate
avio_wl32 ( pb , codec_tag ) ; //< mFormatID
avio_wl32 ( pb , codec_tag ) ; //< mFormatID
avio_wb32 ( pb , codec_flags ( par - > codec_id ) ) ; //< mFormatFlags
avio_wb32 ( pb , codec_flags ( par - > codec_id ) ) ; //< mFormatFlags
avio_wb32 ( pb , par - > block_align ) ; //< mBytesPerPacket
avio_wb32 ( pb , par - > block_align ) ; //< mBytesPerPacket
@ -248,7 +257,7 @@ static int caf_write_trailer(AVFormatContext *s)
avio_seek ( pb , caf - > data , SEEK_SET ) ;
avio_seek ( pb , caf - > data , SEEK_SET ) ;
avio_wb64 ( pb , file_size - caf - > data - 8 ) ;
avio_wb64 ( pb , file_size - caf - > data - 8 ) ;
if ( ! par - > block_align ) {
if ( ! par - > block_align ) {
int packet_size = samples_per_packet ( par - > codec_id , par - > ch_layout . nb_channels , par - > block_align ) ;
int packet_size = samples_per_packet ( par ) ;
if ( ! packet_size ) {
if ( ! packet_size ) {
packet_size = st - > duration / ( caf - > packets - 1 ) ;
packet_size = st - > duration / ( caf - > packets - 1 ) ;
avio_seek ( pb , FRAME_SIZE_OFFSET , SEEK_SET ) ;
avio_seek ( pb , FRAME_SIZE_OFFSET , SEEK_SET ) ;