From patchwork Sat Oct 26 11:05:27 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andrey Semashev X-Patchwork-Id: 15972 Return-Path: X-Original-To: patchwork@ffaux-bg.ffmpeg.org Delivered-To: patchwork@ffaux-bg.ffmpeg.org Received: from ffbox0-bg.mplayerhq.hu (ffbox0-bg.ffmpeg.org [79.124.17.100]) by ffaux.localdomain (Postfix) with ESMTP id A5E8944AA78 for ; Sat, 26 Oct 2019 14:11:56 +0300 (EEST) Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id 83DF768ADCC; Sat, 26 Oct 2019 14:11:56 +0300 (EEST) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from mail-lj1-f181.google.com (mail-lj1-f181.google.com [209.85.208.181]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id 5D2CF68AB79 for ; Sat, 26 Oct 2019 14:11:50 +0300 (EEST) Received: by mail-lj1-f181.google.com with SMTP id w8so1546716lji.13 for ; Sat, 26 Oct 2019 04:11:50 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:mime-version :content-transfer-encoding; bh=hfQizuawXYNVnS+15UI/5ChXfreEHGGqtZQARQPrXfk=; b=gxZwCCdQtd35Mstve7lPlWeRkSn4PIzo7xRco+muiiaL7IiERtjQ9pX8EcW1KoWjJ/ kHjkO/eBicxVFzsfZNN5C1VUNHHHMPKaZVfh4CCu+n9wxDdqG2BrdVCHlTb9gkGsXfRy /MjJvHGsThTZ9z9sMaz4SkzbcxpU/kx9mCYzkJOkm6TQQBiFLpC+RZ+sn6mXZbFa73Gw xdWofusqLuVl3kweBFKimObhIu1+whbgmK6OHfYcrkMBi1vuOdXLQ9jsf57nim7+nZKx hkvirblYE0u5cWREnBVxI6k4lcA7VZE8G/lAsMUbMyxwcyppCkXsib6RIA9JWk2kw91h o3gw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:mime-version :content-transfer-encoding; bh=hfQizuawXYNVnS+15UI/5ChXfreEHGGqtZQARQPrXfk=; b=XCeNFWXU8Btxui8FfIsRa1JEyjB5+Qhm9qVu1svCKKJbf4qGUcwlmbtxzzB0bhxnKi Os8ZC42AG3oHmMDpjbcJqLoW8SB0KL+IOGZJJ+0QfYB80Gvf/HQmuzx7tMy/kovcBqLv PQyKHErFdWmc5AsfAUjAWUWWTy9MXu4y5vmdXS/Hn+WK3xpje16eLKrY+hHrTZZ525l5 ZENQBFgLOIIMQKq8K4zSY0K/xkGfv/WmiP5Nd/KUiEl9qc6ecJ1Xurulmtn/mLhD050h t7qhQRS6wBLDSDS/Ksbke3FCb1RK1PJWeicbWaZfSGiA6ysqxRDEcAMgXLZpD1T9H2VD +1fQ== X-Gm-Message-State: APjAAAWpox18sboF8tOBaR957yoliJojLZTePDr6X9aYGrHyWfqJeZiv LZXUKeXhXjbZgULGUK0J7hTShreO X-Google-Smtp-Source: APXvYqyS8H8SHtxh5Vnc+cbPEARAup++gEt90GkZcz7fzNfua9CBXY1+FIvt4HwwgYhKdT/LkZUHdA== X-Received: by 2002:a2e:998a:: with SMTP id w10mr5632774lji.152.1572087934669; Sat, 26 Oct 2019 04:05:34 -0700 (PDT) Received: from localhost.localdomain (broadband-37-110-154-226.ip.moscow.rt.ru. [37.110.154.226]) by smtp.gmail.com with ESMTPSA id b67sm5290244ljf.5.2019.10.26.04.05.32 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 26 Oct 2019 04:05:33 -0700 (PDT) From: Andrey Semashev To: ffmpeg-devel@ffmpeg.org Date: Sat, 26 Oct 2019 14:05:27 +0300 Message-Id: <20191026110527.29893-1-andrey.semashev@gmail.com> X-Mailer: git-send-email 2.20.1 MIME-Version: 1.0 Subject: [FFmpeg-devel] [PATCH] libavcodec/h261dec: Fix keyframe markup and frame skipping. X-BeenThere: ffmpeg-devel@ffmpeg.org X-Mailman-Version: 2.1.20 Precedence: list List-Id: FFmpeg development discussions and patches List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Reply-To: FFmpeg development discussions and patches Cc: Andrey Semashev Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" The decoder never marks pictures as I-frames, which results in no keyframe indication and incorrect frame skipping, in cases when keyframes should be decoded. This commit works around this decoder limitation and marks I-frames and keyframes based on "freeze picture release" bit in h261 picture header. This reflects h261enc behavior. --- libavcodec/h261.h | 1 + libavcodec/h261dec.c | 27 ++++++++++++++++++--------- 2 files changed, 19 insertions(+), 9 deletions(-) diff --git a/libavcodec/h261.h b/libavcodec/h261.h index 399a404b2b..6662d38d6d 100644 --- a/libavcodec/h261.h +++ b/libavcodec/h261.h @@ -37,6 +37,7 @@ typedef struct H261Context { MpegEncContext s; + int freeze_picture_release; // 1 if freeze picture release bit is set in the picture header int current_mba; int mba_diff; int mtype; diff --git a/libavcodec/h261dec.c b/libavcodec/h261dec.c index 14a874c45d..3b1711a21d 100644 --- a/libavcodec/h261dec.c +++ b/libavcodec/h261dec.c @@ -502,9 +502,9 @@ static int h261_decode_picture_header(H261Context *h) s->avctx->framerate = (AVRational) { 30000, 1001 }; /* PTYPE starts here */ - skip_bits1(&s->gb); /* split screen off */ - skip_bits1(&s->gb); /* camera off */ - skip_bits1(&s->gb); /* freeze picture release off */ + skip_bits1(&s->gb); /* split screen indicator */ + skip_bits1(&s->gb); /* document camera indicator */ + h->freeze_picture_release = get_bits1(&s->gb); /* freeze picture release */ format = get_bits1(&s->gb); @@ -532,7 +532,8 @@ static int h261_decode_picture_header(H261Context *h) /* H.261 has no I-frames, but if we pass AV_PICTURE_TYPE_I for the first * frame, the codec crashes if it does not contain all I-blocks - * (e.g. when a packet is lost). */ + * (e.g. when a packet is lost). We will fix the picture type in the + * output frame based on h->freeze_picture_release later. */ s->pict_type = AV_PICTURE_TYPE_P; h->gob_number = 0; @@ -590,6 +591,7 @@ static int h261_decode_frame(AVCodecContext *avctx, void *data, H261Context *h = avctx->priv_data; MpegEncContext *s = &h->s; int ret; + enum AVPictureType pict_type; AVFrame *pict = data; ff_dlog(avctx, "*****frame %d size=%d\n", avctx->frame_number, buf_size); @@ -630,15 +632,17 @@ retry: goto retry; } - // for skipping the frame - s->current_picture.f->pict_type = s->pict_type; - s->current_picture.f->key_frame = s->pict_type == AV_PICTURE_TYPE_I; + // for skipping the frame and keyframe markup + pict_type = h->freeze_picture_release ? AV_PICTURE_TYPE_I : s->pict_type; - if ((avctx->skip_frame >= AVDISCARD_NONREF && s->pict_type == AV_PICTURE_TYPE_B) || - (avctx->skip_frame >= AVDISCARD_NONKEY && s->pict_type != AV_PICTURE_TYPE_I) || + if ((avctx->skip_frame >= AVDISCARD_NONREF && pict_type == AV_PICTURE_TYPE_B) || + (avctx->skip_frame >= AVDISCARD_NONKEY && pict_type != AV_PICTURE_TYPE_I) || avctx->skip_frame >= AVDISCARD_ALL) return get_consumed_bytes(s, buf_size); + s->current_picture.f->pict_type = s->pict_type; + s->current_picture.f->key_frame = s->pict_type == AV_PICTURE_TYPE_I; + if (ff_mpv_frame_start(s, avctx) < 0) return -1; @@ -660,6 +664,11 @@ retry: if ((ret = av_frame_ref(pict, s->current_picture_ptr->f)) < 0) return ret; + + // fix picture type and correctly mark keyframes + pict->pict_type = pict_type; + pict->key_frame = pict_type == AV_PICTURE_TYPE_I; + ff_print_debug_info(s, s->current_picture_ptr, pict); *got_frame = 1;