mirror of
				https://github.com/nyanmisaka/ffmpeg-rockchip.git
				synced 2025-10-31 04:26:37 +08:00 
			
		
		
		
	avformat/cafenc: derive Opus frame size from the relevant stream parameters
Use the stream duration as last resort, as an off-by-one result of the "st->duration / (caf->packets - 1)" calculation can break playback on some devices. Also, don't write the sample_rate value propagated by encoders like libopus. The sample rate of the audio fed to it is irrelevant after being encoded. Fixes ticket #9930. Signed-off-by: James Almer <jamrial@gmail.com>
This commit is contained in:
		| @@ -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) { | ||||
|     case AV_CODEC_ID_PCM_S8: | ||||
|     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; | ||||
|     case AV_CODEC_ID_MP1: | ||||
|         return 384; | ||||
|     case AV_CODEC_ID_OPUS: | ||||
|         return frame_size * 48000 / sample_rate; | ||||
|     case AV_CODEC_ID_MP2: | ||||
|     case AV_CODEC_ID_MP3: | ||||
|         return 1152; | ||||
| @@ -110,7 +116,7 @@ static int caf_write_header(AVFormatContext *s) | ||||
|     AVDictionaryEntry *t = NULL; | ||||
|     unsigned int codec_tag = ff_codec_get_tag(ff_codec_caf_tags, par->codec_id); | ||||
|     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) { | ||||
|         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) | ||||
|         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 | ||||
|     avio_wb16(pb, 1);         //< mFileVersion | ||||
| @@ -147,7 +156,7 @@ static int caf_write_header(AVFormatContext *s) | ||||
|  | ||||
|     ffio_wfourcc(pb, "desc");                         //< Audio Description chunk | ||||
|     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_wb32(pb, codec_flags(par->codec_id));        //< mFormatFlags | ||||
|     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_wb64(pb, file_size - caf->data - 8); | ||||
|         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) { | ||||
|                 packet_size = st->duration / (caf->packets - 1); | ||||
|                 avio_seek(pb, FRAME_SIZE_OFFSET, SEEK_SET); | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 James Almer
					James Almer