在使用Qt调用FFMPEG库时,swr_convert函数报错:异常被触发在线程0中停止如何解决
如图


在使用Qt调用FFMPEG库时,swr_convert函数报错:异常被触发在线程0中停止如何解决
如图


上午好☀️☀️☀️️
本答案参考通义千问
在使用 Qt 调用 FFMPEG 库(如 swr_convert 函数)时,如果出现“异常被触发在线程0中停止”的错误,通常意味着程序在执行过程中遇到了未处理的异常或错误,导致线程崩溃。
AVFrame 或 SwrContext。SwrContext 没有通过 swr_alloc_set_opts 正确初始化。SwrContext,却仍然调用 swr_convert。swr_convert 参数是否正确确保你传递给 swr_convert 的参数是合法的:
int swr_convert(
SwrContext *s,
uint8_t *out_samples[],
int out_count,
const uint8_t *in_samples[],
int in_count
);
重点:必须确保
s不为 NULL,且out_samples和in_samples是有效的缓冲区。
SwrContext 已正确初始化使用 swr_alloc_set_opts 创建并初始化 SwrContext:
SwrContext *swr_ctx = swr_alloc_set_opts(
nullptr,
output_channel_layout,
output_sample_format,
output_sample_rate,
input_channel_layout,
input_sample_format,
input_sample_rate,
0,
nullptr
);
if (!swr_ctx) {
qWarning() << "Failed to allocate SwrContext";
return;
}
if (swr_init(swr_ctx) < 0) {
qWarning() << "Failed to initialize SwrContext";
swr_free(&swr_ctx);
return;
}
重点: 必须调用
swr_init()初始化上下文。
确保输入和输出格式匹配,比如:
AV_SAMPLE_FMT_FLTP vs AV_SAMPLE_FMT_S16AV_CH_LAYOUT_STEREO vs AV_CH_LAYOUT_MONO44100 vs 48000如果你在 主线程(线程0) 中直接调用 swr_convert,可能会导致 UI 停止响应甚至崩溃。
建议:将耗时操作放到子线程中运行。
示例代码(使用 Qt 线程):
class AudioWorker : public QObject {
Q_OBJECT
public:
void processAudio() {
// 在这里调用 swr_convert
int ret = swr_convert(swr_ctx, out_buffer, out_channels, in_buffer, in_channels);
if (ret < 0) {
qWarning() << "swr_convert failed";
}
}
};
// 在主窗口中启动线程
QThread* thread = new QThread(this);
AudioWorker* worker = new AudioWorker();
worker->moveToThread(thread);
connect(thread, &QThread::started, worker, &AudioWorker::processAudio);
thread->start();
在不再需要 SwrContext 时,务必释放它:
swr_free(&swr_ctx);
注意: 如果
swr_convert被调用前已经释放了swr_ctx,就会导致崩溃。
#include <QDebug>
extern "C" {
#include <libavutil/opt.h>
#include <libswresample/swresample.h>
}
void convertAudio() {
SwrContext *swr_ctx = swr_alloc_set_opts(
nullptr,
AV_CH_LAYOUT_STEREO,
AV_SAMPLE_FMT_FLTP,
44100,
AV_CH_LAYOUT_MONO,
AV_SAMPLE_FMT_S16,
48000,
0,
nullptr
);
if (!swr_ctx) {
qDebug() << "Failed to allocate SwrContext";
return;
}
if (swr_init(swr_ctx) < 0) {
qDebug() << "Failed to initialize SwrContext";
swr_free(&swr_ctx);
return;
}
// 假设我们有一个输入音频帧
AVFrame *in_frame = av_frame_alloc();
in_frame->sample_rate = 48000;
in_frame->channel_layout = AV_CH_LAYOUT_MONO;
in_frame->format = AV_SAMPLE_FMT_S16;
// 分配输出缓冲区
int out_channels = 2;
int out_samples = 1024;
uint8_t *out_buffer[2];
for (int i = 0; i < out_channels; ++i) {
out_buffer[i] = (uint8_t *)malloc(out_samples * sizeof(float));
}
// 执行转换
int ret = swr_convert(swr_ctx, out_buffer, out_samples, (const uint8_t **)in_frame->data, in_frame->nb_samples);
if (ret < 0) {
qDebug() << "swr_convert failed";
}
// 释放资源
for (int i = 0; i < out_channels; ++i) {
free(out_buffer[i]);
}
swr_free(&swr_ctx);
av_frame_free(&in_frame);
}
| 问题 | 解决方案 |
|------|----------|
| swr_convert 报错 | 检查 SwrContext 是否初始化正确 |
| 线程0崩溃 | 避免在主线程中执行耗时操作,使用子线程 |
| 内存越界 | 确保 out_buffer 和 in_buffer 有效 |
| 格式不匹配 | 确认输入输出格式一致 |
如你有具体的错误信息或代码片段,可以提供更多细节,我可以进一步帮助你定位问题。