跳转至内容
  • 0 赞同
    11 帖子
    120 浏览
    Cat-GuijunC

    hi,友友有解决这个情况吗,我也是当speed不为一时就报错了,我完全不知道如何查找崩溃,找了一天了,下面是我的代码:
    void AudioDecodeThread::run()
    {
    // 加入sonic
    // 初始化部分:先创建一个流
    sonicStream stream = sonicCreateStream(m_videoPlayControl->m_audioCodecCtx->sample_rate, 2);
    if (!stream)
    {
    m_videoPlayControl->m_eventHandler->onVideoPlayerError(0, "sonicCreateStream error!");
    }

    if (!initSwrCtx()) { m_videoPlayControl->m_eventHandler->onVideoPlayerError(0, "initSwrCtx error"); return; } while (true) { if (m_videoPlayControl->m_currentState == State::STOP) { break; } else if (m_videoPlayControl->m_currentState == State::PAUSE) { std::this_thread::sleep_for(std::chrono::milliseconds(10)); continue; } AVPacket *pkt = m_videoPlayControl->m_audioPacketQueue.pop(); if (pkt == nullptr) { if (m_videoPlayControl->m_isReadFinished) { break; } continue; } if (memcmp(pkt->data, FLUSHDATA, strlen(FLUSHDATA)) == 0) { avcodec_flush_buffers(m_videoPlayControl->m_audioCodecCtx); av_packet_free(&pkt); continue; } int ret = avcodec_send_packet(m_videoPlayControl->m_audioCodecCtx, pkt); if (ret < 0) { char errbuf[1024] = { 0 }; av_strerror(ret, errbuf, sizeof(errbuf)); fprintf(stderr, "avcodec_send_packet: %s (error pts: %d)\n", errbuf, pkt->pts); av_packet_free(&pkt); continue; } AVFrame *frame = av_frame_alloc(); while (avcodec_receive_frame(m_videoPlayControl->m_audioCodecCtx, frame) == 0) { // 读取frame, swr转换, 放到frameQueue里面去 int inSamples = frame->nb_samples; // int outSamples = av_rescale_rnd(inSamples, 1, 1, AV_ROUND_UP); // 废除手动分配的 audioBuffer,改用 resampleFrame 内部缓冲区 AVFrame *resampleFrame = av_frame_alloc(); resampleFrame->format = AV_SAMPLE_FMT_S16; av_channel_layout_default(&resampleFrame->ch_layout, 2); // 双声道 resampleFrame->sample_rate = frame->sample_rate; // 正确设置采样率 resampleFrame->nb_samples = inSamples; // 让 FFmpeg 自动分配缓冲区(确保地址和大小正确) if (av_frame_get_buffer(resampleFrame, 0) < 0) { av_frame_free(&resampleFrame); continue; } int len = swr_convert(m_swrCtx, resampleFrame->data, resampleFrame->nb_samples, (const uint8_t **)frame->data, inSamples); // 加入sonic sonicSetSpeed(stream, m_videoPlayControl->m_speed); // 4. 写入音频数据到Sonic ,这里的bug short *valid_audio_data = (short *)resampleFrame->data[0]; int total_samples = len; // 单声道总样本数 std::cout << len << std::endl; ret = sonicWriteShortToStream(stream, valid_audio_data, total_samples); if (ret == 0) { m_videoPlayControl->m_eventHandler->onVideoPlayerError(0, "sonicWriteShortToStream error"); continue; } int availableSamples = sonicSamplesAvailable(stream); // if (availableSamples <= 0) { continue; } // 根据实际需要的样本数分配缓冲区 short *output_pcm = new short[availableSamples * 2]; int samples = sonicReadShortFromStream(stream, output_pcm, availableSamples); if (samples <= 0) { delete[] output_pcm; av_frame_free(&resampleFrame); continue; } std::cout << inSamples << "---" << len << "---" << availableSamples << "---" << samples << std::endl; PCMFrame *pcm = new PCMFrame(); pcm->setBuffer((uint8_t *)output_pcm, samples * 4); pcm->setPts(frame->pts); pcm->setSampleRate(frame->sample_rate); m_videoPlayControl->m_audioFrameQueue.push(pcm); delete[] output_pcm; av_frame_free(&resampleFrame); } av_frame_free(&frame); av_packet_free(&pkt); } sonicDestroyStream(stream); }