FFmpeg Input: Support various DSD formats and IFF
Implement support for DFF, WSD, and IFF formats, and all DSD formats carried within, using our own DSD decimation method instead of relying on FFmpeg to do it. Fixes #165 Signed-off-by: Christopher Snowhill <kode54@gmail.com>
This commit is contained in:
parent
f3356a821a
commit
f203911bb1
8 changed files with 178 additions and 82 deletions
|
@ -34,6 +34,11 @@
|
||||||
AVCodecContext *codecCtx;
|
AVCodecContext *codecCtx;
|
||||||
AVFrame *lastDecodedFrame;
|
AVFrame *lastDecodedFrame;
|
||||||
AVPacket *lastReadPacket;
|
AVPacket *lastReadPacket;
|
||||||
|
|
||||||
|
BOOL rawDSD;
|
||||||
|
BOOL rawDSDReverseBits;
|
||||||
|
BOOL rawDSDPlanar;
|
||||||
|
|
||||||
int bytesConsumedFromDecodedFrame;
|
int bytesConsumedFromDecodedFrame;
|
||||||
BOOL readNextPacket;
|
BOOL readNextPacket;
|
||||||
int64_t seekFrame;
|
int64_t seekFrame;
|
||||||
|
|
|
@ -49,10 +49,22 @@ int64_t ffmpeg_seek(void *opaque, int64_t offset, int whence) {
|
||||||
|
|
||||||
@implementation FFMPEGDecoder
|
@implementation FFMPEGDecoder
|
||||||
|
|
||||||
|
static uint8_t reverse_bits[0x100];
|
||||||
|
|
||||||
+ (void)initialize {
|
+ (void)initialize {
|
||||||
if(self == [FFMPEGDecoder class]) {
|
if(self == [FFMPEGDecoder class]) {
|
||||||
av_log_set_flags(AV_LOG_SKIP_REPEATED);
|
av_log_set_flags(AV_LOG_SKIP_REPEATED);
|
||||||
av_log_set_level(AV_LOG_ERROR);
|
av_log_set_level(AV_LOG_ERROR);
|
||||||
|
|
||||||
|
for(int i = 0, j = 0; i < 0x100; i++) {
|
||||||
|
reverse_bits[i] = (uint8_t)j;
|
||||||
|
// "reverse-increment" of j
|
||||||
|
for(int bitmask = 0x80;;) {
|
||||||
|
if(((j ^= bitmask) & bitmask) != 0) break;
|
||||||
|
if(bitmask == 1) break;
|
||||||
|
bitmask >>= 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -79,6 +91,8 @@ int64_t ffmpeg_seek(void *opaque, int64_t offset, int whence) {
|
||||||
totalFrames = 0;
|
totalFrames = 0;
|
||||||
framesRead = 0;
|
framesRead = 0;
|
||||||
|
|
||||||
|
rawDSD = NO;
|
||||||
|
|
||||||
BOOL isStream = NO;
|
BOOL isStream = NO;
|
||||||
|
|
||||||
// register all available codecs
|
// register all available codecs
|
||||||
|
@ -184,6 +198,14 @@ int64_t ffmpeg_seek(void *opaque, int64_t offset, int whence) {
|
||||||
AVDictionary *dict = NULL;
|
AVDictionary *dict = NULL;
|
||||||
|
|
||||||
switch(codec_id) {
|
switch(codec_id) {
|
||||||
|
case AV_CODEC_ID_DSD_LSBF:
|
||||||
|
case AV_CODEC_ID_DSD_MSBF:
|
||||||
|
case AV_CODEC_ID_DSD_LSBF_PLANAR:
|
||||||
|
case AV_CODEC_ID_DSD_MSBF_PLANAR:
|
||||||
|
rawDSD = YES;
|
||||||
|
rawDSDReverseBits = codec_id == AV_CODEC_ID_DSD_LSBF || codec_id == AV_CODEC_ID_DSD_LSBF_PLANAR;
|
||||||
|
rawDSDPlanar = codec_id == AV_CODEC_ID_DSD_LSBF_PLANAR || codec_id == AV_CODEC_ID_DSD_MSBF_PLANAR;
|
||||||
|
break;
|
||||||
case AV_CODEC_ID_MP3:
|
case AV_CODEC_ID_MP3:
|
||||||
codec = avcodec_find_decoder_by_name("mp3float");
|
codec = avcodec_find_decoder_by_name("mp3float");
|
||||||
break;
|
break;
|
||||||
|
@ -211,7 +233,7 @@ int64_t ffmpeg_seek(void *opaque, int64_t offset, int whence) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!codec)
|
if(!codec && !rawDSD)
|
||||||
codec = avcodec_find_decoder(codec_id);
|
codec = avcodec_find_decoder(codec_id);
|
||||||
|
|
||||||
if(@available(macOS 10.15, *)) {
|
if(@available(macOS 10.15, *)) {
|
||||||
|
@ -229,13 +251,13 @@ int64_t ffmpeg_seek(void *opaque, int64_t offset, int whence) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!codec) {
|
if(!codec && !rawDSD) {
|
||||||
ALog(@"codec not found");
|
ALog(@"codec not found");
|
||||||
av_dict_free(&dict);
|
av_dict_free(&dict);
|
||||||
return NO;
|
return NO;
|
||||||
}
|
}
|
||||||
|
|
||||||
if((errcode = avcodec_open2(codecCtx, codec, &dict)) < 0) {
|
if(!rawDSD && (errcode = avcodec_open2(codecCtx, codec, &dict)) < 0) {
|
||||||
char errDescr[4096];
|
char errDescr[4096];
|
||||||
av_dict_free(&dict);
|
av_dict_free(&dict);
|
||||||
av_strerror(errcode, errDescr, 4096);
|
av_strerror(errcode, errDescr, 4096);
|
||||||
|
@ -246,7 +268,7 @@ int64_t ffmpeg_seek(void *opaque, int64_t offset, int whence) {
|
||||||
av_dict_free(&dict);
|
av_dict_free(&dict);
|
||||||
|
|
||||||
// Bah, their skipping is broken
|
// Bah, their skipping is broken
|
||||||
codecCtx->flags2 |= AV_CODEC_FLAG2_SKIP_MANUAL;
|
if(!rawDSD) codecCtx->flags2 |= AV_CODEC_FLAG2_SKIP_MANUAL;
|
||||||
|
|
||||||
lastDecodedFrame = av_frame_alloc();
|
lastDecodedFrame = av_frame_alloc();
|
||||||
av_frame_unref(lastDecodedFrame);
|
av_frame_unref(lastDecodedFrame);
|
||||||
|
@ -256,6 +278,7 @@ int64_t ffmpeg_seek(void *opaque, int64_t offset, int whence) {
|
||||||
bytesConsumedFromDecodedFrame = INT_MAX;
|
bytesConsumedFromDecodedFrame = INT_MAX;
|
||||||
seekFrame = -1;
|
seekFrame = -1;
|
||||||
|
|
||||||
|
if(!rawDSD) {
|
||||||
frequency = codecCtx->sample_rate;
|
frequency = codecCtx->sample_rate;
|
||||||
channels = codecCtx->channels;
|
channels = codecCtx->channels;
|
||||||
channelConfig = (uint32_t)codecCtx->channel_layout;
|
channelConfig = (uint32_t)codecCtx->channel_layout;
|
||||||
|
@ -292,6 +315,13 @@ int64_t ffmpeg_seek(void *opaque, int64_t offset, int whence) {
|
||||||
default:
|
default:
|
||||||
return NO;
|
return NO;
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
frequency = codecPar->sample_rate * 8;
|
||||||
|
channels = codecPar->channels;
|
||||||
|
channelConfig = (uint32_t)codecPar->channel_layout;
|
||||||
|
bitsPerSample = 1;
|
||||||
|
floatingPoint = NO;
|
||||||
|
}
|
||||||
|
|
||||||
lossy = NO;
|
lossy = NO;
|
||||||
if(floatingPoint)
|
if(floatingPoint)
|
||||||
|
@ -395,6 +425,10 @@ int64_t ffmpeg_seek(void *opaque, int64_t offset, int whence) {
|
||||||
endOfStream = NO;
|
endOfStream = NO;
|
||||||
endOfAudio = NO;
|
endOfAudio = NO;
|
||||||
|
|
||||||
|
if(rawDSD) {
|
||||||
|
totalFrames *= 8;
|
||||||
|
}
|
||||||
|
|
||||||
if(!isStream) {
|
if(!isStream) {
|
||||||
if(stream->start_time && stream->start_time != AV_NOPTS_VALUE)
|
if(stream->start_time && stream->start_time != AV_NOPTS_VALUE)
|
||||||
skipSamples = av_rescale_q(stream->start_time, stream->time_base, tb);
|
skipSamples = av_rescale_q(stream->start_time, stream->time_base, tb);
|
||||||
|
@ -533,7 +567,7 @@ int64_t ffmpeg_seek(void *opaque, int64_t offset, int whence) {
|
||||||
if(totalFrames && framesRead >= totalFrames)
|
if(totalFrames && framesRead >= totalFrames)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
int frameSize = channels * (bitsPerSample / 8);
|
int frameSize = rawDSD ? channels : channels * (bitsPerSample / 8);
|
||||||
int dataSize = 0;
|
int dataSize = 0;
|
||||||
|
|
||||||
int bytesToRead = frames * frameSize;
|
int bytesToRead = frames * frameSize;
|
||||||
|
@ -548,10 +582,16 @@ int64_t ffmpeg_seek(void *opaque, int64_t offset, int whence) {
|
||||||
while(bytesRead < bytesToRead) {
|
while(bytesRead < bytesToRead) {
|
||||||
// buffer size needed to hold decoded samples, in bytes
|
// buffer size needed to hold decoded samples, in bytes
|
||||||
int planeSize;
|
int planeSize;
|
||||||
int planar = av_sample_fmt_is_planar(codecCtx->sample_fmt);
|
int planar;
|
||||||
|
if(!rawDSD) {
|
||||||
|
planar = av_sample_fmt_is_planar(codecCtx->sample_fmt);
|
||||||
dataSize = av_samples_get_buffer_size(&planeSize, codecCtx->channels,
|
dataSize = av_samples_get_buffer_size(&planeSize, codecCtx->channels,
|
||||||
lastDecodedFrame->nb_samples,
|
lastDecodedFrame->nb_samples,
|
||||||
codecCtx->sample_fmt, 1);
|
codecCtx->sample_fmt, 1);
|
||||||
|
} else {
|
||||||
|
planar = 0;
|
||||||
|
dataSize = endOfStream ? 0 : lastReadPacket->size;
|
||||||
|
}
|
||||||
|
|
||||||
if(dataSize < 0)
|
if(dataSize < 0)
|
||||||
dataSize = 0;
|
dataSize = 0;
|
||||||
|
@ -577,6 +617,7 @@ int64_t ffmpeg_seek(void *opaque, int64_t offset, int whence) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(!rawDSD) {
|
||||||
if((errcode = avcodec_send_packet(codecCtx, endOfStream ? NULL : lastReadPacket)) < 0) {
|
if((errcode = avcodec_send_packet(codecCtx, endOfStream ? NULL : lastReadPacket)) < 0) {
|
||||||
if(errcode == AVERROR_INVALIDDATA) {
|
if(errcode == AVERROR_INVALIDDATA) {
|
||||||
ALog(@"Sync error sending packet to codec, attempting to skip it");
|
ALog(@"Sync error sending packet to codec, attempting to skip it");
|
||||||
|
@ -588,6 +629,7 @@ int64_t ffmpeg_seek(void *opaque, int64_t offset, int whence) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
readNextPacket = NO; // we probably won't need to consume another chunk
|
readNextPacket = NO; // we probably won't need to consume another chunk
|
||||||
}
|
}
|
||||||
|
@ -598,6 +640,7 @@ int64_t ffmpeg_seek(void *opaque, int64_t offset, int whence) {
|
||||||
|
|
||||||
bytesConsumedFromDecodedFrame = 0;
|
bytesConsumedFromDecodedFrame = 0;
|
||||||
|
|
||||||
|
if(!rawDSD) {
|
||||||
if((errcode = avcodec_receive_frame(codecCtx, lastDecodedFrame)) < 0) {
|
if((errcode = avcodec_receive_frame(codecCtx, lastDecodedFrame)) < 0) {
|
||||||
if(errcode == AVERROR_EOF) {
|
if(errcode == AVERROR_EOF) {
|
||||||
endOfAudio = YES;
|
endOfAudio = YES;
|
||||||
|
@ -618,6 +661,35 @@ int64_t ffmpeg_seek(void *opaque, int64_t offset, int whence) {
|
||||||
dataSize = av_samples_get_buffer_size(&planeSize, codecCtx->channels,
|
dataSize = av_samples_get_buffer_size(&planeSize, codecCtx->channels,
|
||||||
lastDecodedFrame->nb_samples,
|
lastDecodedFrame->nb_samples,
|
||||||
codecCtx->sample_fmt, 1);
|
codecCtx->sample_fmt, 1);
|
||||||
|
} else {
|
||||||
|
dataSize = lastReadPacket->size;
|
||||||
|
if(endOfStream) {
|
||||||
|
endOfAudio = YES;
|
||||||
|
break;
|
||||||
|
} else if(dataSize <= bytesConsumedFromDecodedFrame) {
|
||||||
|
readNextPacket = YES;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(rawDSDPlanar) {
|
||||||
|
uint8_t tempBuf[dataSize];
|
||||||
|
size_t samples = dataSize / channels;
|
||||||
|
uint8_t *packetData = lastReadPacket->data;
|
||||||
|
for(size_t i = 0; i < samples; ++i) {
|
||||||
|
for(size_t j = 0; j < channels; ++j) {
|
||||||
|
tempBuf[i * channels + j] = packetData[j * samples + i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
memmove(packetData, tempBuf, sizeof(tempBuf));
|
||||||
|
}
|
||||||
|
|
||||||
|
if(rawDSDReverseBits) {
|
||||||
|
uint8_t *packetData = lastReadPacket->data;
|
||||||
|
for(size_t i = 0; i < dataSize; ++i) {
|
||||||
|
packetData[i] = reverse_bits[packetData[i]];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if(dataSize < 0)
|
if(dataSize < 0)
|
||||||
dataSize = 0;
|
dataSize = 0;
|
||||||
|
@ -647,6 +719,7 @@ int64_t ffmpeg_seek(void *opaque, int64_t offset, int whence) {
|
||||||
seekBytesSkip -= minSkipped;
|
seekBytesSkip -= minSkipped;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(!rawDSD) {
|
||||||
int _channels = codecCtx->channels;
|
int _channels = codecCtx->channels;
|
||||||
uint32_t _channelConfig = (uint32_t)codecCtx->channel_layout;
|
uint32_t _channelConfig = (uint32_t)codecCtx->channel_layout;
|
||||||
float _frequency = codecCtx->sample_rate;
|
float _frequency = codecCtx->sample_rate;
|
||||||
|
@ -664,11 +737,14 @@ int64_t ffmpeg_seek(void *opaque, int64_t offset, int whence) {
|
||||||
[self didChangeValueForKey:@"properties"];
|
[self didChangeValueForKey:@"properties"];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
int toConsume = FFMIN((dataSize - bytesConsumedFromDecodedFrame), (bytesToRead - bytesRead));
|
int toConsume = FFMIN((dataSize - bytesConsumedFromDecodedFrame), (bytesToRead - bytesRead));
|
||||||
|
|
||||||
// copy decoded samples to Cog's buffer
|
// copy decoded samples to Cog's buffer
|
||||||
if(!planar || channels == 1) {
|
if(rawDSD) {
|
||||||
|
memmove(targetBuf + bytesRead, (lastReadPacket->data + bytesConsumedFromDecodedFrame), toConsume);
|
||||||
|
} else if(!planar || channels == 1) {
|
||||||
memmove(targetBuf + bytesRead, (lastDecodedFrame->data[0] + bytesConsumedFromDecodedFrame), toConsume);
|
memmove(targetBuf + bytesRead, (lastDecodedFrame->data[0] + bytesConsumedFromDecodedFrame), toConsume);
|
||||||
} else {
|
} else {
|
||||||
uint8_t *out = (uint8_t *)targetBuf + bytesRead;
|
uint8_t *out = (uint8_t *)targetBuf + bytesRead;
|
||||||
|
@ -685,6 +761,10 @@ int64_t ffmpeg_seek(void *opaque, int64_t offset, int whence) {
|
||||||
|
|
||||||
bytesConsumedFromDecodedFrame += toConsume;
|
bytesConsumedFromDecodedFrame += toConsume;
|
||||||
bytesRead += toConsume;
|
bytesRead += toConsume;
|
||||||
|
|
||||||
|
if(rawDSD && bytesConsumedFromDecodedFrame == dataSize) {
|
||||||
|
av_packet_unref(lastReadPacket);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
[self updateMetadata];
|
[self updateMetadata];
|
||||||
|
@ -708,10 +788,14 @@ int64_t ffmpeg_seek(void *opaque, int64_t offset, int whence) {
|
||||||
endOfAudio = YES;
|
endOfAudio = YES;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
if(rawDSD) frame /= 8;
|
||||||
AVRational tb = { .num = 1, .den = codecCtx->sample_rate };
|
AVRational tb = { .num = 1, .den = codecCtx->sample_rate };
|
||||||
int64_t ts = av_rescale_q(frame, tb, formatCtx->streams[streamIndex]->time_base);
|
int64_t ts = av_rescale_q(frame, tb, formatCtx->streams[streamIndex]->time_base);
|
||||||
int ret = avformat_seek_file(formatCtx, streamIndex, ts - 1000, ts, ts, 0);
|
int ret = avformat_seek_file(formatCtx, streamIndex, ts - 1000, ts, ts, 0);
|
||||||
|
if(!rawDSD)
|
||||||
avcodec_flush_buffers(codecCtx);
|
avcodec_flush_buffers(codecCtx);
|
||||||
|
else
|
||||||
|
av_packet_unref(lastReadPacket);
|
||||||
if(ret < 0) {
|
if(ret < 0) {
|
||||||
framesRead = totalFrames;
|
framesRead = totalFrames;
|
||||||
endOfStream = YES;
|
endOfStream = YES;
|
||||||
|
@ -721,10 +805,14 @@ int64_t ffmpeg_seek(void *opaque, int64_t offset, int whence) {
|
||||||
readNextPacket = YES; // so we immediately read next packet
|
readNextPacket = YES; // so we immediately read next packet
|
||||||
bytesConsumedFromDecodedFrame = INT_MAX; // so we immediately begin decoding next frame
|
bytesConsumedFromDecodedFrame = INT_MAX; // so we immediately begin decoding next frame
|
||||||
framesRead = frame;
|
framesRead = frame;
|
||||||
|
if(rawDSD) framesRead *= 8;
|
||||||
seekFrame = frame + skipSamples;
|
seekFrame = frame + skipSamples;
|
||||||
endOfStream = NO;
|
endOfStream = NO;
|
||||||
endOfAudio = NO;
|
endOfAudio = NO;
|
||||||
|
|
||||||
|
if(rawDSD)
|
||||||
|
return frame * 8;
|
||||||
|
else
|
||||||
return frame;
|
return frame;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -748,7 +836,7 @@ int64_t ffmpeg_seek(void *opaque, int64_t offset, int whence) {
|
||||||
}
|
}
|
||||||
|
|
||||||
+ (NSArray *)fileTypes {
|
+ (NSArray *)fileTypes {
|
||||||
return @[@"wma", @"asf", @"tak", @"mp4", @"m4a", @"aac", @"mp3", @"mp2", @"m2a", @"mpa", @"ape", @"ac3", @"dts", @"dtshd", @"wav", @"tta", @"vqf", @"vqe", @"vql", @"ra", @"rm", @"rmj", @"mka", @"weba"];
|
return @[@"wma", @"asf", @"tak", @"mp4", @"m4a", @"aac", @"mp3", @"mp2", @"m2a", @"mpa", @"ape", @"ac3", @"dts", @"dtshd", @"wav", @"tta", @"vqf", @"vqe", @"vql", @"ra", @"rm", @"rmj", @"mka", @"weba", @"dff", @"iff", @"dsdiff", @"wsd"];
|
||||||
}
|
}
|
||||||
|
|
||||||
+ (NSArray *)mimeTypes {
|
+ (NSArray *)mimeTypes {
|
||||||
|
@ -770,7 +858,10 @@ int64_t ffmpeg_seek(void *opaque, int64_t offset, int whence) {
|
||||||
@[@"TrueVQ Audio File", @"song.icns", @"vqf", @"vqe", @"vql"],
|
@[@"TrueVQ Audio File", @"song.icns", @"vqf", @"vqe", @"vql"],
|
||||||
@[@"Real Audio File", @"song.icns", @"ra", @"rm", @"rmj"],
|
@[@"Real Audio File", @"song.icns", @"ra", @"rm", @"rmj"],
|
||||||
@[@"Matroska Audio File", @"song.icns", @"mka"],
|
@[@"Matroska Audio File", @"song.icns", @"mka"],
|
||||||
@[@"WebM Audio File", @"song.icns", @"weba"]
|
@[@"WebM Audio File", @"song.icns", @"weba"],
|
||||||
|
@[@"DSD Stream File", @"song.icns", @"dsf"],
|
||||||
|
@[@"Interchange File Format", @"song.icns", @"iff", @"dsdiff"],
|
||||||
|
@[@"Wideband Single-bit Data", @"song.icns", @"wsd"]
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -30,7 +30,7 @@ ADPCM_CODECS=adpcm_4xm,adpcm_adx,adpcm_afx,adpcm_agm,adpcm_aica,adpcm_argo,adpcm
|
||||||
--enable-swresample\
|
--enable-swresample\
|
||||||
--enable-protocol=tcp,tls,http,https,icecast\
|
--enable-protocol=tcp,tls,http,https,icecast\
|
||||||
--enable-parser=ac3,mpegaudio,xma,vorbis,opus\
|
--enable-parser=ac3,mpegaudio,xma,vorbis,opus\
|
||||||
--enable-demuxer=hls,mpegts,mpegtsraw,ac3,asf,xwma,mov,oma,ogg,tak,dsf,wav,w64,aac,dts,dtshd,eac3,mp3,bink,flac,msf,xmv,caf,ape,smacker,spdif,mpc,mpc8,rm,matroska,tta,$PCM_CODECS,$ADPCM_CODECS\
|
--enable-demuxer=hls,mpegts,mpegtsraw,ac3,asf,xwma,mov,oma,ogg,tak,dsf,wav,w64,aac,dts,dtshd,eac3,mp3,bink,flac,msf,xmv,caf,ape,smacker,spdif,mpc,mpc8,rm,matroska,tta,dff,wsd,iff,$PCM_CODECS,$ADPCM_CODECS\
|
||||||
--enable-decoder=ac3,ac3_t,eac3,wmapro,wmav1,wmav2,wmavoice,wmalossless,xma1,xma2,dca,tak,dsd_lsbf,dsd_lsbf_planar,dsd_mbf,dsd_msbf_planar,aac,libfdk_aac,atrac3,atrac3p,mp3float,mp2float,mp1float,bink,binkaudio_dct,binkaudio_rdft,flac,vorbis,ape,smackaud,opus,mpc7,mpc8,alac,cook,tta,$PCM_CODECS,$ADPCM_CODECS\
|
--enable-decoder=ac3,ac3_t,eac3,wmapro,wmav1,wmav2,wmavoice,wmalossless,xma1,xma2,dca,tak,dsd_lsbf,dsd_lsbf_planar,dsd_mbf,dsd_msbf_planar,aac,libfdk_aac,atrac3,atrac3p,mp3float,mp2float,mp1float,bink,binkaudio_dct,binkaudio_rdft,flac,vorbis,ape,smackaud,opus,mpc7,mpc8,alac,cook,tta,$PCM_CODECS,$ADPCM_CODECS\
|
||||||
--disable-parser=mpeg4video,h263\
|
--disable-parser=mpeg4video,h263\
|
||||||
--disable-decoder=mpeg2video,h263,h264,mpeg1video,mpeg2video,mpeg4,hevc,vp9\
|
--disable-decoder=mpeg2video,h263,h264,mpeg1video,mpeg2video,mpeg4,hevc,vp9\
|
||||||
|
|
|
@ -28,7 +28,7 @@ ADPCM_CODECS=adpcm_4xm,adpcm_adx,adpcm_afx,adpcm_agm,adpcm_aica,adpcm_argo,adpcm
|
||||||
--enable-swresample\
|
--enable-swresample\
|
||||||
--enable-protocol=tcp,tls,http,https,icecast,hls\
|
--enable-protocol=tcp,tls,http,https,icecast,hls\
|
||||||
--enable-parser=ac3,mpegaudio,xma,vorbis,opus\
|
--enable-parser=ac3,mpegaudio,xma,vorbis,opus\
|
||||||
--enable-demuxer=hls,mpegts,mpegtsraw,ac3,asf,xwma,mov,oma,ogg,tak,dsf,wav,w64,aac,dts,dtshd,eac3,mp3,bink,flac,msf,xmv,caf,ape,smacker,spdif,mpc,mpc8,rm,matroska,tta,$PCM_CODECS,$ADPCM_CODECS\
|
--enable-demuxer=hls,mpegts,mpegtsraw,ac3,asf,xwma,mov,oma,ogg,tak,dsf,wav,w64,aac,dts,dtshd,eac3,mp3,bink,flac,msf,xmv,caf,ape,smacker,spdif,mpc,mpc8,rm,matroska,tta,dff,wsd,iff,$PCM_CODECS,$ADPCM_CODECS\
|
||||||
--enable-decoder=ac3,ac3_t,eac3,wmapro,wmav1,wmav2,wmavoice,wmalossless,xma1,xma2,dca,tak,dsd_lsbf,dsd_lsbf_planar,dsd_mbf,dsd_msbf_planar,aac,libfdk_aac,atrac3,atrac3p,mp3float,mp2float,mp1float,bink,binkaudio_dct,binkaudio_rdft,flac,vorbis,ape,smackaud,opus,mpc7,mpc8,alac,cook,tta,$PCM_CODECS,$ADPCM_CODECS\
|
--enable-decoder=ac3,ac3_t,eac3,wmapro,wmav1,wmav2,wmavoice,wmalossless,xma1,xma2,dca,tak,dsd_lsbf,dsd_lsbf_planar,dsd_mbf,dsd_msbf_planar,aac,libfdk_aac,atrac3,atrac3p,mp3float,mp2float,mp1float,bink,binkaudio_dct,binkaudio_rdft,flac,vorbis,ape,smackaud,opus,mpc7,mpc8,alac,cook,tta,$PCM_CODECS,$ADPCM_CODECS\
|
||||||
--disable-parser=mpeg4video,h263\
|
--disable-parser=mpeg4video,h263\
|
||||||
--disable-decoder=mpeg2video,h263,h264,mpeg1video,mpeg2video,mpeg4,hevc,vp9\
|
--disable-decoder=mpeg2video,h263,h264,mpeg1video,mpeg2video,mpeg4,hevc,vp9\
|
||||||
|
|
BIN
ThirdParty/ffmpeg/lib/libavcodec.59.dylib
vendored
BIN
ThirdParty/ffmpeg/lib/libavcodec.59.dylib
vendored
Binary file not shown.
BIN
ThirdParty/ffmpeg/lib/libavformat.59.dylib
vendored
BIN
ThirdParty/ffmpeg/lib/libavformat.59.dylib
vendored
Binary file not shown.
BIN
ThirdParty/ffmpeg/lib/libavutil.57.dylib
vendored
BIN
ThirdParty/ffmpeg/lib/libavutil.57.dylib
vendored
Binary file not shown.
BIN
ThirdParty/ffmpeg/lib/libswresample.4.dylib
vendored
BIN
ThirdParty/ffmpeg/lib/libswresample.4.dylib
vendored
Binary file not shown.
Loading…
Reference in a new issue