0

I need to enable FFmpeg in my video playback application. However, the FFmpeg application cannot listen to the correct audio stream data. Here is the part of the code that is not working correctly:

if (avformat_open_input(&m_data->formatContext, Filename.c_str(), nullptr, nullptr) != 0)
 {
 std::cout << "Motion: Failed to open file: '" << Filename << "'" << std::endl;
 return false;
 }
 if (avformat_find_stream_info(m_data->formatContext, nullptr) < 0)
 {
 std::cout << "Motion: Failed to find stream information" << std::endl;
 return false;
 }
 for (unsigned int i = 0; i < m_data->formatContext->nb_streams; i++)
 {
 // Получаем параметры кодека для текущего потока
 AVCodecParameters *codecParams = m_data->formatContext->streams[i]->codecpar;
 switch (codecParams->codec_type)
 {
 case AVMEDIA_TYPE_AUDIO:
 if (m_data->audioStreamID == -1 && EnableAudio)
 m_data->audioStreamID = i;
 break;
 default:
 break;
 }
 }
 if (HasAudio())
 {
 const AVCodec* codec = avcodec_find_decoder(m_data->formatContext->streams[m_data->audioStreamID]->codecpar->codec_id);
 std::cout << m_data->formatContext->streams[m_data->audioStreamID]->codecpar->codec_id<< std::endl;
 m_data->audioContext = avcodec_alloc_context3(codec);
 if (!m_data->audioContext)
 {
 std::cout << "Motion: Failed to get audio codec context" << std::endl;
 m_data->audioStreamID = -1;
 }
 else
 {
 m_data->audioCodec = codec;
 if (!m_data->audioCodec)
 {
 std::cout << "Motion: Failed to find audio codec" << std::endl;
 m_data->audioStreamID = -1;
 }
 else
 {
 if (avcodec_open2(m_data->audioContext, m_data->audioCodec, nullptr) != 0)
 {
 std::cout << "Motion: Failed to load audio codec" << std::endl;
 m_data->audioStreamID = -1;
 }
 else
 {
 m_data->audioRawBuffer = av_frame_alloc();
 if (!m_data->audioRawBuffer)
 {
 std::cout << "Motion: Failed to allocate audio buffer" << std::endl;
 m_data->audioStreamID = -1;
 }
 else
 {
 int buffer_size = av_samples_get_buffer_size(nullptr, m_data->audioContext->channels, MAX_AUDIO_SAMPLES, AV_SAMPLE_FMT_S16, 0);
 if (buffer_size < 0) {
 char err_buf[AV_ERROR_MAX_STRING_SIZE];
 av_strerror(buffer_size, err_buf, sizeof(err_buf));
 std::cerr << "Motion: Failed to calculating buffer size: " << err_buf << std::endl;
 m_data->audioStreamID = -1;
 }
 else if (av_samples_alloc(&m_data->audioPCMBuffer, nullptr, m_data->audioContext->channels, av_samples_get_buffer_size(nullptr, m_data->audioContext->channels, MAX_AUDIO_SAMPLES, AV_SAMPLE_FMT_S16, 0), AV_SAMPLE_FMT_S16, 0) < 0)
 {
 std::cout << "Motion: Failed to create audio samples buffer" << std::endl;
 m_data->audioStreamID = -1;
 }
 else
 {
 av_frame_unref(m_data->audioRawBuffer);
 uint64_t inchanlayout = m_data->audioContext->channel_layout;
 uint64_t outchanlayout = inchanlayout;
 if (inchanlayout == 0)
 inchanlayout = av_get_default_channel_layout(m_data->audioContext->channels);
 if (outchanlayout != AV_CH_LAYOUT_MONO)
 outchanlayout = AV_CH_LAYOUT_STEREO;
 m_data->audioSWContext = swr_alloc();
 std::cout << m_data->audioContext->sample_rate << std::endl;
 std::cout << m_data->audioContext->sample_fmt << std::endl;
 av_opt_set_int(m_data->audioSWContext, "in_channel_layout", inchanlayout, 0);
 av_opt_set_int(m_data->audioSWContext, "out_channel_layout", outchanlayout, 0);
 av_opt_set_int(m_data->audioSWContext, "in_sample_rate", m_data->audioContext->sample_rate, 0);
 av_opt_set_int(m_data->audioSWContext, "out_sample_rate", m_data->audioContext->sample_rate, 0);
 av_opt_set_sample_fmt(m_data->audioSWContext, "in_sample_fmt", m_data->audioContext->sample_fmt, 0);
 av_opt_set_sample_fmt(m_data->audioSWContext, "out_sample_fmt", AV_SAMPLE_FMT_S16, 0);
 swr_init(m_data->audioSWContext);
 m_audioChannelCount = av_get_channel_layout_nb_channels(outchanlayout);
 }
 }
 }
 }
 }
 }

The console displays the error "Motion: Failed to calculating buffer size: Invalid argument". This error occurs because avcodec_alloc_context 3(codec)->channels == 0, but this should not be the case.The video file must have a second audio channel enter image description here

DailyLearner
2,3902 gold badges22 silver badges32 bronze badges
asked Feb 11, 2024 at 17:13

1 Answer 1

1

Take a look at the description of the function avcodec_alloc_context3. This function just allocates context and sets its fields to default values. After allocating and before avcodec_open2 you need to copy stream codec parameters using avcodec_parameters_to_context function, or set parameters manually.

answered Feb 12, 2024 at 16:11
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.