Commit d8b06521 authored by Justin Ruggles's avatar Justin Ruggles

avconv: check for an incompatible changing channel layout

The decoder can change the layout and channel count during decoding,
but currently we only validate that the two are compatible when opening
the codec. This checks for incompatibilities after each decoded frame.
parent 6208313a
...@@ -1191,6 +1191,58 @@ static int check_recording_time(OutputStream *ost) ...@@ -1191,6 +1191,58 @@ static int check_recording_time(OutputStream *ost)
return 1; return 1;
} }
static void get_default_channel_layouts(OutputStream *ost, InputStream *ist)
{
char layout_name[256];
AVCodecContext *enc = ost->st->codec;
AVCodecContext *dec = ist->st->codec;
if (dec->channel_layout &&
av_get_channel_layout_nb_channels(dec->channel_layout) != dec->channels) {
av_get_channel_layout_string(layout_name, sizeof(layout_name),
dec->channels, dec->channel_layout);
av_log(NULL, AV_LOG_ERROR, "New channel layout (%s) is invalid\n",
layout_name);
dec->channel_layout = 0;
}
if (!dec->channel_layout) {
if (enc->channel_layout && dec->channels == enc->channels) {
dec->channel_layout = enc->channel_layout;
} else {
dec->channel_layout = av_get_default_channel_layout(dec->channels);
if (!dec->channel_layout) {
av_log(NULL, AV_LOG_FATAL, "Unable to find default channel "
"layout for Input Stream #%d.%d\n", ist->file_index,
ist->st->index);
exit_program(1);
}
}
av_get_channel_layout_string(layout_name, sizeof(layout_name),
dec->channels, dec->channel_layout);
av_log(NULL, AV_LOG_WARNING, "Guessed Channel Layout for Input Stream "
"#%d.%d : %s\n", ist->file_index, ist->st->index, layout_name);
}
if (!enc->channel_layout) {
if (dec->channels == enc->channels) {
enc->channel_layout = dec->channel_layout;
return;
} else {
enc->channel_layout = av_get_default_channel_layout(enc->channels);
}
if (!enc->channel_layout) {
av_log(NULL, AV_LOG_FATAL, "Unable to find default channel layout "
"for Output Stream #%d.%d\n", ost->file_index,
ost->st->index);
exit_program(1);
}
av_get_channel_layout_string(layout_name, sizeof(layout_name),
enc->channels, enc->channel_layout);
av_log(NULL, AV_LOG_WARNING, "Guessed Channel Layout for Output Stream "
"#%d.%d : %s\n", ost->file_index, ost->st->index, layout_name);
}
}
static void generate_silence(uint8_t* buf, enum AVSampleFormat sample_fmt, size_t size) static void generate_silence(uint8_t* buf, enum AVSampleFormat sample_fmt, size_t size)
{ {
int fill_char = 0x00; int fill_char = 0x00;
...@@ -1301,6 +1353,8 @@ static void do_audio_out(AVFormatContext *s, OutputStream *ost, ...@@ -1301,6 +1353,8 @@ static void do_audio_out(AVFormatContext *s, OutputStream *ost,
uint8_t *buf = decoded_frame->data[0]; uint8_t *buf = decoded_frame->data[0];
int size = decoded_frame->nb_samples * dec->channels * isize; int size = decoded_frame->nb_samples * dec->channels * isize;
get_default_channel_layouts(ost, ist);
if (alloc_audio_output_buf(dec, enc, decoded_frame->nb_samples) < 0) { if (alloc_audio_output_buf(dec, enc, decoded_frame->nb_samples) < 0) {
av_log(NULL, AV_LOG_FATAL, "Error allocating audio buffer\n"); av_log(NULL, AV_LOG_FATAL, "Error allocating audio buffer\n");
exit_program(1); exit_program(1);
...@@ -2430,51 +2484,6 @@ static void print_sdp(void) ...@@ -2430,51 +2484,6 @@ static void print_sdp(void)
av_freep(&avc); av_freep(&avc);
} }
static void get_default_channel_layouts(OutputStream *ost, InputStream *ist)
{
char layout_name[256];
AVCodecContext *enc = ost->st->codec;
AVCodecContext *dec = ist->st->codec;
if (!dec->channel_layout) {
if (enc->channel_layout && dec->channels == enc->channels) {
dec->channel_layout = enc->channel_layout;
} else {
dec->channel_layout = av_get_default_channel_layout(dec->channels);
if (!dec->channel_layout) {
av_log(NULL, AV_LOG_FATAL, "Unable to find default channel "
"layout for Input Stream #%d.%d\n", ist->file_index,
ist->st->index);
exit_program(1);
}
}
av_get_channel_layout_string(layout_name, sizeof(layout_name),
dec->channels, dec->channel_layout);
av_log(NULL, AV_LOG_WARNING, "Guessed Channel Layout for Input Stream "
"#%d.%d : %s\n", ist->file_index, ist->st->index, layout_name);
}
if (!enc->channel_layout) {
if (dec->channels == enc->channels) {
enc->channel_layout = dec->channel_layout;
return;
} else {
enc->channel_layout = av_get_default_channel_layout(enc->channels);
}
if (!enc->channel_layout) {
av_log(NULL, AV_LOG_FATAL, "Unable to find default channel layout "
"for Output Stream #%d.%d\n", ost->file_index,
ost->st->index);
exit_program(1);
}
av_get_channel_layout_string(layout_name, sizeof(layout_name),
enc->channels, enc->channel_layout);
av_log(NULL, AV_LOG_WARNING, "Guessed Channel Layout for Output Stream "
"#%d.%d : %s\n", ost->file_index, ost->st->index, layout_name);
}
}
static int init_input_stream(int ist_index, char *error, int error_len) static int init_input_stream(int ist_index, char *error, int error_len)
{ {
int i; int i;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment