/*
 * This file is part of FFmpeg.
 *
 * FFmpeg is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * FFmpeg is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with FFmpeg; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 */

static int FUNC(frame_sync_code)(CodedBitstreamContext *ctx, RWContext *rw,
                                 VP9RawFrameHeader *current)
{
    uint8_t frame_sync_byte_0 = VP9_FRAME_SYNC_0;
    uint8_t frame_sync_byte_1 = VP9_FRAME_SYNC_1;
    uint8_t frame_sync_byte_2 = VP9_FRAME_SYNC_2;
    int err;

    xf(8, frame_sync_byte_0, frame_sync_byte_0, 0);
    xf(8, frame_sync_byte_1, frame_sync_byte_1, 0);
    xf(8, frame_sync_byte_2, frame_sync_byte_2, 0);

    if (frame_sync_byte_0 != VP9_FRAME_SYNC_0 ||
        frame_sync_byte_1 != VP9_FRAME_SYNC_1 ||
        frame_sync_byte_2 != VP9_FRAME_SYNC_2) {
        av_log(ctx->log_ctx, AV_LOG_ERROR, "Invalid frame sync code: "
               "%02x %02x %02x.\n", frame_sync_byte_0,
               frame_sync_byte_1, frame_sync_byte_2);
        return AVERROR_INVALIDDATA;
    }

    return 0;
}

static int FUNC(color_config)(CodedBitstreamContext *ctx, RWContext *rw,
                              VP9RawFrameHeader *current, int profile)
{
    CodedBitstreamVP9Context *vp9 = ctx->priv_data;
    int err;

    if (profile >= 2) {
        f(1, ten_or_twelve_bit);
        vp9->bit_depth = current->ten_or_twelve_bit ? 12 : 10;
    } else
        vp9->bit_depth = 8;

    f(3, color_space);

    if (current->color_space != VP9_CS_RGB) {
        f(1, color_range);
        if (profile == 1 || profile == 3) {
            f(1, subsampling_x);
            f(1, subsampling_y);
            fixed(1, reserved_zero, 0);
        } else {
            infer(subsampling_x, 1);
            infer(subsampling_y, 1);
        }
    } else {
        infer(color_range, 1);
        if (profile == 1 || profile == 3) {
            infer(subsampling_x, 0);
            infer(subsampling_y, 0);
            fixed(1, reserved_zero, 0);
        }
    }

    vp9->subsampling_x = current->subsampling_x;
    vp9->subsampling_y = current->subsampling_y;

    return 0;
}

static int FUNC(frame_size)(CodedBitstreamContext *ctx, RWContext *rw,
                            VP9RawFrameHeader *current)
{
    CodedBitstreamVP9Context *vp9 = ctx->priv_data;
    int err;

    f(16, frame_width_minus_1);
    f(16, frame_height_minus_1);

    vp9->frame_width  = current->frame_width_minus_1  + 1;
    vp9->frame_height = current->frame_height_minus_1 + 1;

    vp9->mi_cols = (vp9->frame_width  + 7) >> 3;
    vp9->mi_rows = (vp9->frame_height + 7) >> 3;
    vp9->sb64_cols = (vp9->mi_cols + 7) >> 3;
    vp9->sb64_rows = (vp9->mi_rows + 7) >> 3;

    return 0;
}

static int FUNC(render_size)(CodedBitstreamContext *ctx, RWContext *rw,
                             VP9RawFrameHeader *current)
{
    int err;

    f(1, render_and_frame_size_different);

    if (current->render_and_frame_size_different) {
        f(16, render_width_minus_1);
        f(16, render_height_minus_1);
    }

    return 0;
}

static int FUNC(frame_size_with_refs)(CodedBitstreamContext *ctx, RWContext *rw,
                                      VP9RawFrameHeader *current)
{
    CodedBitstreamVP9Context *vp9 = ctx->priv_data;
    int err, i;

    for (i = 0; i < VP9_REFS_PER_FRAME; i++) {
        fs(1, found_ref[i], 1, i);
        if (current->found_ref[i]) {
            VP9ReferenceFrameState *ref =
                &vp9->ref[current->ref_frame_idx[i]];

            vp9->frame_width   = ref->frame_width;
            vp9->frame_height  = ref->frame_height;

            vp9->subsampling_x = ref->subsampling_x;
            vp9->subsampling_y = ref->subsampling_y;
            vp9->bit_depth     = ref->bit_depth;

            break;
        }
    }
    if (i >= VP9_REFS_PER_FRAME)
        CHECK(FUNC(frame_size)(ctx, rw, current));
    else {
        vp9->mi_cols = (vp9->frame_width  + 7) >> 3;
        vp9->mi_rows = (vp9->frame_height + 7) >> 3;
        vp9->sb64_cols = (vp9->mi_cols + 7) >> 3;
        vp9->sb64_rows = (vp9->mi_rows + 7) >> 3;
    }
    CHECK(FUNC(render_size)(ctx, rw, current));

    return 0;
}

static int FUNC(interpolation_filter)(CodedBitstreamContext *ctx, RWContext *rw,
                                      VP9RawFrameHeader *current)
{
    int err;

    f(1, is_filter_switchable);
    if (!current->is_filter_switchable)
        f(2, raw_interpolation_filter_type);

    return 0;
}

static int FUNC(loop_filter_params)(CodedBitstreamContext *ctx, RWContext *rw,
                                    VP9RawFrameHeader *current)
{
    int err, i;

    f(6, loop_filter_level);
    f(3, loop_filter_sharpness);

    f(1, loop_filter_delta_enabled);
    if (current->loop_filter_delta_enabled) {
        f(1, loop_filter_delta_update);
        if (current->loop_filter_delta_update) {
            for (i = 0; i < VP9_MAX_REF_FRAMES; i++) {
                fs(1, update_ref_delta[i], 1, i);
                if (current->update_ref_delta[i])
                    ss(6, loop_filter_ref_deltas[i], 1, i);
            }
            for (i = 0; i < 2; i++) {
                fs(1, update_mode_delta[i], 1, i);
                if (current->update_mode_delta[i])
                    ss(6, loop_filter_mode_deltas[i], 1, i);
            }
        }
    }

    return 0;
}

static int FUNC(quantization_params)(CodedBitstreamContext *ctx, RWContext *rw,
                                     VP9RawFrameHeader *current)
{
    int err;

    f(8, base_q_idx);

    delta_q(delta_q_y_dc);
    delta_q(delta_q_uv_dc);
    delta_q(delta_q_uv_ac);

    return 0;
}

static int FUNC(segmentation_params)(CodedBitstreamContext *ctx, RWContext *rw,
                                     VP9RawFrameHeader *current)
{
    static const int segmentation_feature_bits[VP9_SEG_LVL_MAX]   = { 8, 6, 2, 0 };
    static const int segmentation_feature_signed[VP9_SEG_LVL_MAX] = { 1, 1, 0, 0 };

    int err, i, j;

    f(1, segmentation_enabled);

    if (current->segmentation_enabled) {
        f(1, segmentation_update_map);
        if (current->segmentation_update_map) {
            for (i = 0; i < 7; i++)
                prob(segmentation_tree_probs[i], 1, i);
            f(1, segmentation_temporal_update);
            for (i = 0; i < 3; i++) {
                if (current->segmentation_temporal_update)
                    prob(segmentation_pred_prob[i], 1, i);
                else
                    infer(segmentation_pred_prob[i], 255);
            }
        }

        f(1, segmentation_update_data);
        if (current->segmentation_update_data) {
            f(1, segmentation_abs_or_delta_update);
            for (i = 0; i < VP9_MAX_SEGMENTS; i++) {
                for (j = 0; j < VP9_SEG_LVL_MAX; j++) {
                    fs(1, feature_enabled[i][j], 2, i, j);
                    if (current->feature_enabled[i][j] &&
                        segmentation_feature_bits[j]) {
                        fs(segmentation_feature_bits[j],
                           feature_value[i][j], 2, i, j);
                        if (segmentation_feature_signed[j])
                            fs(1, feature_sign[i][j], 2, i, j);
                        else
                            infer(feature_sign[i][j], 0);
                    } else {
                        infer(feature_value[i][j], 0);
                        infer(feature_sign[i][j],  0);
                    }
                }
            }
        }
    }

    return 0;
}

static int FUNC(tile_info)(CodedBitstreamContext *ctx, RWContext *rw,
                           VP9RawFrameHeader *current)
{
    CodedBitstreamVP9Context *vp9 = ctx->priv_data;
    int min_log2_tile_cols, max_log2_tile_cols;
    int err;

    min_log2_tile_cols = 0;
    while ((VP9_MAX_TILE_WIDTH_B64 << min_log2_tile_cols) < vp9->sb64_cols)
        ++min_log2_tile_cols;
    max_log2_tile_cols = 0;
    while ((vp9->sb64_cols >> (max_log2_tile_cols + 1)) >= VP9_MIN_TILE_WIDTH_B64)
        ++max_log2_tile_cols;

    increment(tile_cols_log2, min_log2_tile_cols, max_log2_tile_cols);

    increment(tile_rows_log2, 0, 2);

    return 0;
}

static int FUNC(uncompressed_header)(CodedBitstreamContext *ctx, RWContext *rw,
                                     VP9RawFrameHeader *current)
{
    CodedBitstreamVP9Context *vp9 = ctx->priv_data;
    int err, i;

    f(2, frame_marker);

    f(1, profile_low_bit);
    f(1, profile_high_bit);
    vp9->profile = (current->profile_high_bit << 1) + current->profile_low_bit;
    if (vp9->profile == 3)
        fixed(1, reserved_zero, 0);

    f(1, show_existing_frame);
    if (current->show_existing_frame) {
        f(3, frame_to_show_map_idx);
        infer(header_size_in_bytes, 0);
        infer(refresh_frame_flags,  0x00);
        infer(loop_filter_level,    0);
        return 0;
    }

    f(1, frame_type);
    f(1, show_frame);
    f(1, error_resilient_mode);

    if (current->frame_type == VP9_KEY_FRAME) {
        CHECK(FUNC(frame_sync_code)(ctx, rw, current));
        CHECK(FUNC(color_config)(ctx, rw, current, vp9->profile));
        CHECK(FUNC(frame_size)(ctx, rw, current));
        CHECK(FUNC(render_size)(ctx, rw, current));

        infer(refresh_frame_flags, 0xff);

    } else {
         if (current->show_frame == 0)
             f(1, intra_only);
         else
             infer(intra_only, 0);

         if (current->error_resilient_mode == 0)
             f(2, reset_frame_context);
         else
             infer(reset_frame_context, 0);

         if (current->intra_only == 1) {
             CHECK(FUNC(frame_sync_code)(ctx, rw, current));

             if (vp9->profile > 0) {
                 CHECK(FUNC(color_config)(ctx, rw, current, vp9->profile));
             } else {
                 infer(color_space,   1);
                 infer(subsampling_x, 1);
                 infer(subsampling_y, 1);
                 vp9->bit_depth = 8;

                 vp9->subsampling_x = current->subsampling_x;
                 vp9->subsampling_y = current->subsampling_y;
             }

             f(8, refresh_frame_flags);

             CHECK(FUNC(frame_size)(ctx, rw, current));
             CHECK(FUNC(render_size)(ctx, rw, current));
         } else {
             f(8, refresh_frame_flags);

             for (i = 0; i < VP9_REFS_PER_FRAME; i++) {
                 fs(3, ref_frame_idx[i], 1, i);
                 fs(1, ref_frame_sign_bias[VP9_LAST_FRAME + i],
                    1, VP9_LAST_FRAME + i);
             }

             CHECK(FUNC(frame_size_with_refs)(ctx, rw, current));
             f(1, allow_high_precision_mv);
             CHECK(FUNC(interpolation_filter)(ctx, rw, current));
         }
    }

    if (current->error_resilient_mode == 0) {
        f(1, refresh_frame_context);
        f(1, frame_parallel_decoding_mode);
    } else {
        infer(refresh_frame_context,        0);
        infer(frame_parallel_decoding_mode, 1);
    }

    f(2, frame_context_idx);

    CHECK(FUNC(loop_filter_params)(ctx, rw, current));
    CHECK(FUNC(quantization_params)(ctx, rw, current));
    CHECK(FUNC(segmentation_params)(ctx, rw, current));
    CHECK(FUNC(tile_info)(ctx, rw, current));

    f(16, header_size_in_bytes);

    for (i = 0; i < VP9_NUM_REF_FRAMES; i++) {
        if (current->refresh_frame_flags & (1 << i)) {
            vp9->ref[i] = (VP9ReferenceFrameState) {
                .frame_width    = vp9->frame_width,
                .frame_height   = vp9->frame_height,
                .subsampling_x  = vp9->subsampling_x,
                .subsampling_y  = vp9->subsampling_y,
                .bit_depth      = vp9->bit_depth,
            };
        }
    }

    av_log(ctx->log_ctx, AV_LOG_DEBUG, "Frame:  size %dx%d  "
           "subsample %dx%d  bit_depth %d  tiles %dx%d.\n",
           vp9->frame_width, vp9->frame_height,
           vp9->subsampling_x, vp9->subsampling_y,
           vp9->bit_depth, 1 << current->tile_cols_log2,
           1 << current->tile_rows_log2);

    return 0;
}

static int FUNC(trailing_bits)(CodedBitstreamContext *ctx, RWContext *rw)
{
    int err;
    av_unused int zero = 0;
    while (byte_alignment(rw) != 0)
        xf(1, zero_bit, zero, 0);

    return 0;
}

static int FUNC(frame)(CodedBitstreamContext *ctx, RWContext *rw,
                       VP9RawFrame *current)
{
    int err;

    HEADER("Frame");

    CHECK(FUNC(uncompressed_header)(ctx, rw, &current->header));

    CHECK(FUNC(trailing_bits)(ctx, rw));

    return 0;
}

static int FUNC(superframe_index)(CodedBitstreamContext *ctx, RWContext *rw,
                                  VP9RawSuperframeIndex *current)
{
    int err, i;

    HEADER("Superframe Index");

    f(3, superframe_marker);
    f(2, bytes_per_framesize_minus_1);
    f(3, frames_in_superframe_minus_1);

    for (i = 0; i <= current->frames_in_superframe_minus_1; i++) {
        // Surprise little-endian!
        fle(8 * (current->bytes_per_framesize_minus_1 + 1),
            frame_sizes[i], 1, i);
    }

    f(3, superframe_marker);
    f(2, bytes_per_framesize_minus_1);
    f(3, frames_in_superframe_minus_1);

    return 0;
}
