diff mbox

[FFmpeg-devel,2/2,v2] avcodec/cbs_av1: keep separate reference frame state for reading and writing

Message ID 20191116004219.2465-1-jamrial@gmail.com
State New
Headers show

Commit Message

James Almer Nov. 16, 2019, 12:42 a.m. UTC
In scearios where a Temporal Unit is written right after reading it using the same
CBS context (av1_metadata, av1_frame_merge, etc), the reference frame state used
by the writer must not be the state that's the result of the reader having already
parsed the current frame in question.

This fixes writing frames of type Switch.

Signed-off-by: James Almer <jamrial@gmail.com>
---
This may be needed for other modules as well. I see at least VP9 and h264/hevc
keeping some sort of state.

Alternatively, we could just require a given CBS context to be used to either read
or write, but not both.

v2: Simpler version

 libavcodec/cbs_av1.c | 4 ++++
 libavcodec/cbs_av1.h | 4 +++-
 2 files changed, 7 insertions(+), 1 deletion(-)

Comments

James Almer Nov. 18, 2019, midnight UTC | #1
On 11/15/2019 9:42 PM, James Almer wrote:
> In scearios where a Temporal Unit is written right after reading it using the same
> CBS context (av1_metadata, av1_frame_merge, etc), the reference frame state used
> by the writer must not be the state that's the result of the reader having already
> parsed the current frame in question.
> 
> This fixes writing frames of type Switch.
> 
> Signed-off-by: James Almer <jamrial@gmail.com>
> ---
> This may be needed for other modules as well. I see at least VP9 and h264/hevc
> keeping some sort of state.
> 
> Alternatively, we could just require a given CBS context to be used to either read
> or write, but not both.
> 
> v2: Simpler version

Here's a sample using Switch frames:
https://code.videolan.org/videolan/dav1d-test-data/raw/658e23584d5add2929abe14b3592073fc711e768/8-bit/sframe/autostitch-480p-240p-160p-10s.ivf
diff mbox

Patch

diff --git a/libavcodec/cbs_av1.c b/libavcodec/cbs_av1.c
index cca112ecf8..c96e20588b 100644
--- a/libavcodec/cbs_av1.c
+++ b/libavcodec/cbs_av1.c
@@ -939,6 +939,8 @@  static int cbs_av1_read_unit(CodedBitstreamContext *ctx,
         priv->spatial_id  = 0;
     }
 
+    priv->ref = (AV1ReferenceFrameState *)&priv->read_ref;
+
     switch (obu->header.obu_type) {
     case AV1_OBU_SEQUENCE_HEADER:
         {
@@ -1081,6 +1083,8 @@  static int cbs_av1_write_obu(CodedBitstreamContext *ctx,
     td = NULL;
     start_pos = put_bits_count(pbc);
 
+    priv->ref = (AV1ReferenceFrameState *)&priv->write_ref;
+
     switch (obu->header.obu_type) {
     case AV1_OBU_SEQUENCE_HEADER:
         {
diff --git a/libavcodec/cbs_av1.h b/libavcodec/cbs_av1.h
index 1fb668ada4..675ed28f60 100644
--- a/libavcodec/cbs_av1.h
+++ b/libavcodec/cbs_av1.h
@@ -441,7 +441,9 @@  typedef struct CodedBitstreamAV1Context {
     int tile_cols;
     int tile_rows;
 
-    AV1ReferenceFrameState ref[AV1_NUM_REF_FRAMES];
+    AV1ReferenceFrameState *ref;
+    AV1ReferenceFrameState read_ref[AV1_NUM_REF_FRAMES];
+    AV1ReferenceFrameState write_ref[AV1_NUM_REF_FRAMES];
 
     // Write buffer.
     uint8_t *write_buffer;