rk3568 ffmpeg 6.1.1 解码出错问题
“Buffer full writing %d bytes to decoder”
“Failed to write data to decoder (code = -11)”,
ffmpeg 编译设置:
./configure --enable-cross-compile --target-os=linux --arch=arm64 \
--cross-prefix=aarch64-buildroot-linux-gnu- \
--cc=aarch64-buildroot-linux-gnu-gcc \
--cxx=aarch64-buildroot-linux-gnu-g++ \
--prefix=/ffmpeg_rk_build \
--sysroot=/RK356X_LINUX_SDK_RELEASE_V1.3.0_20220620/buildroot/output/rockchip_rk3568/host/aarch64-buildroot-linux-gnu/sysroot \
--pkg-config=/RK356X_LINUX_SDK_RELEASE_V1.3.0_20220620/buildroot/output/rockchip_rk3568/host/bin/pkg-config \
--disable-asm --enable-parsers --disable-decoders --enable-decoder=h264 --enable-decoder=aac --disable-debug --enable-ffmpeg --enable-static --disable-stripping --disable-doc \
--enable-decoder=h264_rkmpp --enable-decoder=hevc_rkmpp --enable-version3 --enable-libdrm --enable-rkmpp --enable-gpl
rk3568 解码与取解码数据之间没有什么大的关系,送解码数据出错,并不代表没有解码数据可取,解除两者的逻辑关系既可,在 libavcodec/rkmppdec.c 中,改如下:
static int rkmmp_prepare_frame(AVCodecContext *avctx)
{
RKMPPDecodeContext *rk_context = avctx->priv_data;
RKMPPDecoder *decoder = (RKMPPDecoder *)rk_context->decoder_ref->data;
int ret = MPP_NOK;
AVPacket pkt = {0};
RK_S32 usedslots, freeslots;
if (!decoder->eos_reached) {
// we get the available slots in decoder
ret = decoder->mpi->control(decoder->ctx, MPP_DEC_GET_STREAM_COUNT, &usedslots);
if (ret != MPP_OK) {
av_log(avctx, AV_LOG_ERROR, "Failed to get decoder used slots (code = %d).\n", ret);
return ret;
}
freeslots = INPUT_MAX_PACKETS - usedslots;
if (freeslots > 0) {
ret = ff_decode_get_packet(avctx, &pkt);
if (ret < 0 && ret != AVERROR_EOF) {
return ret;
}
ret = rkmpp_send_packet(avctx, &pkt);
av_packet_unref(&pkt);
if (ret < 0) {
av_log(avctx, AV_LOG_ERROR, "Failed to send packet to decoder (code = %d)\n", ret);
return ret;
}
}
// make sure we keep decoder full
if (freeslots > 1){
return AVERROR(EAGAIN);
}
}
return ret;
}
static int rkmpp_receive_frame(AVCodecContext *avctx, AVFrame *frame)
{
rkmmp_prepare_frame(avctx);
return rkmpp_retrieve_frame(avctx, frame);
}