audio: remove WAVEFORMATEX from internal demuxer API

Same as with the previous commit. A bit more involved due to how the
code is written.
This commit is contained in:
wm4 2014-09-25 01:56:51 +02:00
parent fd7dde404d
commit 9c3c199558
5 changed files with 88 additions and 98 deletions

View File

@ -102,18 +102,6 @@ static void set_data_from_avframe(struct dec_audio *da)
da->decoded.planes[n] = priv->avframe->data[n];
}
static void set_from_wf(AVCodecContext *avctx, MP_WAVEFORMATEX *wf)
{
avctx->channels = wf->nChannels;
avctx->sample_rate = wf->nSamplesPerSec;
avctx->bit_rate = wf->nAvgBytesPerSec * 8;
avctx->block_align = wf->nBlockAlign;
avctx->bits_per_coded_sample = wf->wBitsPerSample;
if (wf->cbSize > 0)
mp_lavc_set_extradata(avctx, wf + 1, wf->cbSize);
}
static int init(struct dec_audio *da, const char *decoder)
{
struct MPOpts *mpopts = da->opts;
@ -156,13 +144,13 @@ 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->block_align = sh_audio->block_align;
lavc_context->bits_per_coded_sample = sh_audio->bits_per_coded_sample;
lavc_context->channels = sh_audio->channels.num;
lavc_context->channel_layout = mp_chmap_to_lavc(&sh_audio->channels);
if (!mp_chmap_is_unknown(&sh_audio->channels))
lavc_context->channel_layout = mp_chmap_to_lavc(&sh_audio->channels);
if (sh_audio->wf)
set_from_wf(lavc_context, sh_audio->wf);
// demux_mkv, demux_mpg
// demux_mkv
if (sh_audio->codecdata_len && sh_audio->codecdata &&
!lavc_context->extradata) {
mp_lavc_set_extradata(lavc_context, sh_audio->codecdata,
@ -183,8 +171,6 @@ static int init(struct dec_audio *da, const char *decoder)
if (lavc_context->bit_rate != 0)
da->bitrate = lavc_context->bit_rate;
else if (sh_audio->wf && sh_audio->wf->nAvgBytesPerSec)
da->bitrate = sh_audio->wf->nAvgBytesPerSec * 8;
return 1;
}

View File

@ -386,9 +386,9 @@ void mp_set_codec_from_tag(struct sh_stream *sh)
sh->codec = lookup_tag(mp_audio_codec_tags,
avformat_get_riff_audio_tags(),
sh->format);
if (sh->audio && sh->audio->wf) {
if (sh->audio && sh->audio->bits_per_coded_sample) {
const char *codec =
map_audio_pcm_tag(sh->format, sh->audio->wf->wBitsPerSample);
map_audio_pcm_tag(sh->format, sh->audio->bits_per_coded_sample);
if (codec)
sh->codec = codec;
}

View File

@ -460,7 +460,7 @@ static void handle_stream(demuxer_t *demuxer, int i)
sh->format = codec->codec_tag;
// probably unneeded
mp_chmap_from_channels(&sh_audio->channels, codec->channels);
mp_chmap_set_unknown(&sh_audio->channels, codec->channels);
if (codec->channel_layout)
mp_chmap_from_lavc(&sh_audio->channels, codec->channel_layout);
sh_audio->samplerate = codec->sample_rate;

View File

@ -1327,15 +1327,6 @@ static const struct mkv_audio_tag {
{ NULL },
};
static void copy_audio_private_data(sh_audio_t *sh, mkv_track_t *track)
{
if (!track->ms_compat && track->private_size) {
sh->codecdata = talloc_size(sh, track->private_size);
sh->codecdata_len = track->private_size;
memcpy(sh->codecdata, track->private_data, track->private_size);
}
}
static int demux_mkv_open_audio(demuxer_t *demuxer, mkv_track_t *track)
{
struct sh_stream *sh = new_sh_stream(demuxer, STREAM_AUDIO);
@ -1344,6 +1335,9 @@ static int demux_mkv_open_audio(demuxer_t *demuxer, mkv_track_t *track)
track->stream = sh;
sh_audio_t *sh_a = sh->audio;
unsigned char *extradata = NULL;
int extradata_len = 0;
if (track->language && (strcmp(track->language, "und") != 0))
sh->lang = talloc_strdup(sh_a, track->language);
sh->demuxer_id = track->tnum;
@ -1352,29 +1346,29 @@ static int demux_mkv_open_audio(demuxer_t *demuxer, mkv_track_t *track)
if (!track->a_osfreq)
track->a_osfreq = track->a_sfreq;
if (track->ms_compat) {
if (track->private_size < sizeof(*sh_a->wf))
if (track->private_size < sizeof(MP_WAVEFORMATEX))
goto error;
MP_VERBOSE(demuxer, "track with MS compat audio.\n");
MP_WAVEFORMATEX *wf = (MP_WAVEFORMATEX *) track->private_data;
sh_a->wf = talloc_zero_size(sh_a, track->private_size);
sh_a->wf->wFormatTag = le2me_16(wf->wFormatTag);
sh_a->wf->nChannels = le2me_16(wf->nChannels);
sh_a->wf->nSamplesPerSec = le2me_32(wf->nSamplesPerSec);
sh_a->wf->nAvgBytesPerSec = le2me_32(wf->nAvgBytesPerSec);
sh_a->wf->nBlockAlign = le2me_16(wf->nBlockAlign);
sh_a->wf->wBitsPerSample = le2me_16(wf->wBitsPerSample);
sh_a->wf->cbSize = track->private_size - sizeof(*sh_a->wf);
memcpy(sh_a->wf + 1, wf + 1,
track->private_size - sizeof(*sh_a->wf));
MP_WAVEFORMATEX *wf = (void *)track->private_data;
wf->wFormatTag = le2me_16(wf->wFormatTag);
wf->nChannels = le2me_16(wf->nChannels);
wf->nSamplesPerSec = le2me_32(wf->nSamplesPerSec);
wf->nAvgBytesPerSec = le2me_32(wf->nAvgBytesPerSec);
wf->nBlockAlign = le2me_16(wf->nBlockAlign);
wf->wBitsPerSample = le2me_16(wf->wBitsPerSample);
wf->cbSize = track->private_size - sizeof(*wf);
extradata = track->private_data + sizeof(*wf);
extradata_len = track->private_size - sizeof(*wf);
if (track->a_osfreq == 0.0)
track->a_osfreq = sh_a->wf->nSamplesPerSec;
track->a_osfreq = wf->nSamplesPerSec;
if (track->a_channels == 0)
track->a_channels = sh_a->wf->nChannels;
track->a_channels = wf->nChannels;
if (track->a_bps == 0)
track->a_bps = sh_a->wf->wBitsPerSample;
track->a_formattag = sh_a->wf->wFormatTag;
track->a_bps = wf->wBitsPerSample;
track->a_formattag = wf->wFormatTag;
sh_a->bitrate = wf->nAvgBytesPerSec * 8;
sh_a->block_align = wf->nBlockAlign;
} else {
sh_a->wf = talloc_zero(sh_a, MP_WAVEFORMATEX);
for (int i = 0; ; i++) {
const struct mkv_audio_tag *t = mkv_audio_tags + i;
if (t->id == NULL)
@ -1393,23 +1387,21 @@ static int demux_mkv_open_audio(demuxer_t *demuxer, mkv_track_t *track)
}
sh->format = track->a_formattag;
sh_a->wf->wFormatTag = track->a_formattag;
mp_chmap_from_channels(&sh_a->channels, track->a_channels);
sh_a->wf->nChannels = track->a_channels;
mp_chmap_set_unknown(&sh_a->channels, track->a_channels);
sh_a->samplerate = (uint32_t) track->a_osfreq;
sh_a->wf->nSamplesPerSec = (uint32_t) track->a_osfreq;
if (track->a_bps == 0)
sh_a->wf->wBitsPerSample = 16;
sh_a->bits_per_coded_sample = 16;
else
sh_a->wf->wBitsPerSample = track->a_bps;
sh_a->bits_per_coded_sample = track->a_bps;
if (track->a_formattag == 0x0055) { /* MP3 || MP2 */
sh_a->wf->nAvgBytesPerSec = 16000;
sh_a->wf->nBlockAlign = 1152;
sh_a->bitrate = 16000 * 8;
sh_a->block_align = 1152;
} else if ((track->a_formattag == 0x2000) /* AC3 */
|| track->a_formattag == MP_FOURCC('E', 'A', 'C', '3')
|| (track->a_formattag == 0x2001)) { /* DTS */
talloc_free(sh_a->wf);
sh_a->wf = NULL;
sh_a->bits_per_coded_sample = 0;
sh_a->bitrate = 0;
sh_a->block_align = 0;
} else if (track->a_formattag == 0x0001) { /* PCM || PCM_BE */
if (!strcmp(track->codec_id, MKV_A_PCM_BE))
sh->format = MP_FOURCC('t', 'w', 'o', 's');
@ -1417,17 +1409,23 @@ static int demux_mkv_open_audio(demuxer_t *demuxer, mkv_track_t *track)
/* ok */
} else if (!strcmp(track->codec_id, MKV_A_QDMC)
|| !strcmp(track->codec_id, MKV_A_QDMC2)) {
sh_a->wf->nAvgBytesPerSec = 16000;
sh_a->wf->nBlockAlign = 1486;
copy_audio_private_data(sh_a, track);
sh_a->bitrate = 16000 * 8;
sh_a->block_align = 1486;
if (!extradata_len) {
extradata = track->private_data;
extradata_len = track->private_size;
}
} else if (track->a_formattag == MP_FOURCC('M', 'P', '4', 'A')) {
int profile, srate_idx;
sh_a->wf->nAvgBytesPerSec = 16000;
sh_a->wf->nBlockAlign = 1024;
sh_a->bitrate = 16000 * 8;
sh_a->block_align = 1024;
if (!strcmp(track->codec_id, MKV_A_AAC) && track->private_data) {
copy_audio_private_data(sh_a, track);
if (!extradata_len) {
extradata = track->private_data;
extradata_len = track->private_size;
}
} else {
/* Recreate the 'private data' */
/* which faad2 uses in its initialization */
@ -1449,7 +1447,6 @@ static int demux_mkv_open_audio(demuxer_t *demuxer, mkv_track_t *track)
/* HE-AAC (aka SBR AAC) */
sh_a->codecdata_len = 5;
sh_a->samplerate = sh_a->wf->nSamplesPerSec = track->a_osfreq;
srate_idx = aac_get_sample_rate_index(sh_a->samplerate);
sh_a->codecdata[2] = AAC_SYNC_EXTENSION_TYPE >> 3;
sh_a->codecdata[3] = ((AAC_SYNC_EXTENSION_TYPE & 0x07) << 5) | 5;
@ -1462,21 +1459,19 @@ static int demux_mkv_open_audio(demuxer_t *demuxer, mkv_track_t *track)
}
} else if (track->a_formattag == MP_FOURCC('v', 'r', 'b', 's')) {
/* VORBIS */
if (track->private_size == 0 || track->ms_compat && !sh_a->wf->cbSize)
if (track->private_size == 0 || (track->ms_compat && !extradata_len))
goto error;
if (!track->ms_compat) {
if (track->private_size > 0x1000000)
goto error;
sh_a->wf->cbSize = track->private_size;
sh_a->wf = talloc_realloc_size(sh_a, sh_a->wf,
sizeof(*sh_a->wf) + sh_a->wf->cbSize);
memcpy((unsigned char *) (sh_a->wf + 1), track->private_data,
sh_a->wf->cbSize);
extradata = track->private_data;
extradata_len = track->private_size;
}
} else if (!strcmp(track->codec_id, MKV_A_OPUS)
|| !strcmp(track->codec_id, MKV_A_OPUS_EXP)) {
sh->format = MP_FOURCC('O', 'p', 'u', 's');
copy_audio_private_data(sh_a, track);
if (!track->ms_compat) {
extradata = track->private_data;
extradata_len = track->private_size;
}
} else if (!strncmp(track->codec_id, MKV_A_REALATRC, 7)) {
if (track->private_size < RAPROPERTIES4_SIZE)
goto error;
@ -1485,13 +1480,13 @@ static int demux_mkv_open_audio(demuxer_t *demuxer, mkv_track_t *track)
int codecdata_length, version;
int flavor;
sh_a->wf->nAvgBytesPerSec = 0; /* FIXME !? */
sh_a->bitrate = 0; /* FIXME !? */
version = AV_RB16(src + 4);
flavor = AV_RB16(src + 22);
track->coded_framesize = AV_RB32(src + 24);
track->sub_packet_h = AV_RB16(src + 40);
sh_a->wf->nBlockAlign = track->audiopk_size = AV_RB16(src + 42);
sh_a->block_align = track->audiopk_size = AV_RB16(src + 42);
track->sub_packet_size = AV_RB16(src + 44);
if (version == 4) {
src += RAPROPERTIES4_SIZE;
@ -1514,27 +1509,25 @@ static int demux_mkv_open_audio(demuxer_t *demuxer, mkv_track_t *track)
if (codecdata_length < 0 || codecdata_length > 0x1000000)
goto error;
src += 4;
sh_a->wf->cbSize = codecdata_length;
sh_a->wf = talloc_realloc_size(sh_a, sh_a->wf,
sizeof(*sh_a->wf) + sh_a->wf->cbSize);
memcpy(((char *) (sh_a->wf + 1)), src, codecdata_length);
extradata_len = codecdata_length;
extradata = src;
switch (track->a_formattag) {
case MP_FOURCC('a', 't', 'r', 'c'):
sh_a->wf->nAvgBytesPerSec = atrc_fl2bps[flavor];
sh_a->wf->nBlockAlign = track->sub_packet_size;
sh_a->bitrate = atrc_fl2bps[flavor] * 8;
sh_a->block_align = track->sub_packet_size;
goto audiobuf;
case MP_FOURCC('c', 'o', 'o', 'k'):
sh_a->wf->nAvgBytesPerSec = cook_fl2bps[flavor];
sh_a->wf->nBlockAlign = track->sub_packet_size;
sh_a->bitrate = cook_fl2bps[flavor] * 8;
sh_a->block_align = track->sub_packet_size;
goto audiobuf;
case MP_FOURCC('s', 'i', 'p', 'r'):
sh_a->wf->nAvgBytesPerSec = sipr_fl2bps[flavor];
sh_a->wf->nBlockAlign = track->coded_framesize;
sh_a->bitrate = sipr_fl2bps[flavor] * 8;
sh_a->block_align = track->coded_framesize;
goto audiobuf;
case MP_FOURCC('2', '8', '_', '8'):
sh_a->wf->nAvgBytesPerSec = 3600;
sh_a->wf->nBlockAlign = track->coded_framesize;
sh_a->bitrate = 3600 * 8;
sh_a->block_align = track->coded_framesize;
audiobuf:
track->audio_buf =
talloc_array_size(track, track->sub_packet_h, track->audiopk_size);
@ -1548,16 +1541,17 @@ static int demux_mkv_open_audio(demuxer_t *demuxer, mkv_track_t *track)
|| (track->a_formattag == 0xf1ac)) {
unsigned char *ptr;
int size;
talloc_free(sh_a->wf);
sh_a->wf = NULL;
sh_a->bits_per_coded_sample = 0;
sh_a->bitrate = 0;
sh_a->block_align = 0;
if (!track->ms_compat) {
ptr = track->private_data;
size = track->private_size;
} else {
sh->format = MP_FOURCC('f', 'L', 'a', 'C');
ptr = track->private_data + sizeof(*sh_a->wf);
size = track->private_size - sizeof(*sh_a->wf);
ptr = extradata;
size = extradata_len;
}
if (size < 4 || ptr[0] != 'f' || ptr[1] != 'L' || ptr[2] != 'a'
|| ptr[3] != 'C') {
@ -1581,7 +1575,10 @@ static int demux_mkv_open_audio(demuxer_t *demuxer, mkv_track_t *track)
}
} else if (track->a_formattag == MP_FOURCC('W', 'V', 'P', 'K') ||
track->a_formattag == MP_FOURCC('T', 'R', 'H', 'D')) {
copy_audio_private_data(sh_a, track);
if (!track->ms_compat) {
extradata = track->private_data;
extradata_len = track->private_size;
}
} else if (track->a_formattag == MP_FOURCC('T', 'T', 'A', '1')) {
sh_a->codecdata_len = 30;
sh_a->codecdata = talloc_zero_size(sh_a, sh_a->codecdata_len);
@ -1591,7 +1588,7 @@ static int demux_mkv_open_audio(demuxer_t *demuxer, mkv_track_t *track)
memcpy(data + 0, "TTA1", 4);
AV_WL16(data + 4, 1);
AV_WL16(data + 6, sh_a->channels.num);
AV_WL16(data + 8, sh_a->wf->wBitsPerSample);
AV_WL16(data + 8, sh_a->bits_per_coded_sample);
AV_WL32(data + 10, track->a_osfreq);
// Bogus: last frame won't be played.
AV_WL32(data + 14, 0);
@ -1607,6 +1604,14 @@ static int demux_mkv_open_audio(demuxer_t *demuxer, mkv_track_t *track)
mp_set_codec_from_tag(sh);
if (track->private_size > 0x1000000 || extradata_len > 0x1000000)
goto error;
if (!sh_a->codecdata && extradata) {
sh_a->codecdata = talloc_memdup(sh_a, extradata, extradata_len);
sh_a->codecdata_len = extradata_len;
}
return 0;
error:
@ -2088,7 +2093,7 @@ static void handle_realaudio(demuxer_t *demuxer, mkv_track_t *track,
if (++(track->sub_packet_cnt) == sph) {
track->sub_packet_cnt = 0;
// apk_usize has same range as coded_framesize in worst case
uint32_t apk_usize = track->stream->audio->wf->nBlockAlign;
uint32_t apk_usize = track->stream->audio->block_align;
if (apk_usize > audiobuf_size)
goto error;
// Release all the audio packets

View File

@ -69,9 +69,8 @@ typedef struct sh_audio {
struct mp_chmap channels;
bool force_channels;
int bitrate; // compressed bits/sec
// win32-compatible codec parameters:
MP_WAVEFORMATEX *wf;
// note codec extradata may be either under "wf" or "codecdata"
int block_align;
int bits_per_coded_sample;
unsigned char *codecdata;
int codecdata_len;
struct replaygain_data *replaygain_data;