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);
}