diff options
Diffstat (limited to 'demux')
-rw-r--r-- | demux/codec_tags.c | 16 | ||||
-rw-r--r-- | demux/codec_tags.h | 4 | ||||
-rw-r--r-- | demux/demux_raw.c | 61 | ||||
-rw-r--r-- | demux/demux_tv.c | 30 | ||||
-rw-r--r-- | demux/stheader.h | 2 |
5 files changed, 62 insertions, 51 deletions
diff --git a/demux/codec_tags.c b/demux/codec_tags.c index 3f5a3e0922..23e1935dba 100644 --- a/demux/codec_tags.c +++ b/demux/codec_tags.c @@ -383,3 +383,19 @@ uint32_t mp_video_fourcc_alias(uint32_t fourcc) } return fourcc; } + +void mp_set_pcm_codec(struct sh_stream *sh, bool sign, bool is_float, int bits, + bool is_be) +{ + // This uses libavcodec pcm codec names, e.g. "pcm_u16le". + char codec[64] = "pcm_"; + if (is_float) { + mp_snprintf_cat(codec, sizeof(codec), "f"); + } else { + mp_snprintf_cat(codec, sizeof(codec), sign ? "s" : "u"); + } + mp_snprintf_cat(codec, sizeof(codec), "%d", bits); + if (bits != 8) + mp_snprintf_cat(codec, sizeof(codec), is_be ? "be" : "le"); + sh->codec = talloc_strdup(sh->audio, codec); +} diff --git a/demux/codec_tags.h b/demux/codec_tags.h index d8c63800b1..b65b68792a 100644 --- a/demux/codec_tags.h +++ b/demux/codec_tags.h @@ -19,6 +19,7 @@ #define MP_CODEC_TAGS_H #include <stdint.h> +#include <stdbool.h> uint32_t mp_video_fourcc_alias(uint32_t fourcc); @@ -26,4 +27,7 @@ struct sh_stream; void mp_set_codec_from_tag(struct sh_stream *sh); +void mp_set_pcm_codec(struct sh_stream *sh, bool sign, bool is_float, int bits, + bool is_be); + #endif diff --git a/demux/demux_raw.c b/demux/demux_raw.c index 552c74a2a3..6faea6e61d 100644 --- a/demux/demux_raw.c +++ b/demux/demux_raw.c @@ -29,7 +29,7 @@ #include "stream/stream.h" #include "demux.h" #include "stheader.h" -#include "audio/format.h" +#include "codec_tags.h" #include "video/img_format.h" #include "video/img_fourcc.h" @@ -40,16 +40,37 @@ struct demux_rawaudio_opts { struct mp_chmap channels; int samplerate; int aformat; - int endian; }; +// Ad-hoc schema to systematically encode the format as int +#define PCM(sign, is_float, bits, is_be) \ + ((sign) | ((is_float) << 1) | ((is_be) << 2) | ((bits) << 3)) +#define NE (BYTE_ORDER == BIG_ENDIAN) + #define OPT_BASE_STRUCT struct demux_rawaudio_opts const struct m_sub_options demux_rawaudio_conf = { .opts = (const m_option_t[]) { OPT_CHMAP("channels", channels, CONF_MIN, .min = 1), OPT_INTRANGE("rate", samplerate, 0, 1000, 8 * 48000), - OPT_AUDIOFORMAT("format", aformat, 0), - OPT_CHOICE("endian", endian, 0, ({"native", 0}, {"le", 1}, {"be", 2})), + OPT_CHOICE("format", aformat, 0, + ({"u8", PCM(0, 0, 8, 0)}, + {"s8", PCM(1, 0, 8, 0)}, + {"u16le", PCM(0, 0, 16, 0)}, {"u16be", PCM(0, 0, 16, 1)}, + {"s16le", PCM(1, 0, 16, 0)}, {"u16be", PCM(1, 0, 16, 1)}, + {"u24le", PCM(0, 0, 24, 0)}, {"u24be", PCM(0, 0, 24, 1)}, + {"s24le", PCM(1, 0, 24, 0)}, {"s24be", PCM(1, 0, 24, 1)}, + {"u32le", PCM(0, 0, 32, 0)}, {"u32be", PCM(0, 0, 32, 1)}, + {"s32le", PCM(1, 0, 32, 0)}, {"s32be", PCM(1, 0, 32, 1)}, + {"floatle", PCM(0, 1, 32, 0)}, {"floatbe", PCM(0, 1, 32, 1)}, + {"doublele",PCM(0, 1, 64, 0)}, {"doublebe", PCM(0, 1, 64, 1)}, + {"u16", PCM(0, 0, 16, NE)}, + {"s16", PCM(1, 0, 16, NE)}, + {"u24", PCM(0, 0, 24, NE)}, + {"s24", PCM(1, 0, 24, NE)}, + {"u32", PCM(0, 0, 32, NE)}, + {"s32", PCM(1, 0, 32, NE)}, + {"float", PCM(0, 1, 32, NE)}, + {"double", PCM(0, 1, 64, NE)})), {0} }, .size = sizeof(struct demux_rawaudio_opts), @@ -57,11 +78,13 @@ const struct m_sub_options demux_rawaudio_conf = { // Note that currently, stream_cdda expects exactly these parameters! .channels = MP_CHMAP_INIT_STEREO, .samplerate = 44100, - .aformat = AF_FORMAT_S16, - .endian = 0, + .aformat = PCM(1, 0, 16, NE), // s16 }, }; +#undef PCM +#undef NE + struct demux_rawvideo_opts { int vformat; int mp_format; @@ -105,32 +128,20 @@ static int demux_rawaudio_open(demuxer_t *demuxer, enum demux_check check) struct demux_rawaudio_opts *opts = demuxer->opts->demux_rawaudio; struct sh_stream *sh; sh_audio_t *sh_audio; - MP_WAVEFORMATEX *w; if (check != DEMUX_CHECK_REQUEST && check != DEMUX_CHECK_FORCE) return -1; - if (AF_FORMAT_IS_SPECIAL(opts->aformat)) - return -1; - sh = new_sh_stream(demuxer, STREAM_AUDIO); sh_audio = sh->audio; - sh->codec = "mp-pcm"; - sh->format = opts->aformat; - sh_audio->wf = w = talloc_zero(sh, MP_WAVEFORMATEX); - w->wFormatTag = 0; sh_audio->channels = opts->channels; - w->nChannels = sh_audio->channels.num; - w->nSamplesPerSec = sh_audio->samplerate = opts->samplerate; - int samplesize = af_fmt2bps(opts->aformat); - w->nAvgBytesPerSec = sh_audio->samplerate * samplesize * w->nChannels; - w->nBlockAlign = w->nChannels * samplesize; - w->wBitsPerSample = 8 * samplesize; - w->cbSize = 0; - int machine_endian = BYTE_ORDER == BIG_ENDIAN ? 2 : 1; - int endian = opts->endian ? opts->endian : machine_endian; - // wav usually implies little endian - sh_audio->big_endian = endian == 2; + sh_audio->force_channels = true; + sh_audio->samplerate = opts->samplerate; + + int f = opts->aformat; + // See PCM(): sign float bits endian + mp_set_pcm_codec(sh, f & 1, f & 2, f >> 3, f & 4); + int samplesize = ((f >> 3) + 7) / 8; struct priv *p = talloc_ptrtype(demuxer, p); demuxer->priv = p; diff --git a/demux/demux_tv.c b/demux/demux_tv.c index a4421a86cf..198ca922e5 100644 --- a/demux/demux_tv.c +++ b/demux/demux_tv.c @@ -8,6 +8,7 @@ #include "options/options.h" #include "demux.h" +#include "codec_tags.h" #include "audio/format.h" #include "video/img_fourcc.h" @@ -105,11 +106,8 @@ static int demux_open_tv(demuxer_t *demuxer, enum demux_check check) switch(audio_format) { - case AF_FORMAT_U8: - case AF_FORMAT_S8: - case AF_FORMAT_U16: + // This is the only format any of the current inputs generate. case AF_FORMAT_S16: - case AF_FORMAT_S32: break; default: MP_ERR(tvh, "Audio type '%s' unsupported!\n", @@ -127,29 +125,11 @@ static int demux_open_tv(demuxer_t *demuxer, enum demux_check check) &nchannels); mp_chmap_from_channels(&sh_audio->channels, nchannels); - sh_a->codec = "mp-pcm"; - sh_a->format = audio_format; - - int samplesize = af_fmt2bps(audio_format); - int block_align = samplesize * sh_audio->channels.num; - int bytes_per_second = sh_audio->samplerate * block_align; - - sh_audio->bitrate = bytes_per_second * 8; - - // emulate WF for win32 codecs: - sh_audio->wf = talloc_zero(sh_audio, MP_WAVEFORMATEX); - sh_audio->wf->wFormatTag = sh_a->format; - sh_audio->wf->nChannels = sh_audio->channels.num; - sh_audio->wf->wBitsPerSample = samplesize * 8; - sh_audio->wf->nSamplesPerSec = sh_audio->samplerate; - sh_audio->wf->nBlockAlign = block_align; - sh_audio->wf->nAvgBytesPerSec = bytes_per_second; - // wav header usually implies little endian - sh_audio->big_endian = BYTE_ORDER == BIG_ENDIAN; + // s16ne + mp_set_pcm_codec(sh_a, true, false, 16, BYTE_ORDER == BIG_ENDIAN); MP_VERBOSE(tvh, " TV audio: %d channels, %d bits, %d Hz\n", - sh_audio->wf->nChannels, sh_audio->wf->wBitsPerSample, - sh_audio->wf->nSamplesPerSec); + nchannels, 16, sh_audio->samplerate); } no_audio: diff --git a/demux/stheader.h b/demux/stheader.h index 806f7d9c5a..a2740f0189 100644 --- a/demux/stheader.h +++ b/demux/stheader.h @@ -67,10 +67,10 @@ struct sh_stream { typedef struct sh_audio { int samplerate; struct mp_chmap channels; + bool force_channels; int bitrate; // compressed bits/sec // win32-compatible codec parameters: MP_WAVEFORMATEX *wf; - bool big_endian; // endianess with wf and mp-pcm // note codec extradata may be either under "wf" or "codecdata" unsigned char *codecdata; int codecdata_len; |