summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--DOCS/man/options.rst1
-rw-r--r--audio/decode/ad_lavc.c37
-rw-r--r--demux/codec_tags.c16
-rw-r--r--demux/codec_tags.h4
-rw-r--r--demux/demux_raw.c61
-rw-r--r--demux/demux_tv.c30
-rw-r--r--demux/stheader.h2
7 files changed, 66 insertions, 85 deletions
diff --git a/DOCS/man/options.rst b/DOCS/man/options.rst
index 70a11e7cc3..b61484ccfe 100644
--- a/DOCS/man/options.rst
+++ b/DOCS/man/options.rst
@@ -2005,6 +2005,7 @@ Demuxer
``--demuxer-rawaudio-format=<value>``
Sample format for ``--demuxer=rawaudio`` (default: s16le).
+ Use ``--demuxer-rawaudio-format=help`` to get a list of all formats.
``--demuxer-rawaudio-rate=<value>``
Sample rate for ``--demuxer=rawaudio`` (default: 44 kHz).
diff --git a/audio/decode/ad_lavc.c b/audio/decode/ad_lavc.c
index 443cfdad54..56d68bbd90 100644
--- a/audio/decode/ad_lavc.c
+++ b/audio/decode/ad_lavc.c
@@ -94,35 +94,6 @@ static const struct pcm_map tag_map[] = {
{-1},
};
-// For demux_rawaudio.c; needed because ffmpeg doesn't have these sample
-// formats natively.
-static const struct pcm_map af_map_le[] = {
- {AF_FORMAT_U8, {"pcm_u8"}},
- {AF_FORMAT_S8, {"pcm_u8"}},
- {AF_FORMAT_U16, {"pcm_u16le"}},
- {AF_FORMAT_S16, {"pcm_s16le"}},
- {AF_FORMAT_U24, {"pcm_u24le"}},
- {AF_FORMAT_S24, {"pcm_s24le"}},
- {AF_FORMAT_U32, {"pcm_u32le"}},
- {AF_FORMAT_S32, {"pcm_s32le"}},
- {AF_FORMAT_FLOAT, {"pcm_f32le"}},
- {AF_FORMAT_DOUBLE, {"pcm_f64le"}},
- {-1},
-};
-static const struct pcm_map af_map_be[] = {
- {AF_FORMAT_U8, {"pcm_u8"}},
- {AF_FORMAT_S8, {"pcm_u8"}},
- {AF_FORMAT_U16, {"pcm_u16be"}},
- {AF_FORMAT_S16, {"pcm_s16be"}},
- {AF_FORMAT_U24, {"pcm_u24be"}},
- {AF_FORMAT_S24, {"pcm_s24be"}},
- {AF_FORMAT_U32, {"pcm_u32be"}},
- {AF_FORMAT_S32, {"pcm_s32be"}},
- {AF_FORMAT_FLOAT, {"pcm_f32be"}},
- {AF_FORMAT_DOUBLE, {"pcm_f64be"}},
- {-1},
-};
-
static const char *find_pcm_decoder(const struct pcm_map *map, int format,
int bits_per_sample)
{
@@ -202,12 +173,10 @@ static int init(struct dec_audio *da, const char *decoder)
if (sh_audio->wf && strcmp(decoder, "pcm") == 0) {
decoder = find_pcm_decoder(tag_map, sh->format,
sh_audio->wf->wBitsPerSample);
- } else if (sh_audio->wf && strcmp(decoder, "mp-pcm") == 0) {
- const struct pcm_map *map = sh_audio->big_endian ? af_map_be : af_map_le;
- decoder = find_pcm_decoder(map, sh->format, 0);
- ctx->force_channel_map = true;
}
+ ctx->force_channel_map = sh_audio->force_channels;
+
lavc_codec = avcodec_find_decoder_by_name(decoder);
if (!lavc_codec) {
MP_ERR(da, "Cannot find codec '%s' in libavcodec...\n", decoder);
@@ -236,6 +205,7 @@ static int init(struct dec_audio *da, const char *decoder)
lavc_context->codec_tag = sh->format;
lavc_context->sample_rate = sh_audio->samplerate;
lavc_context->bit_rate = sh_audio->bitrate;
+ lavc_context->channels = sh_audio->channels.num;
lavc_context->channel_layout = mp_chmap_to_lavc(&sh_audio->channels);
if (sh_audio->wf)
@@ -367,7 +337,6 @@ static void add_decoders(struct mp_decoder_list *list)
{
mp_add_lavc_decoders(list, AVMEDIA_TYPE_AUDIO);
mp_add_decoder(list, "lavc", "pcm", "pcm", "Raw PCM");
- mp_add_decoder(list, "lavc", "mp-pcm", "mp-pcm", "Raw PCM");
}
const struct ad_functions ad_lavc = {
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;