avcodec_decode_video2在帧分辨率更改后无法解码

时间:2016-10-06 13:46:17

标签: android multithreading video ffmpeg decoding

我通过JNI在Android项目中使用ffmpeg来解码实时H264视频流。在Java方面,我只将字节数组发送到本机模块。本机代码正在运行循环并检查数据缓冲区以寻找要解码的新数据。每个数据块都使用以下方式处理:

int bytesLeft = data->GetSize();
int paserLength = 0;
int decodeDataLength = 0;
int gotPicture = 0;
const uint8_t* buffer = data->GetData();
while (bytesLeft > 0) {
    AVPacket packet;
    av_init_packet(&packet);
    paserLength = av_parser_parse2(_codecPaser, _codecCtx, &packet.data, &packet.size, buffer, bytesLeft, AV_NOPTS_VALUE, AV_NOPTS_VALUE, AV_NOPTS_VALUE);
    bytesLeft -= paserLength;
    buffer += paserLength;

    if (packet.size > 0) {
        decodeDataLength = avcodec_decode_video2(_codecCtx, _frame, &gotPicture, &packet);
    }
    else {
        break;
    }
    av_free_packet(&packet);
}

if (gotPicture) {
// pass the frame to rendering
}

系统运行良好,直到传入视频的分辨率发生变化。我需要处理4:3和16:9宽高比之间的转换。将AVCodecContext配置如下:

_codecCtx->flags2|=CODEC_FLAG2_FAST;
_codecCtx->thread_count = 2;
_codecCtx->thread_type = FF_THREAD_FRAME;

if(_codec->capabilities&CODEC_FLAG_LOW_DELAY){
    _codecCtx->flags|=CODEC_FLAG_LOW_DELAY;
}

在视频分辨率变化后,我无法继续解码新帧。在整个框架可用时got_picture_ptr启用的avcodec_decode_video2标志在此之后永远不会成立 This票让我想知道问题是否与多线程无关。我注意到的唯一有用的事情是,当我将thread_type更改为FF_THREAD_SLICE时,解决方案在解决方案更改后并不总是被阻止,大约一半的尝试都是成功的。切换到单线程处理是不可能的,我需要更多的计算能力。为一个线程设置上下文并不能解决问题,并使解码器无法跟上处理传入数据的步骤 应用程序重启后一切正常。

我只能想到一个工作量(它并没有真正解决问题):在流分辨率改变后卸载并加载整个库(例如here中提到的)。我不认为它很好,它会适当地引入其他错误并花费大量时间(从用户的角度来看)。

是否可以解决此问题?

编辑:
我已经转储了传递给解码管道的流数据。在捕获流时,我已经几次更改了分辨率。使用ffplay播放它表明,当分辨率改变并且应用程序中的预览冻结时,ffplay设法继续,但预览是一个小故障一秒左右。您可以看到完整的ffplay日志here。在这种情况下,当我第二次将分辨率更改为960x720时,视频预览停止了。 (Reinit context to 960x720, pix_fmt: yuv420p在日志中。)

0 个答案:

没有答案