diff options
-rw-r--r-- | audio/decode/ad_lavc.c | 24 | ||||
-rw-r--r-- | demux/codec_tags.c | 4 | ||||
-rw-r--r-- | demux/demux_lavf.c | 2 | ||||
-rw-r--r-- | demux/demux_mkv.c | 151 | ||||
-rw-r--r-- | demux/stheader.h | 5 |
5 files changed, 88 insertions, 98 deletions
diff --git a/audio/decode/ad_lavc.c b/audio/decode/ad_lavc.c index a590de92fd..cb65cda184 100644 --- a/audio/decode/ad_lavc.c +++ b/audio/decode/ad_lavc.c @@ -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 (sh_audio->wf) - set_from_wf(lavc_context, sh_audio->wf); + if (!mp_chmap_is_unknown(&sh_audio->channels)) + lavc_context->channel_layout = mp_chmap_to_lavc(&sh_audio->channels); - // 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; } diff --git a/demux/codec_tags.c b/demux/codec_tags.c index 0833757b31..451d9539df 100644 --- a/demux/codec_tags.c +++ b/demux/codec_tags.c @@ -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; } diff --git a/demux/demux_lavf.c b/demux/demux_lavf.c index 750f0f09f3..578e061d46 100644 --- a/demux/demux_lavf.c +++ b/demux/demux_lavf.c @@ -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; diff --git a/demux/demux_mkv.c b/demux/demux_mkv.c index 27be3a169f..5b4864298c 100644 --- a/demux/demux_mkv.c +++ b/demux/demux_mkv.c @@ -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 diff --git a/demux/stheader.h b/demux/stheader.h index a368074d99..a7d1318ff6 100644 --- a/demux/stheader.h +++ b/demux/stheader.h @@ -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; |