diff --git a/libavcodec/rkmppdec.c b/libavcodec/rkmppdec.c index bc918f58b3..8a974ab26d 100644 --- a/libavcodec/rkmppdec.c +++ b/libavcodec/rkmppdec.c @@ -115,6 +115,7 @@ static av_cold int rkmpp_decode_close(AVCodecContext *avctx) r->draining = 0; r->info_change = 0; r->errinfo_cnt = 0; + r->got_frame = 0; if (r->mapi) { r->mapi->reset(r->mctx); @@ -212,6 +213,9 @@ static av_cold int rkmpp_decode_init(AVCodecContext *avctx) goto fail; } + if (avctx->skip_frame == AVDISCARD_NONKEY) + r->deint = 0; + if ((ret = r->mapi->control(r->mctx, MPP_DEC_SET_ENABLE_DEINTERLACE, &r->deint)) != MPP_OK) { av_log(avctx, AV_LOG_ERROR, "Failed to set enable deinterlace: %d\n", ret); ret = AVERROR_EXTERNAL; @@ -749,6 +753,7 @@ static int rkmpp_get_frame(AVCodecContext *avctx, AVFrame *frame, int timeout) } else { av_log(avctx, AV_LOG_DEBUG, "Received a frame\n"); r->errinfo_cnt = 0; + r->got_frame = 1; switch (avctx->pix_fmt) { case AV_PIX_FMT_DRM_PRIME: @@ -838,6 +843,15 @@ static int rkmpp_send_packet(AVCodecContext *avctx, AVPacket *pkt) if (r->draining) return AVERROR(EOF); + /* do not skip non-key pkt until got any frame */ + if (r->got_frame && + avctx->skip_frame == AVDISCARD_NONKEY && + !(pkt->flags & AV_PKT_FLAG_KEY)) { + av_log(avctx, AV_LOG_TRACE, "Skip packet without key flag " + "at pts %"PRId64"\n", pkt->pts); + return 0; + } + if ((ret = mpp_packet_init(&mpp_pkt, pkt->data, pkt->size)) != MPP_OK) { av_log(avctx, AV_LOG_ERROR, "Failed to init packet: %d\n", ret); return AVERROR_EXTERNAL; @@ -928,6 +942,7 @@ static void rkmpp_decode_flush(AVCodecContext *avctx) r->draining = 0; r->info_change = 0; r->errinfo_cnt = 0; + r->got_frame = 0; av_packet_unref(&r->last_pkt); } else diff --git a/libavcodec/rkmppdec.h b/libavcodec/rkmppdec.h index 0eba15000e..b5d94b2d88 100644 --- a/libavcodec/rkmppdec.h +++ b/libavcodec/rkmppdec.h @@ -57,6 +57,7 @@ typedef struct RKMPPDecContext { int draining; int info_change; int errinfo_cnt; + int got_frame; int deint; int afbc;