audio: don't write decoded audio format to sh_audio

sh_audio is supposed to contain file headers, not whatever was decoded.
Fix this, and write the decoded format to separate fields in the decoder
context, the dec_audio.decoded field. (Note that this field is really
only needed to communicate the audio format from decoder driver to the
generic code, so no other code accesses it.)
This commit is contained in:
wm4 2013-11-23 21:25:05 +01:00
parent 0f5ec05d8f
commit e174d31fdd
7 changed files with 55 additions and 56 deletions

View File

@ -161,9 +161,9 @@ static int setup_format(struct dec_audio *da)
lavc_chmap = sh_audio->channels;
}
sh_audio->channels = lavc_chmap;
sh_audio->samplerate = samplerate;
sh_audio->sample_format = sample_format;
mp_audio_set_channels(&da->decoded, &lavc_chmap);
mp_audio_set_format(&da->decoded, sample_format);
da->decoded.rate = samplerate;
return 0;
}
@ -366,9 +366,7 @@ static int decode_new_packet(struct dec_audio *da)
return -1;
priv->frame.samples = priv->avframe->nb_samples;
mp_audio_set_format(&priv->frame, da->header->audio->sample_format);
mp_audio_set_channels(&priv->frame, &da->header->audio->channels);
priv->frame.rate = da->header->audio->samplerate;
mp_audio_copy_config(&priv->frame, &da->decoded);
for (int n = 0; n < priv->frame.num_planes; n++)
priv->frame.planes[n] = priv->avframe->data[n];

View File

@ -151,8 +151,8 @@ static int set_format(struct dec_audio *da)
int encoding;
ret = mpg123_getformat(con->handle, &rate, &channels, &encoding);
if (ret == MPG123_OK) {
mp_chmap_from_channels(&da->header->audio->channels, channels);
da->header->audio->samplerate = rate;
mp_audio_set_num_channels(&da->decoded, channels);
da->decoded.rate = rate;
int af = mpg123_format_to_af(encoding);
if (!af) {
/* This means we got a funny custom build of libmpg123 that only supports an unknown format. */
@ -160,7 +160,7 @@ static int set_format(struct dec_audio *da)
"Bad encoding from mpg123: %i.\n", encoding);
return MPG123_ERR;
}
da->header->audio->sample_format = af;
mp_audio_set_format(&da->decoded, af);
con->sample_size = channels * (af_fmt2bits(af) / 8);
con->new_format = 0;
}
@ -308,9 +308,7 @@ static int decode_audio(struct dec_audio *da, struct mp_audio *buffer, int maxle
return -1;
}
if (da->header->audio->samplerate != buffer->rate ||
!mp_chmap_equals(&da->header->audio->channels, &buffer->channels) ||
da->header->audio->sample_format != buffer->format)
if (!mp_audio_config_equals(&da->decoded, buffer))
return 0;
size_t got_now = 0;

View File

@ -116,57 +116,59 @@ static int init(struct dec_audio *da, const char *decoder)
AVDictionary *format_opts = NULL;
int num_channels = 0;
struct sh_audio *sh = da->header->audio;
int sample_format = 0;
int samplerate = 0;
switch (stream->codec->codec_id) {
case AV_CODEC_ID_AAC:
spdif_ctx->iec61937_packet_size = 16384;
sh->sample_format = AF_FORMAT_IEC61937_LE;
sh->samplerate = 48000;
sample_format = AF_FORMAT_IEC61937_LE;
samplerate = 48000;
num_channels = 2;
break;
case AV_CODEC_ID_AC3:
spdif_ctx->iec61937_packet_size = 6144;
sh->sample_format = AF_FORMAT_AC3_LE;
sh->samplerate = 48000;
sample_format = AF_FORMAT_AC3_LE;
samplerate = 48000;
num_channels = 2;
break;
case AV_CODEC_ID_DTS:
if (sh->opts->dtshd) {
if (da->opts->dtshd) {
av_dict_set(&format_opts, "dtshd_rate", "768000", 0); // 4*192000
spdif_ctx->iec61937_packet_size = 32768;
sh->sample_format = AF_FORMAT_IEC61937_LE;
sh->samplerate = 192000; // DTS core require 48000
sample_format = AF_FORMAT_IEC61937_LE;
samplerate = 192000;
num_channels = 2*4;
} else {
spdif_ctx->iec61937_packet_size = 32768;
sh->sample_format = AF_FORMAT_AC3_LE;
sh->samplerate = 48000;
sample_format = AF_FORMAT_AC3_LE;
samplerate = 48000;
num_channels = 2;
}
break;
case AV_CODEC_ID_EAC3:
spdif_ctx->iec61937_packet_size = 24576;
sh->sample_format = AF_FORMAT_IEC61937_LE;
sh->samplerate = 192000;
sample_format = AF_FORMAT_IEC61937_LE;
samplerate = 192000;
num_channels = 2;
break;
case AV_CODEC_ID_MP3:
spdif_ctx->iec61937_packet_size = 4608;
sh->sample_format = AF_FORMAT_MPEG2;
sh->samplerate = 48000;
sample_format = AF_FORMAT_MPEG2;
samplerate = 48000;
num_channels = 2;
break;
case AV_CODEC_ID_TRUEHD:
spdif_ctx->iec61937_packet_size = 61440;
sh->sample_format = AF_FORMAT_IEC61937_LE;
sh->samplerate = 192000;
sample_format = AF_FORMAT_IEC61937_LE;
samplerate = 192000;
num_channels = 8;
break;
default:
abort();
}
if (num_channels)
mp_chmap_from_channels(&sh->channels, num_channels);
mp_audio_set_num_channels(&da->decoded, num_channels);
mp_audio_set_format(&da->decoded, sample_format);
da->decoded.rate = samplerate;
if (avformat_write_header(lavf_ctx, &format_opts) < 0) {
mp_msg(MSGT_DECAUDIO, MSGL_FATAL,
@ -190,7 +192,7 @@ static int decode_audio(struct dec_audio *da, struct mp_audio *buffer, int maxle
struct spdifContext *spdif_ctx = da->priv;
AVFormatContext *lavf_ctx = spdif_ctx->lavf_ctx;
int sstride = 2 * da->header->audio->channels.num;
int sstride = 2 * da->decoded.channels.num;
assert(sstride == buffer->sstride);
if (maxlen * sstride < spdif_ctx->iec61937_packet_size)

View File

@ -66,9 +66,7 @@ static const struct ad_functions * const ad_drivers[] = {
// Drop audio buffer and reinit it (after format change)
static void reinit_audio_buffer(struct dec_audio *da)
{
struct sh_audio *sh = da->header->audio;
mp_audio_buffer_reinit_fmt(da->decode_buffer, sh->sample_format,
&sh->channels, sh->samplerate);
mp_audio_buffer_reinit(da->decode_buffer, &da->decoded);
mp_audio_buffer_preallocate_min(da->decode_buffer, DECODE_BUFFER_SAMPLES);
}
@ -100,9 +98,8 @@ static int init_audio_codec(struct dec_audio *d_audio, const char *decoder)
d_audio->initialized = 1;
struct sh_audio *sh = d_audio->header->audio;
if (mp_chmap_is_empty(&sh->channels) || !sh->samplerate ||
!sh->sample_format)
if (!d_audio->decoded.channels.num || !d_audio->decoded.rate ||
!d_audio->decoded.format)
{
mp_tmsg(MSGT_DECAUDIO, MSGL_ERR, "Audio decoder did not specify "
"audio format!\n");
@ -177,12 +174,12 @@ int audio_init_best_codec(struct dec_audio *d_audio, char *audio_decoders)
d_audio->decoder_desc);
mp_msg(MSGT_DECAUDIO, MSGL_V,
"AUDIO: %d Hz, %d ch, %s\n",
d_audio->header->audio->samplerate, d_audio->header->audio->channels.num,
af_fmt_to_str(d_audio->header->audio->sample_format));
d_audio->decoded.rate, d_audio->decoded.channels.num,
af_fmt_to_str(d_audio->decoded.format));
mp_msg(MSGT_IDENTIFY, MSGL_INFO,
"ID_AUDIO_BITRATE=%d\nID_AUDIO_RATE=%d\n" "ID_AUDIO_NCH=%d\n",
d_audio->i_bps * 8, d_audio->header->audio->samplerate,
d_audio->header->audio->channels.num);
d_audio->i_bps * 8, d_audio->decoded.rate,
d_audio->decoded.channels.num);
} else {
mp_msg(MSGT_DECAUDIO, MSGL_ERR,
"Failed to initialize an audio decoder for codec '%s'.\n",
@ -269,11 +266,7 @@ static int filter_n_bytes(struct dec_audio *da, struct mp_audio_buffer *outbuf,
// Commit the data just read as valid data
mp_audio_buffer_finish_write(da->decode_buffer, buffer.samples);
// Format change
struct sh_audio *sh = da->header->audio;
if (sh->samplerate != config.rate ||
!mp_chmap_equals(&sh->channels, &config.channels) ||
sh->sample_format != config.format)
{
if (!mp_audio_config_equals(&da->decoded, &config)) {
// If there are still samples left in the buffer, let them drain
// first, and don't signal a format change to the caller yet.
if (mp_audio_buffer_samples(da->decode_buffer) > 0)

View File

@ -20,6 +20,7 @@
#define MPLAYER_DEC_AUDIO_H
#include "audio/chmap.h"
#include "audio/audio.h"
#include "demux/stheader.h"
struct mp_audio_buffer;
@ -34,7 +35,10 @@ struct dec_audio {
int initialized;
char *decoder_desc;
// set by decoder
int i_bps; // input bitrate
struct mp_audio decoded; // format of decoded audio (no data, temporarily
// different from decode_buffer during format
// changes)
int i_bps; // input bitrate, can change with VBR sources
// last known pts value in output from decoder
double pts;
// number of samples output by decoder after last known pts

View File

@ -87,8 +87,6 @@ struct sh_stream {
typedef struct sh_audio {
SH_COMMON
// output format:
int sample_format;
int samplerate;
struct mp_chmap channels;
int i_bps; // == bitrate (compressed bytes/sec)

View File

@ -48,6 +48,7 @@
#include "video/out/vo.h"
#include "video/csputils.h"
#include "audio/mixer.h"
#include "audio/audio_buffer.h"
#include "audio/out/ao.h"
#include "audio/filter/af.h"
#include "video/decode/dec_video.h"
@ -868,15 +869,17 @@ static int mp_property_audio_bitrate(m_option_t *prop, int action,
static int mp_property_samplerate(m_option_t *prop, int action, void *arg,
MPContext *mpctx)
{
if (!mpctx->d_audio)
struct mp_audio fmt = {0};
if (mpctx->d_audio)
mp_audio_buffer_get_format(mpctx->d_audio->decode_buffer, &fmt);
if (!fmt.rate)
return M_PROPERTY_UNAVAILABLE;
switch (action) {
case M_PROPERTY_PRINT:
*(char **)arg = talloc_asprintf(NULL, "%d kHz",
mpctx->d_audio->header->audio->samplerate / 1000);
*(char **)arg = talloc_asprintf(NULL, "%d kHz", fmt.rate / 1000);
return M_PROPERTY_OK;
case M_PROPERTY_GET:
*(int *)arg = mpctx->d_audio->header->audio->samplerate;
*(int *)arg = fmt.rate;
return M_PROPERTY_OK;
}
return M_PROPERTY_NOT_IMPLEMENTED;
@ -886,14 +889,17 @@ static int mp_property_samplerate(m_option_t *prop, int action, void *arg,
static int mp_property_channels(m_option_t *prop, int action, void *arg,
MPContext *mpctx)
{
if (!mpctx->d_audio)
struct mp_audio fmt = {0};
if (mpctx->d_audio)
mp_audio_buffer_get_format(mpctx->d_audio->decode_buffer, &fmt);
if (!fmt.channels.num)
return M_PROPERTY_UNAVAILABLE;
switch (action) {
case M_PROPERTY_PRINT:
*(char **) arg = mp_chmap_to_str(&mpctx->d_audio->header->audio->channels);
*(char **) arg = mp_chmap_to_str(&fmt.channels);
return M_PROPERTY_OK;
case M_PROPERTY_GET:
*(int *)arg = mpctx->d_audio->header->audio->channels.num;
*(int *)arg = fmt.channels.num;
return M_PROPERTY_OK;
}
return M_PROPERTY_NOT_IMPLEMENTED;