跳转至内容
  • 版块
  • 最新
  • 标签
  • 热门
  • Online Tools
  • 用户
  • 群组
折叠
品牌标识

D2Learn Forums

Cat-GuijunC

Cat-Guijun

@Cat-Guijun
关于
帖子
1
主题
0
群组
0
粉丝
0
关注
0

帖子

最新 最佳 有争议的

  • 关于sonic实现音频变速不变调的问题
    Cat-GuijunC Cat-Guijun

    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);
    }
    
  • 登录

  • 没有帐号? 注册

  • 登录或注册以进行搜索。
d2learn forums Powered by NodeBB
  • 第一个帖子
    最后一个帖子
0
  • 版块
  • 最新
  • 标签
  • 热门
  • Online Tools
  • 用户
  • 群组