You've already forked FFmpeg
							
							
				mirror of
				https://github.com/FFmpeg/FFmpeg.git
				synced 2025-10-30 23:18:11 +02:00 
			
		
		
		
	avformat/cafdec: Implement FLAC-in-CAF parsing
The afconvert utility shipped with MacOS supports muxing of FLAC in CAF, see afconvert help output on a recent Mac here: https://hydrogenaud.io/index.php?topic=122509.0 A file created with afconvert free of copyright (licensed CC0) can be found here: http://www.audiograaf.nl/misc_stuff/afconvert-FLAC-in-CAF.caf
This commit is contained in:
		
				
					committed by
					
						 Paul B Mahol
						Paul B Mahol
					
				
			
			
				
	
			
			
			
						parent
						
							aa8905a1b1
						
					
				
				
					commit
					056a9fac5b
				
			| @@ -46,6 +46,7 @@ const AVCodecTag ff_codec_caf_tags[] = { | ||||
|     { AV_CODEC_ID_GSM,             MKTAG('a','g','s','m') }, | ||||
|     { AV_CODEC_ID_GSM_MS,          MKTAG('m','s', 0, '1') }, | ||||
|     { AV_CODEC_ID_ILBC,            MKTAG('i','l','b','c') }, | ||||
|     { AV_CODEC_ID_FLAC,            MKTAG('f','l','a','c') }, | ||||
|     { AV_CODEC_ID_MACE3,           MKTAG('M','A','C','3') }, | ||||
|     { AV_CODEC_ID_MACE6,           MKTAG('M','A','C','6') }, | ||||
|     { AV_CODEC_ID_MP1,             MKTAG('.','m','p','1') }, | ||||
|   | ||||
| @@ -32,6 +32,7 @@ | ||||
| #include "internal.h" | ||||
| #include "isom.h" | ||||
| #include "mov_chan.h" | ||||
| #include "libavcodec/flac.h" | ||||
| #include "libavutil/intreadwrite.h" | ||||
| #include "libavutil/intfloat.h" | ||||
| #include "libavutil/dict.h" | ||||
| @@ -170,6 +171,49 @@ static int read_kuki_chunk(AVFormatContext *s, int64_t size) | ||||
|             } | ||||
|             avio_skip(pb, size - ALAC_NEW_KUKI); | ||||
|         } | ||||
|     } else if (st->codecpar->codec_id == AV_CODEC_ID_FLAC) { | ||||
|         int last, type, flac_metadata_size; | ||||
|         uint8_t buf[4]; | ||||
|         /* The magic cookie format for FLAC consists mostly of an mp4 dfLa atom. */ | ||||
|         if (size < (16 + FLAC_STREAMINFO_SIZE)) { | ||||
|             av_log(s, AV_LOG_ERROR, "invalid FLAC magic cookie\n"); | ||||
|             return AVERROR_INVALIDDATA; | ||||
|         } | ||||
|         /* Check cookie version. */ | ||||
|         if (avio_r8(pb) != 0) { | ||||
|             av_log(s, AV_LOG_ERROR, "unknown FLAC magic cookie\n"); | ||||
|             return AVERROR_INVALIDDATA; | ||||
|         } | ||||
|         avio_rb24(pb); /* Flags */ | ||||
|         /* read dfLa fourcc */ | ||||
|         if (avio_read(pb, buf, 4) != 4) { | ||||
|             av_log(s, AV_LOG_ERROR, "failed to read FLAC magic cookie\n"); | ||||
|             return pb->error < 0 ? pb->error : AVERROR_INVALIDDATA; | ||||
|         } | ||||
|         if (memcmp(buf, "dfLa", 4)) { | ||||
|             av_log(s, AV_LOG_ERROR, "invalid FLAC magic cookie\n"); | ||||
|             return AVERROR_INVALIDDATA; | ||||
|         } | ||||
|         /* Check dfLa version. */ | ||||
|         if (avio_r8(pb) != 0) { | ||||
|             av_log(s, AV_LOG_ERROR, "unknown dfLa version\n"); | ||||
|             return AVERROR_INVALIDDATA; | ||||
|         } | ||||
|         avio_rb24(pb); /* Flags */ | ||||
|         if (avio_read(pb, buf, sizeof(buf)) != sizeof(buf)) { | ||||
|             av_log(s, AV_LOG_ERROR, "failed to read FLAC metadata block header\n"); | ||||
|             return pb->error < 0 ? pb->error : AVERROR_INVALIDDATA; | ||||
|         } | ||||
|         flac_parse_block_header(buf, &last, &type, &flac_metadata_size); | ||||
|         if (type != FLAC_METADATA_TYPE_STREAMINFO || flac_metadata_size != FLAC_STREAMINFO_SIZE) { | ||||
|             av_log(s, AV_LOG_ERROR, "STREAMINFO must be first FLACMetadataBlock\n"); | ||||
|             return AVERROR_INVALIDDATA; | ||||
|         } | ||||
|         ret = ff_get_extradata(s, st->codecpar, pb, FLAC_STREAMINFO_SIZE); | ||||
|         if (ret < 0) | ||||
|             return ret; | ||||
|         if (!last) | ||||
|             av_log(s, AV_LOG_WARNING, "non-STREAMINFO FLACMetadataBlock(s) ignored\n"); | ||||
|     } else if (st->codecpar->codec_id == AV_CODEC_ID_OPUS) { | ||||
|         // The data layout for Opus is currently unknown, so we do not export | ||||
|         // extradata at all. Multichannel streams are not supported. | ||||
|   | ||||
		Reference in New Issue
	
	Block a user