diff --git a/audio/decode/ad_spdif.c b/audio/decode/ad_spdif.c index 3c5e0ef6e1..bb39298dd6 100644 --- a/audio/decode/ad_spdif.c +++ b/audio/decode/ad_spdif.c @@ -117,13 +117,13 @@ static int init(struct dec_audio *da, const char *decoder) switch (stream->codec->codec_id) { case AV_CODEC_ID_AAC: spdif_ctx->iec61937_packet_size = 16384; - sample_format = AF_FORMAT_IEC61937; + sample_format = AF_FORMAT_S_AAC; samplerate = 48000; num_channels = 2; break; case AV_CODEC_ID_AC3: spdif_ctx->iec61937_packet_size = 6144; - sample_format = AF_FORMAT_AC3; + sample_format = AF_FORMAT_S_AC3; samplerate = 48000; num_channels = 2; break; @@ -131,31 +131,31 @@ static int init(struct dec_audio *da, const char *decoder) if (da->opts->dtshd) { av_dict_set(&format_opts, "dtshd_rate", "768000", 0); // 4*192000 spdif_ctx->iec61937_packet_size = 32768; - sample_format = AF_FORMAT_IEC61937; + sample_format = AF_FORMAT_S_DTSHD; samplerate = 192000; num_channels = 2*4; } else { spdif_ctx->iec61937_packet_size = 32768; - sample_format = AF_FORMAT_AC3; + sample_format = AF_FORMAT_S_DTS; samplerate = 48000; num_channels = 2; } break; case AV_CODEC_ID_EAC3: spdif_ctx->iec61937_packet_size = 24576; - sample_format = AF_FORMAT_IEC61937; + sample_format = AF_FORMAT_S_EAC3; samplerate = 192000; num_channels = 2; break; case AV_CODEC_ID_MP3: spdif_ctx->iec61937_packet_size = 4608; - sample_format = AF_FORMAT_MPEG2; + sample_format = AF_FORMAT_S_MP3; samplerate = 48000; num_channels = 2; break; case AV_CODEC_ID_TRUEHD: spdif_ctx->iec61937_packet_size = 61440; - sample_format = AF_FORMAT_IEC61937; + sample_format = AF_FORMAT_S_TRUEHD; samplerate = 192000; num_channels = 8; break; diff --git a/audio/filter/af_convertsignendian.c b/audio/filter/af_convertsignendian.c index 7e7e436352..52ae8164df 100644 --- a/audio/filter/af_convertsignendian.c +++ b/audio/filter/af_convertsignendian.c @@ -29,7 +29,7 @@ static bool test_conversion(int src_format, int dst_format) return false; if (((src_format & ~AF_FORMAT_SIGN_MASK) == (dst_format & ~AF_FORMAT_SIGN_MASK)) && - ((src_format & AF_FORMAT_POINT_MASK) == AF_FORMAT_I)) + ((src_format & AF_FORMAT_TYPE_MASK) == AF_FORMAT_I)) return true; return false; } diff --git a/audio/filter/af_lavcac3enc.c b/audio/filter/af_lavcac3enc.c index 0763057665..18bca8e2cb 100644 --- a/audio/filter/af_lavcac3enc.c +++ b/audio/filter/af_lavcac3enc.c @@ -88,7 +88,7 @@ static int control(struct af_instance *af, int cmd, void *arg) if (in->nch > AC3_MAX_CHANNELS) mp_audio_set_num_channels(in, AC3_MAX_CHANNELS); - mp_audio_set_format(af->data, AF_FORMAT_AC3); + mp_audio_set_format(af->data, AF_FORMAT_S_AC3); mp_audio_set_num_channels(af->data, 2); if (!mp_audio_config_equals(in, &orig_in)) diff --git a/audio/format.c b/audio/format.c index 60a86ea5ae..618a00e0c1 100644 --- a/audio/format.c +++ b/audio/format.c @@ -30,9 +30,6 @@ int af_fmt2bps(int format) { - if (AF_FORMAT_IS_AC3(format)) return 2; - if (format == AF_FORMAT_UNKNOWN) - return 0; switch (format & AF_FORMAT_BITS_MASK) { case AF_FORMAT_8BIT: return 1; case AF_FORMAT_16BIT: return 2; @@ -62,7 +59,7 @@ static int bits_to_mask(int bits) int af_fmt_change_bits(int format, int bits) { - if (!af_fmt_is_valid(format) || (format & AF_FORMAT_SPECIAL_MASK)) + if (!af_fmt_is_valid(format)) return 0; int mask = bits_to_mask(bits); format = (format & ~AF_FORMAT_BITS_MASK) | mask; @@ -110,10 +107,6 @@ bool af_fmt_is_planar(int format) } const struct af_fmt_entry af_fmtstr_table[] = { - {"mpeg2", AF_FORMAT_MPEG2}, - {"ac3", AF_FORMAT_AC3}, - {"iec61937", AF_FORMAT_IEC61937}, - {"u8", AF_FORMAT_U8}, {"s8", AF_FORMAT_S8}, {"u16", AF_FORMAT_U16}, @@ -131,6 +124,14 @@ const struct af_fmt_entry af_fmtstr_table[] = { {"floatp", AF_FORMAT_FLOATP}, {"doublep", AF_FORMAT_DOUBLEP}, + {"spdif-aac", AF_FORMAT_S_AAC}, + {"spdif-ac3", AF_FORMAT_S_AC3}, + {"spdif-dts", AF_FORMAT_S_DTS}, + {"spdif-dtshd", AF_FORMAT_S_DTSHD}, + {"spdif-eac3", AF_FORMAT_S_EAC3}, + {"spdif-mp3", AF_FORMAT_S_MP3}, + {"spdif-truehd",AF_FORMAT_S_TRUEHD}, + {0} }; @@ -199,9 +200,9 @@ int af_format_conversion_score(int dst_format, int src_format) score -= 1; // has to (de-)planarize if (FMT_DIFF(AF_FORMAT_SIGN_MASK, dst_format, src_format)) score -= 4; // has to swap sign - if (FMT_DIFF(AF_FORMAT_POINT_MASK, dst_format, src_format)) { + if (FMT_DIFF(AF_FORMAT_TYPE_MASK, dst_format, src_format)) { int dst_bits = dst_format & AF_FORMAT_BITS_MASK; - if ((dst_format & AF_FORMAT_POINT_MASK) == AF_FORMAT_F) { + if ((dst_format & AF_FORMAT_TYPE_MASK) == AF_FORMAT_F) { // For int->float, always prefer 32 bit float. score -= dst_bits == AF_FORMAT_32BIT ? 8 : 0; } else { @@ -217,7 +218,7 @@ int af_format_conversion_score(int dst_format, int src_format) } } // Consider this the worst case. - if (FMT_DIFF(AF_FORMAT_POINT_MASK, dst_format, src_format)) + if (FMT_DIFF(AF_FORMAT_TYPE_MASK, dst_format, src_format)) score -= 2048; // has to convert float<->int return score; } diff --git a/audio/format.h b/audio/format.h index 3662d817f1..06c5d566e5 100644 --- a/audio/format.h +++ b/audio/format.h @@ -28,39 +28,38 @@ #include "misc/bstr.h" // Signed/unsigned -#define AF_FORMAT_SI (0<<1) // Signed -#define AF_FORMAT_US (1<<1) // Unsigned -#define AF_FORMAT_SIGN_MASK (1<<1) +#define AF_FORMAT_SI (0<<0) // Signed +#define AF_FORMAT_US (1<<0) // Unsigned +#define AF_FORMAT_SIGN_MASK (1<<0) // Bits used // Some code assumes they're sorted by size. -#define AF_FORMAT_8BIT (0<<3) -#define AF_FORMAT_16BIT (1<<3) -#define AF_FORMAT_24BIT (2<<3) -#define AF_FORMAT_32BIT (3<<3) -#define AF_FORMAT_64BIT (4<<3) -#define AF_FORMAT_BITS_MASK (7<<3) +#define AF_FORMAT_8BIT (0<<1) +#define AF_FORMAT_16BIT (1<<1) +#define AF_FORMAT_24BIT (2<<1) +#define AF_FORMAT_32BIT (3<<1) +#define AF_FORMAT_64BIT (4<<1) +#define AF_FORMAT_BITS_MASK (7<<1) -// Special flags refering to non pcm data (note: 1<<6, 2<<6, 5<<6 unused) -#define AF_FORMAT_S_MPEG2 (3<<6) // MPEG(2) audio -#define AF_FORMAT_S_AC3 (4<<6) // Dolby Digital AC3 -#define AF_FORMAT_S_IEC61937 (6<<6) -#define AF_FORMAT_SPECIAL_MASK (7<<6) - -// Fixed or floating point -#define AF_FORMAT_I (1<<9) // Int -#define AF_FORMAT_F (2<<9) // Foating point -#define AF_FORMAT_POINT_MASK (3<<9) +// Fixed/floating point/special +#define AF_FORMAT_I (1<<4) // Int +#define AF_FORMAT_F (2<<4) // Foating point +#define AF_FORMAT_S (4<<4) // special (IEC61937) +#define AF_FORMAT_TYPE_MASK (7<<4) // Interleaving (planar formats have data for each channel in separate planes) -#define AF_FORMAT_INTERLEAVED (0<<11) // must be 0 -#define AF_FORMAT_PLANAR (1<<11) -#define AF_FORMAT_INTERLEAVING_MASK (1<<11) +#define AF_FORMAT_INTERLEAVED (0<<7) // must be 0 +#define AF_FORMAT_PLANAR (1<<7) +#define AF_FORMAT_INTERLEAVING_MASK (1<<7) + +#define AF_FORMAT_S_CODEC(n) ((n)<<8) +#define AF_FORMAT_S_CODEC_MASK (15 <<8) // 16 codecs max. #define AF_FORMAT_MASK ((1<<12)-1) #define AF_INTP (AF_FORMAT_I|AF_FORMAT_PLANAR) #define AF_FLTP (AF_FORMAT_F|AF_FORMAT_PLANAR) +#define AF_FORMAT_S_(n) (AF_FORMAT_S_CODEC(n)|AF_FORMAT_S|AF_FORMAT_16BIT) // actual sample formats enum af_format { @@ -78,27 +77,25 @@ enum af_format { AF_FORMAT_FLOAT = (AF_FORMAT_F|AF_FORMAT_32BIT), AF_FORMAT_DOUBLE = (AF_FORMAT_F|AF_FORMAT_64BIT), - AF_FORMAT_AC3 = (AF_FORMAT_S_AC3|AF_FORMAT_16BIT), - AF_FORMAT_IEC61937 = (AF_FORMAT_S_IEC61937|AF_FORMAT_16BIT), - AF_FORMAT_MPEG2 = (AF_FORMAT_S_MPEG2), - // Planar variants AF_FORMAT_U8P = (AF_INTP|AF_FORMAT_US|AF_FORMAT_8BIT), AF_FORMAT_S16P = (AF_INTP|AF_FORMAT_SI|AF_FORMAT_16BIT), AF_FORMAT_S32P = (AF_INTP|AF_FORMAT_SI|AF_FORMAT_32BIT), AF_FORMAT_FLOATP = (AF_FLTP|AF_FORMAT_32BIT), AF_FORMAT_DOUBLEP = (AF_FLTP|AF_FORMAT_64BIT), + + // All of these use IEC61937 framing, and otherwise pretend to be like PCM. + AF_FORMAT_S_AAC = AF_FORMAT_S_(0), + AF_FORMAT_S_AC3 = AF_FORMAT_S_(1), + AF_FORMAT_S_DTS = AF_FORMAT_S_(2), + AF_FORMAT_S_DTSHD = AF_FORMAT_S_(3), + AF_FORMAT_S_EAC3 = AF_FORMAT_S_(4), + AF_FORMAT_S_MP3 = AF_FORMAT_S_(5), + AF_FORMAT_S_TRUEHD = AF_FORMAT_S_(6), }; -#define AF_FORMAT_IS_AC3(fmt) \ - ((fmt) == AF_FORMAT_AC3) - -#define AF_FORMAT_IS_IEC61937(fmt) \ - (AF_FORMAT_IS_AC3(fmt) || \ - ((fmt) & AF_FORMAT_SPECIAL_MASK) == AF_FORMAT_S_IEC61937) - -#define AF_FORMAT_IS_SPECIAL(fmt) \ - ((fmt & AF_FORMAT_SPECIAL_MASK) != 0) +#define AF_FORMAT_IS_IEC61937(f) (((f) & AF_FORMAT_TYPE_MASK) == AF_FORMAT_S) +#define AF_FORMAT_IS_SPECIAL(f) AF_FORMAT_IS_IEC61937(f) struct af_fmt_entry { const char *name; diff --git a/audio/out/ao_alsa.c b/audio/out/ao_alsa.c index c344f6f20e..52f410cf5e 100644 --- a/audio/out/ao_alsa.c +++ b/audio/out/ao_alsa.c @@ -100,7 +100,7 @@ static int control(struct ao *ao, enum aocontrol cmd, void *arg) long get_vol, set_vol; float f_multi; - if (AF_FORMAT_IS_IEC61937(ao->format)) + if (AF_FORMAT_IS_SPECIAL(ao->format)) return CONTROL_FALSE; //allocate simple id @@ -218,9 +218,6 @@ static const int mp_to_alsa_format[][2] = { {AF_FORMAT_S24, MP_SELECT_LE_BE(SND_PCM_FORMAT_S24_3LE, SND_PCM_FORMAT_S24_3BE)}, {AF_FORMAT_FLOAT, SND_PCM_FORMAT_FLOAT}, - {AF_FORMAT_AC3, SND_PCM_FORMAT_S16}, - {AF_FORMAT_IEC61937, SND_PCM_FORMAT_S16}, - {AF_FORMAT_MPEG2, SND_PCM_FORMAT_MPEG}, {AF_FORMAT_UNKNOWN, SND_PCM_FORMAT_UNKNOWN}, }; @@ -403,7 +400,15 @@ static int init(struct ao *ao) err = snd_pcm_hw_params_any(p->alsa, alsa_hwparams); CHECK_ALSA_ERROR("Unable to get initial parameters"); - p->alsa_fmt = find_alsa_format(ao->format); + if (AF_FORMAT_IS_IEC61937(ao->format)) { + if (ao->format == AF_FORMAT_S_MP3) { + p->alsa_fmt = SND_PCM_FORMAT_MPEG; + } else { + p->alsa_fmt = SND_PCM_FORMAT_S16; + } + } else { + p->alsa_fmt = find_alsa_format(ao->format); + } if (p->alsa_fmt == SND_PCM_FORMAT_UNKNOWN) { p->alsa_fmt = SND_PCM_FORMAT_S16; ao->format = AF_FORMAT_S16; @@ -411,15 +416,12 @@ static int init(struct ao *ao) err = snd_pcm_hw_params_test_format(p->alsa, alsa_hwparams, p->alsa_fmt); if (err < 0) { + if (AF_FORMAT_IS_IEC61937(ao->format)) + CHECK_ALSA_ERROR("Unable to set IEC61937 format"); MP_INFO(ao, "Format %s is not supported by hardware, trying default.\n", af_fmt_to_str(ao->format)); p->alsa_fmt = SND_PCM_FORMAT_S16; - if (AF_FORMAT_IS_AC3(ao->format)) - ao->format = AF_FORMAT_AC3; - else if (AF_FORMAT_IS_IEC61937(ao->format)) - ao->format = AF_FORMAT_IEC61937; - else - ao->format = AF_FORMAT_S16; + ao->format = AF_FORMAT_S16; } err = snd_pcm_hw_params_set_format(p->alsa, alsa_hwparams, p->alsa_fmt); diff --git a/audio/out/ao_coreaudio_device.c b/audio/out/ao_coreaudio_device.c index 3ba1f0ce37..c221b62e59 100644 --- a/audio/out/ao_coreaudio_device.c +++ b/audio/out/ao_coreaudio_device.c @@ -410,8 +410,9 @@ static int init(struct ao *ao) ao->format = af_fmt_from_planar(ao->format); bool supports_digital = false; - /* Probe whether device support S/PDIF stream output if input is AC3 stream. */ - if (AF_FORMAT_IS_AC3(ao->format)) { + /* Probe whether device support S/PDIF stream output if input is AC3 stream, + * or anything else IEC61937-framed. */ + if (AF_FORMAT_IS_IEC61937(ao->format)) { if (ca_device_supports_digital(ao, p->device)) supports_digital = true; } diff --git a/audio/out/ao_coreaudio_utils.c b/audio/out/ao_coreaudio_utils.c index b39323ce72..08214ef387 100644 --- a/audio/out/ao_coreaudio_utils.c +++ b/audio/out/ao_coreaudio_utils.c @@ -130,14 +130,15 @@ bool check_ca_st(struct ao *ao, int level, OSStatus code, const char *message) void ca_fill_asbd(struct ao *ao, AudioStreamBasicDescription *asbd) { asbd->mSampleRate = ao->samplerate; - asbd->mFormatID = AF_FORMAT_IS_AC3(ao->format) ? + // Set "AC3" for other spdif formats too - unknown if that works. + asbd->mFormatID = AF_FORMAT_IS_IEC61937(ao->format) ? kAudioFormat60958AC3 : kAudioFormatLinearPCM; asbd->mChannelsPerFrame = ao->channels.num; asbd->mBitsPerChannel = af_fmt2bits(ao->format); asbd->mFormatFlags = kAudioFormatFlagIsPacked; - if ((ao->format & AF_FORMAT_POINT_MASK) == AF_FORMAT_F) + if ((ao->format & AF_FORMAT_TYPE_MASK) == AF_FORMAT_F) asbd->mFormatFlags |= kAudioFormatFlagIsFloat; if ((ao->format & AF_FORMAT_SIGN_MASK) == AF_FORMAT_SI) diff --git a/audio/out/ao_dsound.c b/audio/out/ao_dsound.c index 78b39b17b9..cd6a986831 100644 --- a/audio/out/ao_dsound.c +++ b/audio/out/ao_dsound.c @@ -382,21 +382,20 @@ static int init(struct ao *ao) int format = af_fmt_from_planar(ao->format); int rate = ao->samplerate; - if (AF_FORMAT_IS_AC3(format)) - format = AF_FORMAT_AC3; - else { + if (!AF_FORMAT_IS_IEC61937(format)) { struct mp_chmap_sel sel = {0}; mp_chmap_sel_add_waveext(&sel); if (!ao_chmap_sel_adjust(ao, &sel, &ao->channels)) return -1; } switch (format) { - case AF_FORMAT_AC3: case AF_FORMAT_S24: case AF_FORMAT_S16: case AF_FORMAT_U8: break; default: + if (AF_FORMAT_IS_IEC61937(format)) + break; MP_VERBOSE(ao, "format %s not supported defaulting to Signed 16-bit Little-Endian\n", af_fmt_to_str(format)); format = AF_FORMAT_S16; @@ -417,7 +416,8 @@ static int init(struct ao *ao) ? sizeof(WAVEFORMATEXTENSIBLE) - sizeof(WAVEFORMATEX) : 0; wformat.Format.nChannels = ao->channels.num; wformat.Format.nSamplesPerSec = rate; - if (AF_FORMAT_IS_AC3(format)) { + if (AF_FORMAT_IS_IEC61937(format)) { + // Whether it also works with e.g. DTS is unknown, but probably does. wformat.Format.wFormatTag = WAVE_FORMAT_DOLBY_AC3_SPDIF; wformat.Format.wBitsPerSample = 16; wformat.Format.nBlockAlign = 4; diff --git a/audio/out/ao_oss.c b/audio/out/ao_oss.c index de71017432..7780a08978 100644 --- a/audio/out/ao_oss.c +++ b/audio/out/ao_oss.c @@ -133,17 +133,14 @@ static const int format_table[][2] = { #endif #ifdef AFMT_FLOAT {AFMT_FLOAT, AF_FORMAT_FLOAT}, -#endif - // SPECIALS -#ifdef AFMT_MPEG - {AFMT_MPEG, AF_FORMAT_MPEG2}, -#endif -#ifdef AFMT_AC3 - {AFMT_AC3, AF_FORMAT_AC3}, #endif {-1, -1} }; +#ifndef AFMT_AC3 +#define AFMT_AC3 -1 +#endif + static int format2oss(int format) { for (int n = 0; format_table[n][0] != -1; n++) { @@ -204,7 +201,7 @@ static int control(struct ao *ao, enum aocontrol cmd, void *arg) return CONTROL_OK; #endif - if (AF_FORMAT_IS_AC3(ao->format)) + if (AF_FORMAT_IS_SPECIAL(ao->format)) return CONTROL_TRUE; if ((fd = open(p->oss_mixer_device, O_RDONLY)) != -1) { @@ -293,14 +290,16 @@ static int reopen_device(struct ao *ao, bool allow_format_changes) fcntl(p->audio_fd, F_SETFD, FD_CLOEXEC); #endif - if (AF_FORMAT_IS_AC3(format)) { + if (AF_FORMAT_IS_IEC61937(format)) { ioctl(p->audio_fd, SNDCTL_DSP_SPEED, &samplerate); } ac3_retry: - if (AF_FORMAT_IS_AC3(format)) - format = AF_FORMAT_AC3; - oss_format = format2oss(format); + if (AF_FORMAT_IS_IEC61937(format)) { + oss_format = format2oss(format); + } else { + oss_format = AFMT_AC3; + } if (oss_format == -1) { MP_VERBOSE(ao, "Unknown/not supported internal format: %s\n", af_fmt_to_str(format)); @@ -345,7 +344,7 @@ ac3_retry: MP_VERBOSE(ao, "sample format: %s\n", af_fmt_to_str(format)); - if (!AF_FORMAT_IS_AC3(format)) { + if (!AF_FORMAT_IS_IEC61937(format)) { struct mp_chmap_sel sel = {0}; for (int n = 0; n < MP_NUM_CHANNELS + 1; n++) mp_chmap_sel_add_map(&sel, &oss_layouts[n]); diff --git a/audio/out/ao_pcm.c b/audio/out/ao_pcm.c index eb089c6c42..8357174f95 100644 --- a/audio/out/ao_pcm.c +++ b/audio/out/ao_pcm.c @@ -137,10 +137,10 @@ static int init(struct ao *ao) case AF_FORMAT_S24: case AF_FORMAT_S32: case AF_FORMAT_FLOAT: - case AF_FORMAT_AC3: break; default: - ao->format = AF_FORMAT_S16; + if (!AF_FORMAT_IS_IEC61937(ao->format)) + ao->format = AF_FORMAT_S16; break; } } diff --git a/audio/out/ao_wasapi_utils.c b/audio/out/ao_wasapi_utils.c index c39eb6fea2..bf59d7802b 100755 --- a/audio/out/ao_wasapi_utils.c +++ b/audio/out/ao_wasapi_utils.c @@ -300,7 +300,7 @@ static int find_formats(struct ao *const ao) { struct wasapi_state *state = (struct wasapi_state *)ao->priv; - if (AF_FORMAT_IS_IEC61937(ao->format) || ao->format == AF_FORMAT_MPEG2) { + if (AF_FORMAT_IS_IEC61937(ao->format)) { if (try_passthrough(state, ao)) return 0; diff --git a/demux/demux_raw.c b/demux/demux_raw.c index 5dae30308a..552c74a2a3 100644 --- a/demux/demux_raw.c +++ b/demux/demux_raw.c @@ -110,7 +110,7 @@ static int demux_rawaudio_open(demuxer_t *demuxer, enum demux_check check) if (check != DEMUX_CHECK_REQUEST && check != DEMUX_CHECK_FORCE) return -1; - if ((opts->aformat & AF_FORMAT_SPECIAL_MASK) != 0) + if (AF_FORMAT_IS_SPECIAL(opts->aformat)) return -1; sh = new_sh_stream(demuxer, STREAM_AUDIO); diff --git a/player/audio.c b/player/audio.c index c74032f174..56e6c233c7 100644 --- a/player/audio.c +++ b/player/audio.c @@ -315,7 +315,7 @@ static bool get_sync_samples(struct MPContext *mpctx, int *skip) ao_get_format(mpctx->ao, &out_format); double play_samplerate = out_format.rate / opts->playback_speed; - bool is_pcm = !(out_format.format & AF_FORMAT_SPECIAL_MASK); // no spdif + bool is_pcm = !AF_FORMAT_IS_SPECIAL(out_format.format); // no spdif if (!opts->initial_audio_sync || !is_pcm) { mpctx->audio_status = STATUS_FILLING; return true;