mirror of https://github.com/mpv-player/mpv
ad_spdif: fix obscure cases of AC3 passthrough
Apparently you set the native sample rate when passing through AC3. This fixes passthrough with 44100 Hz AC3. Avoid opening a decoder for this and only open the parser. (Hopefully DTS will also support this some time in the future or so - having to open a decoder just to get the profile is dumb.)
This commit is contained in:
parent
da8011c5df
commit
c522d0dfbd
|
@ -93,13 +93,34 @@ static int init(struct dec_audio *da, const char *decoder)
|
|||
return spdif_ctx->codec_id != AV_CODEC_ID_NONE;
|
||||
}
|
||||
|
||||
static int determine_codec_profile(struct dec_audio *da, AVPacket *pkt)
|
||||
static void determine_codec_params(struct dec_audio *da, AVPacket *pkt,
|
||||
int *out_profile, int *out_rate)
|
||||
{
|
||||
struct spdifContext *spdif_ctx = da->priv;
|
||||
int profile = FF_PROFILE_UNKNOWN;
|
||||
AVCodecContext *ctx = NULL;
|
||||
AVFrame *frame = NULL;
|
||||
|
||||
AVCodecParserContext *parser = av_parser_init(spdif_ctx->codec_id);
|
||||
if (parser) {
|
||||
// Don't make it wait for the next frame.
|
||||
parser->flags |= PARSER_FLAG_COMPLETE_FRAMES;
|
||||
|
||||
ctx = avcodec_alloc_context3(NULL);
|
||||
|
||||
uint8_t *d = NULL;
|
||||
int s = 0;
|
||||
av_parser_parse2(parser, ctx, &d, &s, pkt->data, pkt->size, 0, 0, 0);
|
||||
*out_profile = profile = ctx->profile;
|
||||
*out_rate = ctx->sample_rate;
|
||||
|
||||
av_free(ctx);
|
||||
av_parser_close(parser);
|
||||
}
|
||||
|
||||
if (profile != FF_PROFILE_UNKNOWN || spdif_ctx->codec_id != AV_CODEC_ID_DTS)
|
||||
return;
|
||||
|
||||
AVCodec *codec = avcodec_find_decoder(spdif_ctx->codec_id);
|
||||
if (!codec)
|
||||
goto done;
|
||||
|
@ -123,7 +144,8 @@ static int determine_codec_profile(struct dec_audio *da, AVPacket *pkt)
|
|||
if (avcodec_receive_frame(ctx, frame) < 0)
|
||||
goto done;
|
||||
|
||||
profile = ctx->profile;
|
||||
*out_profile = profile = ctx->profile;
|
||||
*out_rate = ctx->sample_rate;
|
||||
|
||||
done:
|
||||
av_frame_free(&frame);
|
||||
|
@ -133,8 +155,6 @@ done:
|
|||
|
||||
if (profile == FF_PROFILE_UNKNOWN)
|
||||
MP_WARN(da, "Failed to parse codec profile.\n");
|
||||
|
||||
return profile;
|
||||
}
|
||||
|
||||
static int init_filter(struct dec_audio *da, AVPacket *pkt)
|
||||
|
@ -142,8 +162,9 @@ static int init_filter(struct dec_audio *da, AVPacket *pkt)
|
|||
struct spdifContext *spdif_ctx = da->priv;
|
||||
|
||||
int profile = FF_PROFILE_UNKNOWN;
|
||||
if (spdif_ctx->codec_id == AV_CODEC_ID_DTS)
|
||||
profile = determine_codec_profile(da, pkt);
|
||||
int c_rate = 0;
|
||||
determine_codec_params(da, pkt, &profile, &c_rate);
|
||||
MP_VERBOSE(da, "In: profile=%d samplerate=%d\n", profile, c_rate);
|
||||
|
||||
AVFormatContext *lavf_ctx = avformat_alloc_context();
|
||||
if (!lavf_ctx)
|
||||
|
@ -189,7 +210,7 @@ static int init_filter(struct dec_audio *da, AVPacket *pkt)
|
|||
break;
|
||||
case AV_CODEC_ID_AC3:
|
||||
sample_format = AF_FORMAT_S_AC3;
|
||||
samplerate = 48000;
|
||||
samplerate = c_rate > 0 ? c_rate : 48000;
|
||||
num_channels = 2;
|
||||
break;
|
||||
case AV_CODEC_ID_DTS: {
|
||||
|
|
Loading…
Reference in New Issue