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]; 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) static int init(struct dec_audio *da, const char *decoder)
{ {
struct MPOpts *mpopts = da->opts; 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->codec_tag = sh->format;
lavc_context->sample_rate = sh_audio->samplerate; lavc_context->sample_rate = sh_audio->samplerate;
lavc_context->bit_rate = sh_audio->bitrate; 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->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) // demux_mkv
set_from_wf(lavc_context, sh_audio->wf);
// demux_mkv, demux_mpg
if (sh_audio->codecdata_len && sh_audio->codecdata && if (sh_audio->codecdata_len && sh_audio->codecdata &&
!lavc_context->extradata) { !lavc_context->extradata) {
mp_lavc_set_extradata(lavc_context, sh_audio->codecdata, 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) if (lavc_context->bit_rate != 0)
da->bitrate = lavc_context->bit_rate; da->bitrate = lavc_context->bit_rate;
else if (sh_audio->wf && sh_audio->wf->nAvgBytesPerSec)
da->bitrate = sh_audio->wf->nAvgBytesPerSec * 8;
return 1; 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, sh->codec = lookup_tag(mp_audio_codec_tags,
avformat_get_riff_audio_tags(), avformat_get_riff_audio_tags(),
sh->format); sh->format);
if (sh->audio && sh->audio->wf) { if (sh->audio && sh->audio->bits_per_coded_sample) {
const char *codec = 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) if (codec)
sh->codec = codec; sh->codec = codec;
} }

View File

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

View File

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

View File

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