2015-08-06 05:00:31 +03:00
|
|
|
/*
|
2016-09-02 22:04:54 +03:00
|
|
|
* Copyright (c) 2016, Alliance for Open Media. All rights reserved
|
2015-08-06 05:00:31 +03:00
|
|
|
*
|
2016-09-02 22:04:54 +03:00
|
|
|
* This source code is subject to the terms of the BSD 2 Clause License and
|
|
|
|
* the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
|
|
|
|
* was not distributed with this source code in the LICENSE file, you can
|
|
|
|
* obtain it at www.aomedia.org/license/software. If the Alliance for Open
|
|
|
|
* Media Patent License 1.0 was not distributed with this source code in the
|
|
|
|
* PATENTS file, you can obtain it at www.aomedia.org/license/patent.
|
2015-08-06 05:00:31 +03:00
|
|
|
*/
|
|
|
|
|
|
|
|
#include <assert.h>
|
|
|
|
#include <stdlib.h> // qsort()
|
|
|
|
|
2016-08-31 00:01:10 +03:00
|
|
|
#include "./aom_config.h"
|
|
|
|
#include "./aom_dsp_rtcd.h"
|
|
|
|
#include "./aom_scale_rtcd.h"
|
2016-06-03 21:09:06 +03:00
|
|
|
#include "./av1_rtcd.h"
|
2015-08-06 05:00:31 +03:00
|
|
|
|
2016-08-31 00:01:10 +03:00
|
|
|
#include "aom_dsp/aom_dsp_common.h"
|
2016-06-03 21:09:06 +03:00
|
|
|
#include "aom_dsp/bitreader.h"
|
|
|
|
#include "aom_dsp/bitreader_buffer.h"
|
2016-08-31 00:01:10 +03:00
|
|
|
#include "aom_mem/aom_mem.h"
|
2016-08-23 02:08:15 +03:00
|
|
|
#include "aom_ports/mem.h"
|
|
|
|
#include "aom_ports/mem_ops.h"
|
2016-08-31 00:01:10 +03:00
|
|
|
#include "aom_scale/aom_scale.h"
|
|
|
|
#include "aom_util/aom_thread.h"
|
2015-08-06 05:00:31 +03:00
|
|
|
|
2016-08-23 02:08:15 +03:00
|
|
|
#include "av1/common/alloccommon.h"
|
2016-08-11 19:39:47 +03:00
|
|
|
#if CONFIG_CLPF
|
2016-08-23 02:08:15 +03:00
|
|
|
#include "av1/common/clpf.h"
|
2016-08-11 19:39:47 +03:00
|
|
|
#endif
|
2016-08-23 02:08:15 +03:00
|
|
|
#include "av1/common/common.h"
|
2016-08-15 20:27:19 +03:00
|
|
|
#if CONFIG_DERING
|
2016-08-23 02:08:15 +03:00
|
|
|
#include "av1/common/dering.h"
|
2016-08-15 20:27:19 +03:00
|
|
|
#endif // CONFIG_DERING
|
2016-08-23 02:08:15 +03:00
|
|
|
#include "av1/common/entropy.h"
|
|
|
|
#include "av1/common/entropymode.h"
|
|
|
|
#include "av1/common/idct.h"
|
|
|
|
#include "av1/common/pred_common.h"
|
|
|
|
#include "av1/common/quant_common.h"
|
|
|
|
#include "av1/common/reconinter.h"
|
2016-06-03 21:09:06 +03:00
|
|
|
#include "av1/common/reconintra.h"
|
2016-08-23 02:08:15 +03:00
|
|
|
#include "av1/common/seg_common.h"
|
2016-06-03 21:09:06 +03:00
|
|
|
#include "av1/common/thread_common.h"
|
2016-08-23 02:08:15 +03:00
|
|
|
#include "av1/common/tile_common.h"
|
2015-08-07 07:14:07 +03:00
|
|
|
|
2016-08-23 02:08:15 +03:00
|
|
|
#include "av1/decoder/decodeframe.h"
|
|
|
|
#include "av1/decoder/decodemv.h"
|
|
|
|
#include "av1/decoder/decoder.h"
|
2016-06-03 21:09:06 +03:00
|
|
|
#include "av1/decoder/detokenize.h"
|
2016-08-23 02:08:15 +03:00
|
|
|
#include "av1/decoder/dsubexp.h"
|
2015-08-06 05:00:31 +03:00
|
|
|
|
2016-08-31 00:01:10 +03:00
|
|
|
#define MAX_AV1_HEADER_SIZE 80
|
2015-08-06 05:00:31 +03:00
|
|
|
|
2016-08-31 00:01:10 +03:00
|
|
|
static int is_compound_reference_allowed(const AV1_COMMON *cm) {
|
2015-08-06 05:00:31 +03:00
|
|
|
int i;
|
2016-08-12 04:53:26 +03:00
|
|
|
if (frame_is_intra_only(cm)) return 0;
|
Code refactoring on Macros related to ref frame numbers
We have renamed following Macros to avoid name confusion:
REFS_PER_FRAME --> INTER_REFS_PER_FRAME
(= ALTREF_FRAME - LAST_FRAME + 1)
MAX_REF_FRAMES --> TOTAL_REFS_PER_FRAME
(= ALTREF_FRAME - INTRA_FRAME + 1)
INTER_REFS_PER_FRAME specifies the maximum number of reference frames
that each Inter frame may use.
TOTAL_REFS_PER_FRAME is equal to INTER_REFS_PER_FRAME + 1, which
counts the INTRA_FRAME.
Further, at the encoder side, since REF_FRAMES specifies the maximum
number of the reference frames that the encoder may store, REF_FRAMES
is usually larger than INTER_REFS_PER_FRAME. For example, in the
ext-refs experiment, REF_FRAMES == 8, which allows the encoder to
store maximum 8 reference frames in the buffer, but
INTER_REFS_PER_FRAME equals to 6, which allows each Inter frame may
use up to 6 frames out of the 8 buffered frames as its references.
Hence, in order to explore the possibility to store more reference
frames in future patches, we modified a couple of array sizes to
accomodate the case that the number of buffered reference frames is
not always equal to the number of the references that are being used
by each Inter frame.
Change-Id: I19e42ef608946cc76ebfd3e965a05f4b9b93a0b3
2016-08-04 00:46:43 +03:00
|
|
|
for (i = 1; i < INTER_REFS_PER_FRAME; ++i)
|
2016-08-12 04:53:26 +03:00
|
|
|
if (cm->ref_frame_sign_bias[i + 1] != cm->ref_frame_sign_bias[1]) return 1;
|
2015-08-06 05:00:31 +03:00
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2016-08-31 00:01:10 +03:00
|
|
|
static void setup_compound_reference_mode(AV1_COMMON *cm) {
|
Merge bi-predictive frames to EXT_REFS
This patch removed the experiment of BIDIR_PRED and merged the feature
into the experiment of EXT_REFS:
(1) Each frame now has up to 6 reference frames, namely
LAST_FRAME, LAST2_FRAME, LAST3_FRAME, GOLDEN_FRAME, (forward) and
BWDREF_FRAME, ALTREF_FRAME (backward);
LAST4_FRAME has been removed;
(2) First pass still keeps the 8 updates:
KF_UPDATE, LF_UPDATE, GF_UPDATE, ARF_UPDATE, OVERLAY_UPDATE, and
BRF_UPDATE, LAST_BIPRED_UPDATE, BI_PRED_UPDATE;
(3) show_existing_frame==1 is supported in the experiment of EXT_REFS;
(4) New encoding modes are added for both single-ref and compound cases,
through the use of the 2 extra forward references (LAST2 & LAST3)
and the 1 extra backward reference (BWDREF).
RD performance wise, using Overall PSNR: Avg/BDRate
Bipred only Prev EXT_REFS Current EXT_REFS with bipred
lowres: -3.474/-3.324 -1.748/-1.586 -4.613/-4.387
derflr: -2.097/-1.353 -1.439/-1.215 -3.120/-2.252
midres: -2.129/-1.901 -1.345/-1.185 -2.898/-2.636
If in vp10/encoder/firstpass.h, change BFG_INTERVAL from 2 to 3, i.e. to
use 2 bi-predictive frames than 1, a further improvement may be
obtained:
Current EXT_REFS with bipred
1 bi-predictive frame 2 bi-predictive frames
lowres: -4.613/-4.387 -4.675/-4.465
derflr: -3.120/-2.252 -3.333/-2.516
midres: -2.898/-2.636 -3.406/-3.095
Change-Id: Ib06fe9ea0a5cfd7418a1d79b978ee9d80bf191cb
2016-06-09 00:27:56 +03:00
|
|
|
#if CONFIG_EXT_REFS
|
2016-02-04 20:47:46 +03:00
|
|
|
cm->comp_fwd_ref[0] = LAST_FRAME;
|
Merge bi-predictive frames to EXT_REFS
This patch removed the experiment of BIDIR_PRED and merged the feature
into the experiment of EXT_REFS:
(1) Each frame now has up to 6 reference frames, namely
LAST_FRAME, LAST2_FRAME, LAST3_FRAME, GOLDEN_FRAME, (forward) and
BWDREF_FRAME, ALTREF_FRAME (backward);
LAST4_FRAME has been removed;
(2) First pass still keeps the 8 updates:
KF_UPDATE, LF_UPDATE, GF_UPDATE, ARF_UPDATE, OVERLAY_UPDATE, and
BRF_UPDATE, LAST_BIPRED_UPDATE, BI_PRED_UPDATE;
(3) show_existing_frame==1 is supported in the experiment of EXT_REFS;
(4) New encoding modes are added for both single-ref and compound cases,
through the use of the 2 extra forward references (LAST2 & LAST3)
and the 1 extra backward reference (BWDREF).
RD performance wise, using Overall PSNR: Avg/BDRate
Bipred only Prev EXT_REFS Current EXT_REFS with bipred
lowres: -3.474/-3.324 -1.748/-1.586 -4.613/-4.387
derflr: -2.097/-1.353 -1.439/-1.215 -3.120/-2.252
midres: -2.129/-1.901 -1.345/-1.185 -2.898/-2.636
If in vp10/encoder/firstpass.h, change BFG_INTERVAL from 2 to 3, i.e. to
use 2 bi-predictive frames than 1, a further improvement may be
obtained:
Current EXT_REFS with bipred
1 bi-predictive frame 2 bi-predictive frames
lowres: -4.613/-4.387 -4.675/-4.465
derflr: -3.120/-2.252 -3.333/-2.516
midres: -2.898/-2.636 -3.406/-3.095
Change-Id: Ib06fe9ea0a5cfd7418a1d79b978ee9d80bf191cb
2016-06-09 00:27:56 +03:00
|
|
|
cm->comp_fwd_ref[1] = LAST2_FRAME;
|
|
|
|
cm->comp_fwd_ref[2] = LAST3_FRAME;
|
|
|
|
cm->comp_fwd_ref[3] = GOLDEN_FRAME;
|
|
|
|
|
2016-02-04 20:47:46 +03:00
|
|
|
cm->comp_bwd_ref[0] = BWDREF_FRAME;
|
|
|
|
cm->comp_bwd_ref[1] = ALTREF_FRAME;
|
Merge bi-predictive frames to EXT_REFS
This patch removed the experiment of BIDIR_PRED and merged the feature
into the experiment of EXT_REFS:
(1) Each frame now has up to 6 reference frames, namely
LAST_FRAME, LAST2_FRAME, LAST3_FRAME, GOLDEN_FRAME, (forward) and
BWDREF_FRAME, ALTREF_FRAME (backward);
LAST4_FRAME has been removed;
(2) First pass still keeps the 8 updates:
KF_UPDATE, LF_UPDATE, GF_UPDATE, ARF_UPDATE, OVERLAY_UPDATE, and
BRF_UPDATE, LAST_BIPRED_UPDATE, BI_PRED_UPDATE;
(3) show_existing_frame==1 is supported in the experiment of EXT_REFS;
(4) New encoding modes are added for both single-ref and compound cases,
through the use of the 2 extra forward references (LAST2 & LAST3)
and the 1 extra backward reference (BWDREF).
RD performance wise, using Overall PSNR: Avg/BDRate
Bipred only Prev EXT_REFS Current EXT_REFS with bipred
lowres: -3.474/-3.324 -1.748/-1.586 -4.613/-4.387
derflr: -2.097/-1.353 -1.439/-1.215 -3.120/-2.252
midres: -2.129/-1.901 -1.345/-1.185 -2.898/-2.636
If in vp10/encoder/firstpass.h, change BFG_INTERVAL from 2 to 3, i.e. to
use 2 bi-predictive frames than 1, a further improvement may be
obtained:
Current EXT_REFS with bipred
1 bi-predictive frame 2 bi-predictive frames
lowres: -4.613/-4.387 -4.675/-4.465
derflr: -3.120/-2.252 -3.333/-2.516
midres: -2.898/-2.636 -3.406/-3.095
Change-Id: Ib06fe9ea0a5cfd7418a1d79b978ee9d80bf191cb
2016-06-09 00:27:56 +03:00
|
|
|
#else
|
2015-08-06 05:00:31 +03:00
|
|
|
if (cm->ref_frame_sign_bias[LAST_FRAME] ==
|
2016-08-12 04:53:26 +03:00
|
|
|
cm->ref_frame_sign_bias[GOLDEN_FRAME]) {
|
2015-08-06 05:00:31 +03:00
|
|
|
cm->comp_fixed_ref = ALTREF_FRAME;
|
|
|
|
cm->comp_var_ref[0] = LAST_FRAME;
|
|
|
|
cm->comp_var_ref[1] = GOLDEN_FRAME;
|
|
|
|
} else if (cm->ref_frame_sign_bias[LAST_FRAME] ==
|
2016-08-12 04:53:26 +03:00
|
|
|
cm->ref_frame_sign_bias[ALTREF_FRAME]) {
|
2015-08-06 05:00:31 +03:00
|
|
|
cm->comp_fixed_ref = GOLDEN_FRAME;
|
|
|
|
cm->comp_var_ref[0] = LAST_FRAME;
|
|
|
|
cm->comp_var_ref[1] = ALTREF_FRAME;
|
|
|
|
} else {
|
|
|
|
cm->comp_fixed_ref = LAST_FRAME;
|
|
|
|
cm->comp_var_ref[0] = GOLDEN_FRAME;
|
|
|
|
cm->comp_var_ref[1] = ALTREF_FRAME;
|
|
|
|
}
|
Merge bi-predictive frames to EXT_REFS
This patch removed the experiment of BIDIR_PRED and merged the feature
into the experiment of EXT_REFS:
(1) Each frame now has up to 6 reference frames, namely
LAST_FRAME, LAST2_FRAME, LAST3_FRAME, GOLDEN_FRAME, (forward) and
BWDREF_FRAME, ALTREF_FRAME (backward);
LAST4_FRAME has been removed;
(2) First pass still keeps the 8 updates:
KF_UPDATE, LF_UPDATE, GF_UPDATE, ARF_UPDATE, OVERLAY_UPDATE, and
BRF_UPDATE, LAST_BIPRED_UPDATE, BI_PRED_UPDATE;
(3) show_existing_frame==1 is supported in the experiment of EXT_REFS;
(4) New encoding modes are added for both single-ref and compound cases,
through the use of the 2 extra forward references (LAST2 & LAST3)
and the 1 extra backward reference (BWDREF).
RD performance wise, using Overall PSNR: Avg/BDRate
Bipred only Prev EXT_REFS Current EXT_REFS with bipred
lowres: -3.474/-3.324 -1.748/-1.586 -4.613/-4.387
derflr: -2.097/-1.353 -1.439/-1.215 -3.120/-2.252
midres: -2.129/-1.901 -1.345/-1.185 -2.898/-2.636
If in vp10/encoder/firstpass.h, change BFG_INTERVAL from 2 to 3, i.e. to
use 2 bi-predictive frames than 1, a further improvement may be
obtained:
Current EXT_REFS with bipred
1 bi-predictive frame 2 bi-predictive frames
lowres: -4.613/-4.387 -4.675/-4.465
derflr: -3.120/-2.252 -3.333/-2.516
midres: -2.898/-2.636 -3.406/-3.095
Change-Id: Ib06fe9ea0a5cfd7418a1d79b978ee9d80bf191cb
2016-06-09 00:27:56 +03:00
|
|
|
#endif // CONFIG_EXT_REFS
|
2015-08-06 05:00:31 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
static int read_is_valid(const uint8_t *start, size_t len, const uint8_t *end) {
|
|
|
|
return len != 0 && len <= (size_t)(end - start);
|
|
|
|
}
|
|
|
|
|
2016-08-31 00:01:10 +03:00
|
|
|
static int decode_unsigned_max(struct aom_read_bit_buffer *rb, int max) {
|
|
|
|
const int data = aom_rb_read_literal(rb, get_unsigned_bits(max));
|
2015-08-06 05:00:31 +03:00
|
|
|
return data > max ? max : data;
|
|
|
|
}
|
|
|
|
|
2016-08-31 00:01:10 +03:00
|
|
|
static TX_MODE read_tx_mode(struct aom_read_bit_buffer *rb) {
|
|
|
|
return aom_rb_read_bit(rb) ? TX_MODE_SELECT : aom_rb_read_literal(rb, 2);
|
2015-09-08 21:33:17 +03:00
|
|
|
}
|
2015-08-06 05:00:31 +03:00
|
|
|
|
2016-08-31 00:01:10 +03:00
|
|
|
static void read_switchable_interp_probs(FRAME_CONTEXT *fc, aom_reader *r) {
|
2015-08-06 05:00:31 +03:00
|
|
|
int i, j;
|
|
|
|
for (j = 0; j < SWITCHABLE_FILTER_CONTEXTS; ++j)
|
|
|
|
for (i = 0; i < SWITCHABLE_FILTERS - 1; ++i)
|
2016-08-31 00:01:10 +03:00
|
|
|
av1_diff_update_prob(r, &fc->switchable_interp_prob[j][i]);
|
2015-08-06 05:00:31 +03:00
|
|
|
}
|
|
|
|
|
2016-08-31 00:01:10 +03:00
|
|
|
static void read_inter_mode_probs(FRAME_CONTEXT *fc, aom_reader *r) {
|
2015-12-02 21:59:01 +03:00
|
|
|
int i;
|
|
|
|
#if CONFIG_REF_MV
|
|
|
|
for (i = 0; i < NEWMV_MODE_CONTEXTS; ++i)
|
2016-08-31 00:01:10 +03:00
|
|
|
av1_diff_update_prob(r, &fc->newmv_prob[i]);
|
2015-12-02 21:59:01 +03:00
|
|
|
for (i = 0; i < ZEROMV_MODE_CONTEXTS; ++i)
|
2016-08-31 00:01:10 +03:00
|
|
|
av1_diff_update_prob(r, &fc->zeromv_prob[i]);
|
2015-12-02 21:59:01 +03:00
|
|
|
for (i = 0; i < REFMV_MODE_CONTEXTS; ++i)
|
2016-08-31 00:01:10 +03:00
|
|
|
av1_diff_update_prob(r, &fc->refmv_prob[i]);
|
2016-01-22 05:07:31 +03:00
|
|
|
for (i = 0; i < DRL_MODE_CONTEXTS; ++i)
|
2016-08-31 00:01:10 +03:00
|
|
|
av1_diff_update_prob(r, &fc->drl_prob[i]);
|
2016-01-08 02:13:52 +03:00
|
|
|
#if CONFIG_EXT_INTER
|
2016-08-31 00:01:10 +03:00
|
|
|
av1_diff_update_prob(r, &fc->new2mv_prob);
|
2016-01-08 02:13:52 +03:00
|
|
|
#endif // CONFIG_EXT_INTER
|
2015-12-02 21:59:01 +03:00
|
|
|
#else
|
|
|
|
int j;
|
2015-08-06 05:00:31 +03:00
|
|
|
for (i = 0; i < INTER_MODE_CONTEXTS; ++i)
|
|
|
|
for (j = 0; j < INTER_MODES - 1; ++j)
|
2016-08-31 00:01:10 +03:00
|
|
|
av1_diff_update_prob(r, &fc->inter_mode_probs[i][j]);
|
2015-12-02 21:59:01 +03:00
|
|
|
#endif
|
2015-08-06 05:00:31 +03:00
|
|
|
}
|
|
|
|
|
2016-01-20 03:45:45 +03:00
|
|
|
#if CONFIG_EXT_INTER
|
2016-08-31 00:01:10 +03:00
|
|
|
static void read_inter_compound_mode_probs(FRAME_CONTEXT *fc, aom_reader *r) {
|
2016-01-20 03:45:45 +03:00
|
|
|
int i, j;
|
2016-08-31 00:01:10 +03:00
|
|
|
if (aom_read(r, GROUP_DIFF_UPDATE_PROB)) {
|
2016-01-20 03:45:45 +03:00
|
|
|
for (j = 0; j < INTER_MODE_CONTEXTS; ++j) {
|
|
|
|
for (i = 0; i < INTER_COMPOUND_MODES - 1; ++i) {
|
2016-08-31 00:01:10 +03:00
|
|
|
av1_diff_update_prob(r, &fc->inter_compound_mode_probs[j][i]);
|
2016-01-20 03:45:45 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
#endif // CONFIG_EXT_INTER
|
|
|
|
|
2016-08-12 04:53:26 +03:00
|
|
|
static REFERENCE_MODE read_frame_reference_mode(
|
2016-08-31 00:01:10 +03:00
|
|
|
const AV1_COMMON *cm, struct aom_read_bit_buffer *rb) {
|
2015-09-29 01:55:46 +03:00
|
|
|
if (is_compound_reference_allowed(cm)) {
|
2016-08-31 00:01:10 +03:00
|
|
|
return aom_rb_read_bit(rb)
|
2016-08-12 04:53:26 +03:00
|
|
|
? REFERENCE_MODE_SELECT
|
2016-08-31 00:01:10 +03:00
|
|
|
: (aom_rb_read_bit(rb) ? COMPOUND_REFERENCE : SINGLE_REFERENCE);
|
2015-09-29 01:55:46 +03:00
|
|
|
} else {
|
|
|
|
return SINGLE_REFERENCE;
|
|
|
|
}
|
|
|
|
}
|
2015-08-06 05:00:31 +03:00
|
|
|
|
2016-08-31 00:01:10 +03:00
|
|
|
static void read_frame_reference_mode_probs(AV1_COMMON *cm, aom_reader *r) {
|
2015-08-06 05:00:31 +03:00
|
|
|
FRAME_CONTEXT *const fc = cm->fc;
|
2015-11-12 13:12:17 +03:00
|
|
|
int i, j;
|
2015-08-06 05:00:31 +03:00
|
|
|
|
|
|
|
if (cm->reference_mode == REFERENCE_MODE_SELECT)
|
|
|
|
for (i = 0; i < COMP_INTER_CONTEXTS; ++i)
|
2016-08-31 00:01:10 +03:00
|
|
|
av1_diff_update_prob(r, &fc->comp_inter_prob[i]);
|
2015-08-06 05:00:31 +03:00
|
|
|
|
2015-11-12 13:12:17 +03:00
|
|
|
if (cm->reference_mode != COMPOUND_REFERENCE) {
|
2015-08-06 05:00:31 +03:00
|
|
|
for (i = 0; i < REF_CONTEXTS; ++i) {
|
2015-11-12 13:12:17 +03:00
|
|
|
for (j = 0; j < (SINGLE_REFS - 1); ++j) {
|
2016-08-31 00:01:10 +03:00
|
|
|
av1_diff_update_prob(r, &fc->single_ref_prob[i][j]);
|
2015-11-12 13:12:17 +03:00
|
|
|
}
|
2015-08-06 05:00:31 +03:00
|
|
|
}
|
2015-11-12 13:12:17 +03:00
|
|
|
}
|
2015-08-06 05:00:31 +03:00
|
|
|
|
2015-11-12 13:12:17 +03:00
|
|
|
if (cm->reference_mode != SINGLE_REFERENCE) {
|
|
|
|
for (i = 0; i < REF_CONTEXTS; ++i) {
|
Merge bi-predictive frames to EXT_REFS
This patch removed the experiment of BIDIR_PRED and merged the feature
into the experiment of EXT_REFS:
(1) Each frame now has up to 6 reference frames, namely
LAST_FRAME, LAST2_FRAME, LAST3_FRAME, GOLDEN_FRAME, (forward) and
BWDREF_FRAME, ALTREF_FRAME (backward);
LAST4_FRAME has been removed;
(2) First pass still keeps the 8 updates:
KF_UPDATE, LF_UPDATE, GF_UPDATE, ARF_UPDATE, OVERLAY_UPDATE, and
BRF_UPDATE, LAST_BIPRED_UPDATE, BI_PRED_UPDATE;
(3) show_existing_frame==1 is supported in the experiment of EXT_REFS;
(4) New encoding modes are added for both single-ref and compound cases,
through the use of the 2 extra forward references (LAST2 & LAST3)
and the 1 extra backward reference (BWDREF).
RD performance wise, using Overall PSNR: Avg/BDRate
Bipred only Prev EXT_REFS Current EXT_REFS with bipred
lowres: -3.474/-3.324 -1.748/-1.586 -4.613/-4.387
derflr: -2.097/-1.353 -1.439/-1.215 -3.120/-2.252
midres: -2.129/-1.901 -1.345/-1.185 -2.898/-2.636
If in vp10/encoder/firstpass.h, change BFG_INTERVAL from 2 to 3, i.e. to
use 2 bi-predictive frames than 1, a further improvement may be
obtained:
Current EXT_REFS with bipred
1 bi-predictive frame 2 bi-predictive frames
lowres: -4.613/-4.387 -4.675/-4.465
derflr: -3.120/-2.252 -3.333/-2.516
midres: -2.898/-2.636 -3.406/-3.095
Change-Id: Ib06fe9ea0a5cfd7418a1d79b978ee9d80bf191cb
2016-06-09 00:27:56 +03:00
|
|
|
#if CONFIG_EXT_REFS
|
2016-02-04 20:47:46 +03:00
|
|
|
for (j = 0; j < (FWD_REFS - 1); ++j)
|
2016-08-31 00:01:10 +03:00
|
|
|
av1_diff_update_prob(r, &fc->comp_ref_prob[i][j]);
|
2016-02-04 20:47:46 +03:00
|
|
|
for (j = 0; j < (BWD_REFS - 1); ++j)
|
2016-08-31 00:01:10 +03:00
|
|
|
av1_diff_update_prob(r, &fc->comp_bwdref_prob[i][j]);
|
2016-02-04 20:47:46 +03:00
|
|
|
#else
|
|
|
|
for (j = 0; j < (COMP_REFS - 1); ++j)
|
2016-08-31 00:01:10 +03:00
|
|
|
av1_diff_update_prob(r, &fc->comp_ref_prob[i][j]);
|
Merge bi-predictive frames to EXT_REFS
This patch removed the experiment of BIDIR_PRED and merged the feature
into the experiment of EXT_REFS:
(1) Each frame now has up to 6 reference frames, namely
LAST_FRAME, LAST2_FRAME, LAST3_FRAME, GOLDEN_FRAME, (forward) and
BWDREF_FRAME, ALTREF_FRAME (backward);
LAST4_FRAME has been removed;
(2) First pass still keeps the 8 updates:
KF_UPDATE, LF_UPDATE, GF_UPDATE, ARF_UPDATE, OVERLAY_UPDATE, and
BRF_UPDATE, LAST_BIPRED_UPDATE, BI_PRED_UPDATE;
(3) show_existing_frame==1 is supported in the experiment of EXT_REFS;
(4) New encoding modes are added for both single-ref and compound cases,
through the use of the 2 extra forward references (LAST2 & LAST3)
and the 1 extra backward reference (BWDREF).
RD performance wise, using Overall PSNR: Avg/BDRate
Bipred only Prev EXT_REFS Current EXT_REFS with bipred
lowres: -3.474/-3.324 -1.748/-1.586 -4.613/-4.387
derflr: -2.097/-1.353 -1.439/-1.215 -3.120/-2.252
midres: -2.129/-1.901 -1.345/-1.185 -2.898/-2.636
If in vp10/encoder/firstpass.h, change BFG_INTERVAL from 2 to 3, i.e. to
use 2 bi-predictive frames than 1, a further improvement may be
obtained:
Current EXT_REFS with bipred
1 bi-predictive frame 2 bi-predictive frames
lowres: -4.613/-4.387 -4.675/-4.465
derflr: -3.120/-2.252 -3.333/-2.516
midres: -2.898/-2.636 -3.406/-3.095
Change-Id: Ib06fe9ea0a5cfd7418a1d79b978ee9d80bf191cb
2016-06-09 00:27:56 +03:00
|
|
|
#endif // CONFIG_EXT_REFS
|
2015-11-12 13:12:17 +03:00
|
|
|
}
|
|
|
|
}
|
2015-08-06 05:00:31 +03:00
|
|
|
}
|
|
|
|
|
2016-08-31 00:01:10 +03:00
|
|
|
static void update_mv_probs(aom_prob *p, int n, aom_reader *r) {
|
2015-08-06 05:00:31 +03:00
|
|
|
int i;
|
2016-08-31 00:01:10 +03:00
|
|
|
for (i = 0; i < n; ++i) av1_diff_update_prob(r, &p[i]);
|
2015-08-06 05:00:31 +03:00
|
|
|
}
|
|
|
|
|
2016-08-31 00:01:10 +03:00
|
|
|
static void read_mv_probs(nmv_context *ctx, int allow_hp, aom_reader *r) {
|
2015-08-06 05:00:31 +03:00
|
|
|
int i, j;
|
|
|
|
|
|
|
|
update_mv_probs(ctx->joints, MV_JOINTS - 1, r);
|
|
|
|
|
2016-04-14 22:37:10 +03:00
|
|
|
#if CONFIG_REF_MV
|
2016-08-31 00:01:10 +03:00
|
|
|
av1_diff_update_prob(r, &ctx->zero_rmv);
|
2016-04-14 22:37:10 +03:00
|
|
|
#endif
|
|
|
|
|
2015-08-06 05:00:31 +03:00
|
|
|
for (i = 0; i < 2; ++i) {
|
|
|
|
nmv_component *const comp_ctx = &ctx->comps[i];
|
|
|
|
update_mv_probs(&comp_ctx->sign, 1, r);
|
|
|
|
update_mv_probs(comp_ctx->classes, MV_CLASSES - 1, r);
|
|
|
|
update_mv_probs(comp_ctx->class0, CLASS0_SIZE - 1, r);
|
|
|
|
update_mv_probs(comp_ctx->bits, MV_OFFSET_BITS, r);
|
|
|
|
}
|
|
|
|
|
|
|
|
for (i = 0; i < 2; ++i) {
|
|
|
|
nmv_component *const comp_ctx = &ctx->comps[i];
|
|
|
|
for (j = 0; j < CLASS0_SIZE; ++j)
|
|
|
|
update_mv_probs(comp_ctx->class0_fp[j], MV_FP_SIZE - 1, r);
|
|
|
|
update_mv_probs(comp_ctx->fp, 3, r);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (allow_hp) {
|
|
|
|
for (i = 0; i < 2; ++i) {
|
|
|
|
nmv_component *const comp_ctx = &ctx->comps[i];
|
|
|
|
update_mv_probs(&comp_ctx->class0_hp, 1, r);
|
|
|
|
update_mv_probs(&comp_ctx->hp, 1, r);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-08-12 04:53:26 +03:00
|
|
|
static void inverse_transform_block(MACROBLOCKD *xd, int plane,
|
2016-03-15 03:00:53 +03:00
|
|
|
const TX_TYPE tx_type,
|
2016-08-12 04:53:26 +03:00
|
|
|
const TX_SIZE tx_size, uint8_t *dst,
|
|
|
|
int stride, int eob) {
|
2015-08-06 05:00:31 +03:00
|
|
|
struct macroblockd_plane *const pd = &xd->plane[plane];
|
|
|
|
if (eob > 0) {
|
|
|
|
tran_low_t *const dqcoeff = pd->dqcoeff;
|
2016-03-15 03:38:15 +03:00
|
|
|
INV_TXFM_PARAM inv_txfm_param;
|
|
|
|
inv_txfm_param.tx_type = tx_type;
|
|
|
|
inv_txfm_param.tx_size = tx_size;
|
|
|
|
inv_txfm_param.eob = eob;
|
2016-06-09 19:06:02 +03:00
|
|
|
inv_txfm_param.lossless = xd->lossless[xd->mi[0]->mbmi.segment_id];
|
2016-03-15 03:38:15 +03:00
|
|
|
|
2016-08-31 00:01:10 +03:00
|
|
|
#if CONFIG_AOM_HIGHBITDEPTH
|
2015-08-06 05:00:31 +03:00
|
|
|
if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
|
2016-03-15 03:38:15 +03:00
|
|
|
inv_txfm_param.bd = xd->bd;
|
|
|
|
highbd_inv_txfm_add(dqcoeff, dst, stride, &inv_txfm_param);
|
2015-08-06 05:00:31 +03:00
|
|
|
} else {
|
2016-08-31 00:01:10 +03:00
|
|
|
#endif // CONFIG_AOM_HIGHBITDEPTH
|
2016-03-15 03:38:15 +03:00
|
|
|
inv_txfm_add(dqcoeff, dst, stride, &inv_txfm_param);
|
2016-08-31 00:01:10 +03:00
|
|
|
#if CONFIG_AOM_HIGHBITDEPTH
|
2015-08-06 05:00:31 +03:00
|
|
|
}
|
2016-08-31 00:01:10 +03:00
|
|
|
#endif // CONFIG_AOM_HIGHBITDEPTH
|
2015-08-06 05:00:31 +03:00
|
|
|
|
|
|
|
if (eob == 1) {
|
|
|
|
dqcoeff[0] = 0;
|
|
|
|
} else {
|
2016-01-06 22:24:57 +03:00
|
|
|
if (tx_type == DCT_DCT && tx_size <= TX_16X16 && eob <= 10)
|
2016-07-01 22:57:14 +03:00
|
|
|
memset(dqcoeff, 0, 4 * 4 * num_4x4_blocks_wide_txsize_lookup[tx_size] *
|
2016-08-12 04:53:26 +03:00
|
|
|
sizeof(dqcoeff[0]));
|
2016-03-09 19:58:07 +03:00
|
|
|
#if CONFIG_EXT_TX
|
|
|
|
else
|
2016-07-01 22:57:14 +03:00
|
|
|
memset(dqcoeff, 0, get_tx2d_size(tx_size) * sizeof(dqcoeff[0]));
|
2016-03-09 19:58:07 +03:00
|
|
|
#else
|
2015-08-06 05:00:31 +03:00
|
|
|
else if (tx_size == TX_32X32 && eob <= 34)
|
|
|
|
memset(dqcoeff, 0, 256 * sizeof(dqcoeff[0]));
|
|
|
|
else
|
2016-07-01 22:57:14 +03:00
|
|
|
memset(dqcoeff, 0, get_tx2d_size(tx_size) * sizeof(dqcoeff[0]));
|
2016-03-09 19:58:07 +03:00
|
|
|
#endif
|
2015-08-06 05:00:31 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void predict_and_reconstruct_intra_block(MACROBLOCKD *const xd,
|
2015-12-16 22:17:25 +03:00
|
|
|
#if CONFIG_ANS
|
|
|
|
struct AnsDecoder *const r,
|
|
|
|
#else
|
2016-08-31 00:01:10 +03:00
|
|
|
aom_reader *r,
|
2015-12-16 22:17:25 +03:00
|
|
|
#endif // CONFIG_ANS
|
2015-08-06 05:00:31 +03:00
|
|
|
MB_MODE_INFO *const mbmi,
|
2016-08-12 04:53:26 +03:00
|
|
|
int plane, int row, int col,
|
2015-08-06 05:00:31 +03:00
|
|
|
TX_SIZE tx_size) {
|
|
|
|
struct macroblockd_plane *const pd = &xd->plane[plane];
|
|
|
|
PREDICTION_MODE mode = (plane == 0) ? mbmi->mode : mbmi->uv_mode;
|
2015-08-19 02:57:07 +03:00
|
|
|
PLANE_TYPE plane_type = (plane == 0) ? PLANE_TYPE_Y : PLANE_TYPE_UV;
|
2015-08-06 05:00:31 +03:00
|
|
|
uint8_t *dst;
|
2015-08-19 02:57:07 +03:00
|
|
|
int block_idx = (row << 1) + col;
|
2015-08-06 05:00:31 +03:00
|
|
|
dst = &pd->dst.buf[4 * row * pd->dst.stride + 4 * col];
|
|
|
|
|
|
|
|
if (mbmi->sb_type < BLOCK_8X8)
|
2016-08-12 04:53:26 +03:00
|
|
|
if (plane == 0) mode = xd->mi[0]->bmi[(row << 1) + col].as_mode;
|
2015-08-06 05:00:31 +03:00
|
|
|
|
2016-08-31 00:01:10 +03:00
|
|
|
av1_predict_intra_block(xd, pd->n4_wl, pd->n4_hl, tx_size, mode, dst,
|
|
|
|
pd->dst.stride, dst, pd->dst.stride, col, row, plane);
|
2015-08-06 05:00:31 +03:00
|
|
|
|
|
|
|
if (!mbmi->skip) {
|
2015-08-25 00:37:54 +03:00
|
|
|
TX_TYPE tx_type = get_tx_type(plane_type, xd, block_idx, tx_size);
|
2015-09-03 12:58:12 +03:00
|
|
|
const scan_order *sc = get_scan(tx_size, tx_type, 0);
|
2016-08-31 00:01:10 +03:00
|
|
|
const int eob = av1_decode_block_tokens(xd, plane, sc, col, row, tx_size,
|
|
|
|
tx_type, r, mbmi->segment_id);
|
2016-08-12 04:53:26 +03:00
|
|
|
inverse_transform_block(xd, plane, tx_type, tx_size, dst, pd->dst.stride,
|
|
|
|
eob);
|
2015-08-06 05:00:31 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-10-07 03:02:34 +03:00
|
|
|
#if CONFIG_VAR_TX
|
2016-08-31 00:01:10 +03:00
|
|
|
static void decode_reconstruct_tx(MACROBLOCKD *const xd, aom_reader *r,
|
2016-08-12 04:53:26 +03:00
|
|
|
MB_MODE_INFO *const mbmi, int plane,
|
|
|
|
BLOCK_SIZE plane_bsize, int block,
|
|
|
|
int blk_row, int blk_col, TX_SIZE tx_size,
|
|
|
|
int *eob_total) {
|
2015-10-07 03:02:34 +03:00
|
|
|
const struct macroblockd_plane *const pd = &xd->plane[plane];
|
2015-10-09 19:57:42 +03:00
|
|
|
const BLOCK_SIZE bsize = txsize_to_bsize[tx_size];
|
2016-03-16 21:03:57 +03:00
|
|
|
const int tx_row = blk_row >> (1 - pd->subsampling_y);
|
|
|
|
const int tx_col = blk_col >> (1 - pd->subsampling_x);
|
2016-08-12 04:53:26 +03:00
|
|
|
const TX_SIZE plane_tx_size =
|
2016-08-31 03:43:38 +03:00
|
|
|
plane ? uv_txsize_lookup[bsize][mbmi->inter_tx_size[tx_row][tx_col]][0][0]
|
2016-08-12 04:53:26 +03:00
|
|
|
: mbmi->inter_tx_size[tx_row][tx_col];
|
2015-10-07 03:02:34 +03:00
|
|
|
int max_blocks_high = num_4x4_blocks_high_lookup[plane_bsize];
|
|
|
|
int max_blocks_wide = num_4x4_blocks_wide_lookup[plane_bsize];
|
|
|
|
|
|
|
|
if (xd->mb_to_bottom_edge < 0)
|
|
|
|
max_blocks_high += xd->mb_to_bottom_edge >> (5 + pd->subsampling_y);
|
|
|
|
if (xd->mb_to_right_edge < 0)
|
|
|
|
max_blocks_wide += xd->mb_to_right_edge >> (5 + pd->subsampling_x);
|
|
|
|
|
2016-08-12 04:53:26 +03:00
|
|
|
if (blk_row >= max_blocks_high || blk_col >= max_blocks_wide) return;
|
2015-10-07 03:02:34 +03:00
|
|
|
|
2016-08-12 02:42:08 +03:00
|
|
|
if (tx_size == plane_tx_size) {
|
2015-10-07 03:02:34 +03:00
|
|
|
PLANE_TYPE plane_type = (plane == 0) ? PLANE_TYPE_Y : PLANE_TYPE_UV;
|
2016-07-01 22:57:14 +03:00
|
|
|
TX_TYPE tx_type = get_tx_type(plane_type, xd, block, plane_tx_size);
|
|
|
|
const scan_order *sc = get_scan(plane_tx_size, tx_type, 1);
|
2016-08-12 04:53:26 +03:00
|
|
|
const int eob =
|
2016-08-31 00:01:10 +03:00
|
|
|
av1_decode_block_tokens(xd, plane, sc, blk_col, blk_row, plane_tx_size,
|
|
|
|
tx_type, r, mbmi->segment_id);
|
2016-08-12 04:53:26 +03:00
|
|
|
inverse_transform_block(
|
|
|
|
xd, plane, tx_type, plane_tx_size,
|
2015-10-07 03:02:34 +03:00
|
|
|
&pd->dst.buf[4 * blk_row * pd->dst.stride + 4 * blk_col],
|
2016-03-15 03:00:53 +03:00
|
|
|
pd->dst.stride, eob);
|
2015-10-07 03:02:34 +03:00
|
|
|
*eob_total += eob;
|
|
|
|
} else {
|
|
|
|
int bsl = b_width_log2_lookup[bsize];
|
|
|
|
int i;
|
|
|
|
|
|
|
|
assert(bsl > 0);
|
|
|
|
--bsl;
|
|
|
|
|
|
|
|
for (i = 0; i < 4; ++i) {
|
|
|
|
const int offsetr = blk_row + ((i >> 1) << bsl);
|
|
|
|
const int offsetc = blk_col + ((i & 0x01) << bsl);
|
2016-07-01 22:57:14 +03:00
|
|
|
int step = num_4x4_blocks_txsize_lookup[tx_size - 1];
|
2015-10-07 03:02:34 +03:00
|
|
|
|
2016-08-12 04:53:26 +03:00
|
|
|
if (offsetr >= max_blocks_high || offsetc >= max_blocks_wide) continue;
|
2015-10-07 03:02:34 +03:00
|
|
|
|
|
|
|
decode_reconstruct_tx(xd, r, mbmi, plane, plane_bsize, block + i * step,
|
|
|
|
offsetr, offsetc, tx_size - 1, eob_total);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2015-11-20 03:51:16 +03:00
|
|
|
#endif // CONFIG_VAR_TX
|
2015-10-07 03:02:34 +03:00
|
|
|
|
2016-08-12 02:42:08 +03:00
|
|
|
#if !CONFIG_VAR_TX || CONFIG_SUPERTX || (CONFIG_EXT_TX && CONFIG_RECT_TX)
|
2015-12-16 22:17:25 +03:00
|
|
|
static int reconstruct_inter_block(MACROBLOCKD *const xd,
|
|
|
|
#if CONFIG_ANS
|
|
|
|
struct AnsDecoder *const r,
|
|
|
|
#else
|
2016-08-31 00:01:10 +03:00
|
|
|
aom_reader *r,
|
2015-12-16 22:17:25 +03:00
|
|
|
#endif
|
2016-08-12 04:53:26 +03:00
|
|
|
int segment_id, int plane, int row, int col,
|
|
|
|
TX_SIZE tx_size) {
|
2015-08-06 05:00:31 +03:00
|
|
|
struct macroblockd_plane *const pd = &xd->plane[plane];
|
2015-08-19 02:57:07 +03:00
|
|
|
PLANE_TYPE plane_type = (plane == 0) ? PLANE_TYPE_Y : PLANE_TYPE_UV;
|
|
|
|
int block_idx = (row << 1) + col;
|
2015-08-25 00:37:54 +03:00
|
|
|
TX_TYPE tx_type = get_tx_type(plane_type, xd, block_idx, tx_size);
|
2015-09-03 12:58:12 +03:00
|
|
|
const scan_order *sc = get_scan(tx_size, tx_type, 1);
|
2016-08-31 00:01:10 +03:00
|
|
|
const int eob = av1_decode_block_tokens(xd, plane, sc, col, row, tx_size,
|
|
|
|
tx_type, r, segment_id);
|
2015-08-06 05:00:31 +03:00
|
|
|
|
2016-03-15 03:00:53 +03:00
|
|
|
inverse_transform_block(xd, plane, tx_type, tx_size,
|
|
|
|
&pd->dst.buf[4 * row * pd->dst.stride + 4 * col],
|
|
|
|
pd->dst.stride, eob);
|
2015-08-06 05:00:31 +03:00
|
|
|
return eob;
|
|
|
|
}
|
2016-03-01 20:47:04 +03:00
|
|
|
#endif // !CONFIG_VAR_TX || CONFIG_SUPER_TX
|
2015-08-06 05:00:31 +03:00
|
|
|
|
|
|
|
static INLINE void dec_reset_skip_context(MACROBLOCKD *xd) {
|
|
|
|
int i;
|
|
|
|
for (i = 0; i < MAX_MB_PLANE; i++) {
|
|
|
|
struct macroblockd_plane *const pd = &xd->plane[i];
|
|
|
|
memset(pd->above_context, 0, sizeof(ENTROPY_CONTEXT) * pd->n4_w);
|
|
|
|
memset(pd->left_context, 0, sizeof(ENTROPY_CONTEXT) * pd->n4_h);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void set_plane_n4(MACROBLOCKD *const xd, int bw, int bh, int bwl,
|
|
|
|
int bhl) {
|
|
|
|
int i;
|
|
|
|
for (i = 0; i < MAX_MB_PLANE; i++) {
|
|
|
|
xd->plane[i].n4_w = (bw << 1) >> xd->plane[i].subsampling_x;
|
|
|
|
xd->plane[i].n4_h = (bh << 1) >> xd->plane[i].subsampling_y;
|
|
|
|
xd->plane[i].n4_wl = bwl - xd->plane[i].subsampling_x;
|
|
|
|
xd->plane[i].n4_hl = bhl - xd->plane[i].subsampling_y;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-08-31 00:01:10 +03:00
|
|
|
static MB_MODE_INFO *set_offsets(AV1_COMMON *const cm, MACROBLOCKD *const xd,
|
2015-08-06 05:00:31 +03:00
|
|
|
BLOCK_SIZE bsize, int mi_row, int mi_col,
|
2016-08-12 04:53:26 +03:00
|
|
|
int bw, int bh, int x_mis, int y_mis, int bwl,
|
|
|
|
int bhl) {
|
2015-08-06 05:00:31 +03:00
|
|
|
const int offset = mi_row * cm->mi_stride + mi_col;
|
|
|
|
int x, y;
|
|
|
|
const TileInfo *const tile = &xd->tile;
|
|
|
|
|
|
|
|
xd->mi = cm->mi_grid_visible + offset;
|
|
|
|
xd->mi[0] = &cm->mi[offset];
|
|
|
|
// TODO(slavarnway): Generate sb_type based on bwl and bhl, instead of
|
|
|
|
// passing bsize from decode_partition().
|
|
|
|
xd->mi[0]->mbmi.sb_type = bsize;
|
|
|
|
for (y = 0; y < y_mis; ++y)
|
|
|
|
for (x = !y; x < x_mis; ++x) {
|
|
|
|
xd->mi[y * cm->mi_stride + x] = xd->mi[0];
|
|
|
|
}
|
|
|
|
|
|
|
|
set_plane_n4(xd, bw, bh, bwl, bhl);
|
|
|
|
|
|
|
|
set_skip_context(xd, mi_row, mi_col);
|
|
|
|
|
2015-11-02 23:05:47 +03:00
|
|
|
#if CONFIG_VAR_TX
|
|
|
|
xd->max_tx_size = max_txsize_lookup[bsize];
|
|
|
|
#endif
|
|
|
|
|
2015-08-06 05:00:31 +03:00
|
|
|
// Distance of Mb to the various image edges. These are specified to 8th pel
|
|
|
|
// as they are always compared to values that are in 1/8th pel units
|
|
|
|
set_mi_row_col(xd, tile, mi_row, bh, mi_col, bw, cm->mi_rows, cm->mi_cols);
|
|
|
|
|
2016-08-31 00:01:10 +03:00
|
|
|
av1_setup_dst_planes(xd->plane, get_frame_new_buffer(cm), mi_row, mi_col);
|
2015-08-06 05:00:31 +03:00
|
|
|
return &xd->mi[0]->mbmi;
|
|
|
|
}
|
|
|
|
|
2015-11-20 03:51:16 +03:00
|
|
|
#if CONFIG_SUPERTX
|
2016-08-31 00:01:10 +03:00
|
|
|
static MB_MODE_INFO *set_offsets_extend(AV1_COMMON *const cm,
|
2015-11-20 03:51:16 +03:00
|
|
|
MACROBLOCKD *const xd,
|
|
|
|
const TileInfo *const tile,
|
2016-08-12 04:53:26 +03:00
|
|
|
BLOCK_SIZE bsize_pred, int mi_row_pred,
|
|
|
|
int mi_col_pred, int mi_row_ori,
|
|
|
|
int mi_col_ori) {
|
2015-11-20 03:51:16 +03:00
|
|
|
// Used in supertx
|
|
|
|
// (mi_row_ori, mi_col_ori): location for mv
|
|
|
|
// (mi_row_pred, mi_col_pred, bsize_pred): region to predict
|
|
|
|
const int bw = num_8x8_blocks_wide_lookup[bsize_pred];
|
|
|
|
const int bh = num_8x8_blocks_high_lookup[bsize_pred];
|
|
|
|
const int offset = mi_row_ori * cm->mi_stride + mi_col_ori;
|
|
|
|
const int bwl = b_width_log2_lookup[bsize_pred];
|
|
|
|
const int bhl = b_height_log2_lookup[bsize_pred];
|
|
|
|
xd->mi = cm->mi_grid_visible + offset;
|
|
|
|
xd->mi[0] = cm->mi + offset;
|
2016-08-12 04:53:26 +03:00
|
|
|
set_mi_row_col(xd, tile, mi_row_pred, bh, mi_col_pred, bw, cm->mi_rows,
|
|
|
|
cm->mi_cols);
|
2015-11-20 03:51:16 +03:00
|
|
|
|
2016-08-12 04:53:26 +03:00
|
|
|
xd->up_available = (mi_row_ori > tile->mi_row_start);
|
|
|
|
xd->left_available = (mi_col_ori > tile->mi_col_start);
|
2015-11-20 03:51:16 +03:00
|
|
|
|
|
|
|
set_plane_n4(xd, bw, bh, bwl, bhl);
|
|
|
|
|
|
|
|
return &xd->mi[0]->mbmi;
|
|
|
|
}
|
|
|
|
|
2016-08-31 00:01:10 +03:00
|
|
|
static MB_MODE_INFO *set_mb_offsets(AV1_COMMON *const cm, MACROBLOCKD *const xd,
|
|
|
|
BLOCK_SIZE bsize, int mi_row, int mi_col,
|
|
|
|
int bw, int bh, int x_mis, int y_mis) {
|
2015-11-20 03:51:16 +03:00
|
|
|
const int offset = mi_row * cm->mi_stride + mi_col;
|
|
|
|
const TileInfo *const tile = &xd->tile;
|
|
|
|
int x, y;
|
|
|
|
|
|
|
|
xd->mi = cm->mi_grid_visible + offset;
|
|
|
|
xd->mi[0] = cm->mi + offset;
|
|
|
|
xd->mi[0]->mbmi.sb_type = bsize;
|
|
|
|
for (y = 0; y < y_mis; ++y)
|
2016-08-12 04:53:26 +03:00
|
|
|
for (x = !y; x < x_mis; ++x) xd->mi[y * cm->mi_stride + x] = xd->mi[0];
|
2015-11-20 03:51:16 +03:00
|
|
|
|
|
|
|
set_mi_row_col(xd, tile, mi_row, bh, mi_col, bw, cm->mi_rows, cm->mi_cols);
|
|
|
|
return &xd->mi[0]->mbmi;
|
|
|
|
}
|
|
|
|
|
2016-08-31 00:01:10 +03:00
|
|
|
static void set_offsets_topblock(AV1_COMMON *const cm, MACROBLOCKD *const xd,
|
2016-08-12 04:53:26 +03:00
|
|
|
const TileInfo *const tile, BLOCK_SIZE bsize,
|
|
|
|
int mi_row, int mi_col) {
|
2015-11-20 03:51:16 +03:00
|
|
|
const int bw = num_8x8_blocks_wide_lookup[bsize];
|
|
|
|
const int bh = num_8x8_blocks_high_lookup[bsize];
|
|
|
|
const int offset = mi_row * cm->mi_stride + mi_col;
|
|
|
|
const int bwl = b_width_log2_lookup[bsize];
|
|
|
|
const int bhl = b_height_log2_lookup[bsize];
|
|
|
|
|
|
|
|
xd->mi = cm->mi_grid_visible + offset;
|
|
|
|
xd->mi[0] = cm->mi + offset;
|
|
|
|
|
|
|
|
set_plane_n4(xd, bw, bh, bwl, bhl);
|
|
|
|
|
|
|
|
set_mi_row_col(xd, tile, mi_row, bh, mi_col, bw, cm->mi_rows, cm->mi_cols);
|
|
|
|
|
2016-08-31 00:01:10 +03:00
|
|
|
av1_setup_dst_planes(xd->plane, get_frame_new_buffer(cm), mi_row, mi_col);
|
2015-11-20 03:51:16 +03:00
|
|
|
}
|
|
|
|
|
2016-08-31 00:01:10 +03:00
|
|
|
static void set_param_topblock(AV1_COMMON *const cm, MACROBLOCKD *const xd,
|
2015-11-20 03:51:16 +03:00
|
|
|
BLOCK_SIZE bsize, int mi_row, int mi_col,
|
2016-03-01 03:08:07 +03:00
|
|
|
int txfm, int skip) {
|
2015-11-20 03:51:16 +03:00
|
|
|
const int bw = num_8x8_blocks_wide_lookup[bsize];
|
|
|
|
const int bh = num_8x8_blocks_high_lookup[bsize];
|
2016-08-31 00:01:10 +03:00
|
|
|
const int x_mis = AOMMIN(bw, cm->mi_cols - mi_col);
|
|
|
|
const int y_mis = AOMMIN(bh, cm->mi_rows - mi_row);
|
2015-11-20 03:51:16 +03:00
|
|
|
const int offset = mi_row * cm->mi_stride + mi_col;
|
|
|
|
int x, y;
|
|
|
|
|
|
|
|
xd->mi = cm->mi_grid_visible + offset;
|
|
|
|
xd->mi[0] = cm->mi + offset;
|
|
|
|
|
|
|
|
for (y = 0; y < y_mis; ++y)
|
|
|
|
for (x = 0; x < x_mis; ++x) {
|
|
|
|
xd->mi[y * cm->mi_stride + x]->mbmi.skip = skip;
|
|
|
|
xd->mi[y * cm->mi_stride + x]->mbmi.tx_type = txfm;
|
|
|
|
}
|
2016-01-07 18:23:08 +03:00
|
|
|
#if CONFIG_VAR_TX
|
|
|
|
xd->above_txfm_context = cm->above_txfm_context + mi_col;
|
2016-03-24 14:20:25 +03:00
|
|
|
xd->left_txfm_context =
|
2016-08-12 04:53:26 +03:00
|
|
|
xd->left_txfm_context_buffer + (mi_row & MAX_MIB_MASK);
|
2016-08-12 02:42:08 +03:00
|
|
|
set_txfm_ctxs(xd->mi[0]->mbmi.tx_size, bw, bh, xd);
|
2016-01-07 18:23:08 +03:00
|
|
|
#endif
|
2015-11-20 03:51:16 +03:00
|
|
|
}
|
|
|
|
|
2016-08-31 00:01:10 +03:00
|
|
|
static void set_ref(AV1_COMMON *const cm, MACROBLOCKD *const xd, int idx,
|
2016-08-12 04:53:26 +03:00
|
|
|
int mi_row, int mi_col) {
|
2015-11-20 03:51:16 +03:00
|
|
|
MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
|
|
|
|
RefBuffer *ref_buffer = &cm->frame_refs[mbmi->ref_frame[idx] - LAST_FRAME];
|
|
|
|
xd->block_refs[idx] = ref_buffer;
|
2016-08-31 00:01:10 +03:00
|
|
|
if (!av1_is_valid_scale(&ref_buffer->sf))
|
|
|
|
aom_internal_error(&cm->error, AOM_CODEC_UNSUP_BITSTREAM,
|
2015-11-20 03:51:16 +03:00
|
|
|
"Invalid scale factors");
|
2016-08-31 00:01:10 +03:00
|
|
|
av1_setup_pre_planes(xd, idx, ref_buffer->buf, mi_row, mi_col,
|
|
|
|
&ref_buffer->sf);
|
2015-11-20 03:51:16 +03:00
|
|
|
xd->corrupted |= ref_buffer->buf->corrupted;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void dec_predict_b_extend(
|
2016-08-31 00:01:10 +03:00
|
|
|
AV1Decoder *const pbi, MACROBLOCKD *const xd, const TileInfo *const tile,
|
2016-08-12 04:53:26 +03:00
|
|
|
int block, int mi_row_ori, int mi_col_ori, int mi_row_pred, int mi_col_pred,
|
|
|
|
int mi_row_top, int mi_col_top, uint8_t *dst_buf[3], int dst_stride[3],
|
|
|
|
BLOCK_SIZE bsize_top, BLOCK_SIZE bsize_pred, int b_sub8x8, int bextend) {
|
2015-11-20 03:51:16 +03:00
|
|
|
// Used in supertx
|
|
|
|
// (mi_row_ori, mi_col_ori): location for mv
|
|
|
|
// (mi_row_pred, mi_col_pred, bsize_pred): region to predict
|
|
|
|
// (mi_row_top, mi_col_top, bsize_top): region of the top partition size
|
|
|
|
// block: sub location of sub8x8 blocks
|
|
|
|
// b_sub8x8: 1: ori is sub8x8; 0: ori is not sub8x8
|
|
|
|
// bextend: 1: region to predict is an extension of ori; 0: not
|
|
|
|
int r = (mi_row_pred - mi_row_top) * MI_SIZE;
|
|
|
|
int c = (mi_col_pred - mi_col_top) * MI_SIZE;
|
|
|
|
const int mi_width_top = num_8x8_blocks_wide_lookup[bsize_top];
|
|
|
|
const int mi_height_top = num_8x8_blocks_high_lookup[bsize_top];
|
|
|
|
MB_MODE_INFO *mbmi;
|
2016-08-31 00:01:10 +03:00
|
|
|
AV1_COMMON *const cm = &pbi->common;
|
2015-11-20 03:51:16 +03:00
|
|
|
|
|
|
|
if (mi_row_pred < mi_row_top || mi_col_pred < mi_col_top ||
|
|
|
|
mi_row_pred >= mi_row_top + mi_height_top ||
|
2016-08-12 04:53:26 +03:00
|
|
|
mi_col_pred >= mi_col_top + mi_width_top || mi_row_pred >= cm->mi_rows ||
|
|
|
|
mi_col_pred >= cm->mi_cols)
|
2015-11-20 03:51:16 +03:00
|
|
|
return;
|
|
|
|
|
2016-08-12 04:53:26 +03:00
|
|
|
mbmi = set_offsets_extend(cm, xd, tile, bsize_pred, mi_row_pred, mi_col_pred,
|
2015-11-20 03:51:16 +03:00
|
|
|
mi_row_ori, mi_col_ori);
|
|
|
|
set_ref(cm, xd, 0, mi_row_pred, mi_col_pred);
|
|
|
|
if (has_second_ref(&xd->mi[0]->mbmi))
|
|
|
|
set_ref(cm, xd, 1, mi_row_pred, mi_col_pred);
|
|
|
|
|
|
|
|
if (!bextend) {
|
|
|
|
mbmi->tx_size = b_width_log2_lookup[bsize_top];
|
|
|
|
}
|
|
|
|
|
|
|
|
xd->plane[0].dst.stride = dst_stride[0];
|
|
|
|
xd->plane[1].dst.stride = dst_stride[1];
|
|
|
|
xd->plane[2].dst.stride = dst_stride[2];
|
|
|
|
xd->plane[0].dst.buf = dst_buf[0] +
|
|
|
|
(r >> xd->plane[0].subsampling_y) * dst_stride[0] +
|
|
|
|
(c >> xd->plane[0].subsampling_x);
|
|
|
|
xd->plane[1].dst.buf = dst_buf[1] +
|
|
|
|
(r >> xd->plane[1].subsampling_y) * dst_stride[1] +
|
|
|
|
(c >> xd->plane[1].subsampling_x);
|
|
|
|
xd->plane[2].dst.buf = dst_buf[2] +
|
|
|
|
(r >> xd->plane[2].subsampling_y) * dst_stride[2] +
|
|
|
|
(c >> xd->plane[2].subsampling_x);
|
|
|
|
|
|
|
|
if (!b_sub8x8)
|
2016-08-31 00:01:10 +03:00
|
|
|
av1_build_inter_predictors_sb_extend(xd,
|
2016-03-01 03:08:07 +03:00
|
|
|
#if CONFIG_EXT_INTER
|
2016-08-31 00:01:10 +03:00
|
|
|
mi_row_ori, mi_col_ori,
|
2016-03-01 03:08:07 +03:00
|
|
|
#endif // CONFIG_EXT_INTER
|
2016-08-31 00:01:10 +03:00
|
|
|
mi_row_pred, mi_col_pred, bsize_pred);
|
2015-11-20 03:51:16 +03:00
|
|
|
else
|
2016-08-31 00:01:10 +03:00
|
|
|
av1_build_inter_predictors_sb_sub8x8_extend(xd,
|
2016-03-01 03:08:07 +03:00
|
|
|
#if CONFIG_EXT_INTER
|
2016-08-31 00:01:10 +03:00
|
|
|
mi_row_ori, mi_col_ori,
|
2016-03-01 03:08:07 +03:00
|
|
|
#endif // CONFIG_EXT_INTER
|
2016-08-31 00:01:10 +03:00
|
|
|
mi_row_pred, mi_col_pred,
|
|
|
|
bsize_pred, block);
|
2015-11-20 03:51:16 +03:00
|
|
|
}
|
|
|
|
|
2016-08-31 00:01:10 +03:00
|
|
|
static void dec_extend_dir(AV1Decoder *const pbi, MACROBLOCKD *const xd,
|
2015-11-20 03:51:16 +03:00
|
|
|
const TileInfo *const tile, int block,
|
2016-08-12 04:53:26 +03:00
|
|
|
BLOCK_SIZE bsize, BLOCK_SIZE top_bsize, int mi_row,
|
|
|
|
int mi_col, int mi_row_top, int mi_col_top,
|
|
|
|
uint8_t *dst_buf[3], int dst_stride[3], int dir) {
|
2015-11-20 03:51:16 +03:00
|
|
|
// dir: 0-lower, 1-upper, 2-left, 3-right
|
|
|
|
// 4-lowerleft, 5-upperleft, 6-lowerright, 7-upperright
|
|
|
|
const int mi_width = num_8x8_blocks_wide_lookup[bsize];
|
|
|
|
const int mi_height = num_8x8_blocks_high_lookup[bsize];
|
|
|
|
int xss = xd->plane[1].subsampling_x;
|
|
|
|
int yss = xd->plane[1].subsampling_y;
|
|
|
|
int b_sub8x8 = (bsize < BLOCK_8X8) ? 1 : 0;
|
|
|
|
BLOCK_SIZE extend_bsize;
|
|
|
|
int unit, mi_row_pred, mi_col_pred;
|
|
|
|
|
|
|
|
if (dir == 0 || dir == 1) {
|
2016-08-12 04:53:26 +03:00
|
|
|
extend_bsize = (mi_width == 1 || bsize < BLOCK_8X8 || xss < yss)
|
|
|
|
? BLOCK_8X8
|
|
|
|
: BLOCK_16X8;
|
2015-11-20 03:51:16 +03:00
|
|
|
unit = num_8x8_blocks_wide_lookup[extend_bsize];
|
|
|
|
mi_row_pred = mi_row + ((dir == 0) ? mi_height : -1);
|
|
|
|
mi_col_pred = mi_col;
|
|
|
|
|
2016-08-12 04:53:26 +03:00
|
|
|
dec_predict_b_extend(pbi, xd, tile, block, mi_row, mi_col, mi_row_pred,
|
|
|
|
mi_col_pred, mi_row_top, mi_col_top, dst_buf,
|
|
|
|
dst_stride, top_bsize, extend_bsize, b_sub8x8, 1);
|
2015-11-20 03:51:16 +03:00
|
|
|
|
|
|
|
if (mi_width > unit) {
|
|
|
|
int i;
|
|
|
|
assert(!b_sub8x8);
|
2016-08-12 04:53:26 +03:00
|
|
|
for (i = 0; i < mi_width / unit - 1; i++) {
|
2015-11-20 03:51:16 +03:00
|
|
|
mi_col_pred += unit;
|
2016-08-12 04:53:26 +03:00
|
|
|
dec_predict_b_extend(pbi, xd, tile, block, mi_row, mi_col, mi_row_pred,
|
|
|
|
mi_col_pred, mi_row_top, mi_col_top, dst_buf,
|
|
|
|
dst_stride, top_bsize, extend_bsize, b_sub8x8, 1);
|
2015-11-20 03:51:16 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
} else if (dir == 2 || dir == 3) {
|
2016-08-12 04:53:26 +03:00
|
|
|
extend_bsize = (mi_height == 1 || bsize < BLOCK_8X8 || yss < xss)
|
|
|
|
? BLOCK_8X8
|
|
|
|
: BLOCK_8X16;
|
2015-11-20 03:51:16 +03:00
|
|
|
unit = num_8x8_blocks_high_lookup[extend_bsize];
|
|
|
|
mi_row_pred = mi_row;
|
|
|
|
mi_col_pred = mi_col + ((dir == 3) ? mi_width : -1);
|
|
|
|
|
2016-08-12 04:53:26 +03:00
|
|
|
dec_predict_b_extend(pbi, xd, tile, block, mi_row, mi_col, mi_row_pred,
|
|
|
|
mi_col_pred, mi_row_top, mi_col_top, dst_buf,
|
|
|
|
dst_stride, top_bsize, extend_bsize, b_sub8x8, 1);
|
2015-11-20 03:51:16 +03:00
|
|
|
|
|
|
|
if (mi_height > unit) {
|
|
|
|
int i;
|
2016-08-12 04:53:26 +03:00
|
|
|
for (i = 0; i < mi_height / unit - 1; i++) {
|
2015-11-20 03:51:16 +03:00
|
|
|
mi_row_pred += unit;
|
2016-08-12 04:53:26 +03:00
|
|
|
dec_predict_b_extend(pbi, xd, tile, block, mi_row, mi_col, mi_row_pred,
|
|
|
|
mi_col_pred, mi_row_top, mi_col_top, dst_buf,
|
|
|
|
dst_stride, top_bsize, extend_bsize, b_sub8x8, 1);
|
2015-11-20 03:51:16 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
extend_bsize = BLOCK_8X8;
|
|
|
|
mi_row_pred = mi_row + ((dir == 4 || dir == 6) ? mi_height : -1);
|
|
|
|
mi_col_pred = mi_col + ((dir == 6 || dir == 7) ? mi_width : -1);
|
2016-08-12 04:53:26 +03:00
|
|
|
dec_predict_b_extend(pbi, xd, tile, block, mi_row, mi_col, mi_row_pred,
|
|
|
|
mi_col_pred, mi_row_top, mi_col_top, dst_buf,
|
|
|
|
dst_stride, top_bsize, extend_bsize, b_sub8x8, 1);
|
2015-11-20 03:51:16 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-08-31 00:01:10 +03:00
|
|
|
static void dec_extend_all(AV1Decoder *const pbi, MACROBLOCKD *const xd,
|
2015-11-20 03:51:16 +03:00
|
|
|
const TileInfo *const tile, int block,
|
2016-08-12 04:53:26 +03:00
|
|
|
BLOCK_SIZE bsize, BLOCK_SIZE top_bsize, int mi_row,
|
|
|
|
int mi_col, int mi_row_top, int mi_col_top,
|
|
|
|
uint8_t *dst_buf[3], int dst_stride[3]) {
|
2015-11-20 03:51:16 +03:00
|
|
|
dec_extend_dir(pbi, xd, tile, block, bsize, top_bsize, mi_row, mi_col,
|
|
|
|
mi_row_top, mi_col_top, dst_buf, dst_stride, 0);
|
|
|
|
dec_extend_dir(pbi, xd, tile, block, bsize, top_bsize, mi_row, mi_col,
|
|
|
|
mi_row_top, mi_col_top, dst_buf, dst_stride, 1);
|
|
|
|
dec_extend_dir(pbi, xd, tile, block, bsize, top_bsize, mi_row, mi_col,
|
|
|
|
mi_row_top, mi_col_top, dst_buf, dst_stride, 2);
|
|
|
|
dec_extend_dir(pbi, xd, tile, block, bsize, top_bsize, mi_row, mi_col,
|
|
|
|
mi_row_top, mi_col_top, dst_buf, dst_stride, 3);
|
|
|
|
dec_extend_dir(pbi, xd, tile, block, bsize, top_bsize, mi_row, mi_col,
|
|
|
|
mi_row_top, mi_col_top, dst_buf, dst_stride, 4);
|
|
|
|
dec_extend_dir(pbi, xd, tile, block, bsize, top_bsize, mi_row, mi_col,
|
|
|
|
mi_row_top, mi_col_top, dst_buf, dst_stride, 5);
|
|
|
|
dec_extend_dir(pbi, xd, tile, block, bsize, top_bsize, mi_row, mi_col,
|
|
|
|
mi_row_top, mi_col_top, dst_buf, dst_stride, 6);
|
|
|
|
dec_extend_dir(pbi, xd, tile, block, bsize, top_bsize, mi_row, mi_col,
|
|
|
|
mi_row_top, mi_col_top, dst_buf, dst_stride, 7);
|
|
|
|
}
|
|
|
|
|
2016-08-31 00:01:10 +03:00
|
|
|
static void dec_predict_sb_complex(AV1Decoder *const pbi, MACROBLOCKD *const xd,
|
2016-08-12 04:53:26 +03:00
|
|
|
const TileInfo *const tile, int mi_row,
|
|
|
|
int mi_col, int mi_row_top, int mi_col_top,
|
2015-11-20 03:51:16 +03:00
|
|
|
BLOCK_SIZE bsize, BLOCK_SIZE top_bsize,
|
|
|
|
uint8_t *dst_buf[3], int dst_stride[3]) {
|
2016-08-31 00:01:10 +03:00
|
|
|
const AV1_COMMON *const cm = &pbi->common;
|
2016-04-04 13:37:29 +03:00
|
|
|
const int hbs = num_8x8_blocks_wide_lookup[bsize] / 2;
|
|
|
|
const PARTITION_TYPE partition = get_partition(cm, mi_row, mi_col, bsize);
|
|
|
|
const BLOCK_SIZE subsize = get_subsize(bsize, partition);
|
2016-03-17 19:50:28 +03:00
|
|
|
#if CONFIG_EXT_PARTITION_TYPES
|
2016-04-04 13:37:29 +03:00
|
|
|
const BLOCK_SIZE bsize2 = get_subsize(bsize, PARTITION_SPLIT);
|
2016-03-17 19:50:28 +03:00
|
|
|
#endif
|
2016-04-04 13:37:29 +03:00
|
|
|
int i;
|
|
|
|
const int mi_offset = mi_row * cm->mi_stride + mi_col;
|
2015-11-20 03:51:16 +03:00
|
|
|
uint8_t *dst_buf1[3], *dst_buf2[3], *dst_buf3[3];
|
|
|
|
|
2016-08-12 04:53:26 +03:00
|
|
|
DECLARE_ALIGNED(16, uint8_t, tmp_buf1[MAX_MB_PLANE * MAX_TX_SQUARE * 2]);
|
|
|
|
DECLARE_ALIGNED(16, uint8_t, tmp_buf2[MAX_MB_PLANE * MAX_TX_SQUARE * 2]);
|
|
|
|
DECLARE_ALIGNED(16, uint8_t, tmp_buf3[MAX_MB_PLANE * MAX_TX_SQUARE * 2]);
|
|
|
|
int dst_stride1[3] = { MAX_TX_SIZE, MAX_TX_SIZE, MAX_TX_SIZE };
|
|
|
|
int dst_stride2[3] = { MAX_TX_SIZE, MAX_TX_SIZE, MAX_TX_SIZE };
|
|
|
|
int dst_stride3[3] = { MAX_TX_SIZE, MAX_TX_SIZE, MAX_TX_SIZE };
|
2015-11-20 03:51:16 +03:00
|
|
|
|
2016-08-31 00:01:10 +03:00
|
|
|
#if CONFIG_AOM_HIGHBITDEPTH
|
2015-11-20 03:51:16 +03:00
|
|
|
if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
|
|
|
|
int len = sizeof(uint16_t);
|
|
|
|
dst_buf1[0] = CONVERT_TO_BYTEPTR(tmp_buf1);
|
2016-03-07 16:46:39 +03:00
|
|
|
dst_buf1[1] = CONVERT_TO_BYTEPTR(tmp_buf1 + MAX_TX_SQUARE * len);
|
|
|
|
dst_buf1[2] = CONVERT_TO_BYTEPTR(tmp_buf1 + 2 * MAX_TX_SQUARE * len);
|
2015-11-20 03:51:16 +03:00
|
|
|
dst_buf2[0] = CONVERT_TO_BYTEPTR(tmp_buf2);
|
2016-03-07 16:46:39 +03:00
|
|
|
dst_buf2[1] = CONVERT_TO_BYTEPTR(tmp_buf2 + MAX_TX_SQUARE * len);
|
|
|
|
dst_buf2[2] = CONVERT_TO_BYTEPTR(tmp_buf2 + 2 * MAX_TX_SQUARE * len);
|
2015-11-20 03:51:16 +03:00
|
|
|
dst_buf3[0] = CONVERT_TO_BYTEPTR(tmp_buf3);
|
2016-03-07 16:46:39 +03:00
|
|
|
dst_buf3[1] = CONVERT_TO_BYTEPTR(tmp_buf3 + MAX_TX_SQUARE * len);
|
|
|
|
dst_buf3[2] = CONVERT_TO_BYTEPTR(tmp_buf3 + 2 * MAX_TX_SQUARE * len);
|
2015-11-20 03:51:16 +03:00
|
|
|
} else {
|
|
|
|
#endif
|
|
|
|
dst_buf1[0] = tmp_buf1;
|
2016-03-07 16:46:39 +03:00
|
|
|
dst_buf1[1] = tmp_buf1 + MAX_TX_SQUARE;
|
|
|
|
dst_buf1[2] = tmp_buf1 + 2 * MAX_TX_SQUARE;
|
2015-11-20 03:51:16 +03:00
|
|
|
dst_buf2[0] = tmp_buf2;
|
2016-03-07 16:46:39 +03:00
|
|
|
dst_buf2[1] = tmp_buf2 + MAX_TX_SQUARE;
|
|
|
|
dst_buf2[2] = tmp_buf2 + 2 * MAX_TX_SQUARE;
|
2015-11-20 03:51:16 +03:00
|
|
|
dst_buf3[0] = tmp_buf3;
|
2016-03-07 16:46:39 +03:00
|
|
|
dst_buf3[1] = tmp_buf3 + MAX_TX_SQUARE;
|
|
|
|
dst_buf3[2] = tmp_buf3 + 2 * MAX_TX_SQUARE;
|
2016-08-31 00:01:10 +03:00
|
|
|
#if CONFIG_AOM_HIGHBITDEPTH
|
2015-11-20 03:51:16 +03:00
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2016-08-12 04:53:26 +03:00
|
|
|
if (mi_row >= cm->mi_rows || mi_col >= cm->mi_cols) return;
|
2015-11-20 03:51:16 +03:00
|
|
|
|
2016-04-04 13:37:29 +03:00
|
|
|
xd->mi = cm->mi_grid_visible + mi_offset;
|
|
|
|
xd->mi[0] = cm->mi + mi_offset;
|
2015-11-20 03:51:16 +03:00
|
|
|
|
|
|
|
for (i = 0; i < MAX_MB_PLANE; i++) {
|
|
|
|
xd->plane[i].dst.buf = dst_buf[i];
|
|
|
|
xd->plane[i].dst.stride = dst_stride[i];
|
|
|
|
}
|
|
|
|
|
|
|
|
switch (partition) {
|
|
|
|
case PARTITION_NONE:
|
|
|
|
assert(bsize < top_bsize);
|
|
|
|
dec_predict_b_extend(pbi, xd, tile, 0, mi_row, mi_col, mi_row, mi_col,
|
|
|
|
mi_row_top, mi_col_top, dst_buf, dst_stride,
|
|
|
|
top_bsize, bsize, 0, 0);
|
|
|
|
dec_extend_all(pbi, xd, tile, 0, bsize, top_bsize, mi_row, mi_col,
|
|
|
|
mi_row_top, mi_col_top, dst_buf, dst_stride);
|
|
|
|
break;
|
|
|
|
case PARTITION_HORZ:
|
|
|
|
if (bsize == BLOCK_8X8) {
|
|
|
|
// For sub8x8, predict in 8x8 unit
|
|
|
|
// First half
|
|
|
|
dec_predict_b_extend(pbi, xd, tile, 0, mi_row, mi_col, mi_row, mi_col,
|
|
|
|
mi_row_top, mi_col_top, dst_buf, dst_stride,
|
|
|
|
top_bsize, BLOCK_8X8, 1, 0);
|
|
|
|
if (bsize < top_bsize)
|
|
|
|
dec_extend_all(pbi, xd, tile, 0, subsize, top_bsize, mi_row, mi_col,
|
|
|
|
mi_row_top, mi_col_top, dst_buf, dst_stride);
|
|
|
|
|
|
|
|
// Second half
|
|
|
|
dec_predict_b_extend(pbi, xd, tile, 2, mi_row, mi_col, mi_row, mi_col,
|
|
|
|
mi_row_top, mi_col_top, dst_buf1, dst_stride1,
|
|
|
|
top_bsize, BLOCK_8X8, 1, 1);
|
|
|
|
if (bsize < top_bsize)
|
|
|
|
dec_extend_all(pbi, xd, tile, 2, subsize, top_bsize, mi_row, mi_col,
|
|
|
|
mi_row_top, mi_col_top, dst_buf1, dst_stride1);
|
|
|
|
|
|
|
|
// weighted average to smooth the boundary
|
|
|
|
xd->plane[0].dst.buf = dst_buf[0];
|
|
|
|
xd->plane[0].dst.stride = dst_stride[0];
|
2016-08-31 00:01:10 +03:00
|
|
|
av1_build_masked_inter_predictor_complex(
|
2016-08-12 04:53:26 +03:00
|
|
|
xd, dst_buf[0], dst_stride[0], dst_buf1[0], dst_stride1[0], mi_row,
|
|
|
|
mi_col, mi_row_top, mi_col_top, bsize, top_bsize, PARTITION_HORZ,
|
|
|
|
0);
|
2015-11-20 03:51:16 +03:00
|
|
|
} else {
|
|
|
|
// First half
|
|
|
|
dec_predict_b_extend(pbi, xd, tile, 0, mi_row, mi_col, mi_row, mi_col,
|
|
|
|
mi_row_top, mi_col_top, dst_buf, dst_stride,
|
|
|
|
top_bsize, subsize, 0, 0);
|
|
|
|
if (bsize < top_bsize)
|
|
|
|
dec_extend_all(pbi, xd, tile, 0, subsize, top_bsize, mi_row, mi_col,
|
|
|
|
mi_row_top, mi_col_top, dst_buf, dst_stride);
|
|
|
|
else
|
|
|
|
dec_extend_dir(pbi, xd, tile, 0, subsize, top_bsize, mi_row, mi_col,
|
|
|
|
mi_row_top, mi_col_top, dst_buf, dst_stride, 0);
|
|
|
|
|
|
|
|
if (mi_row + hbs < cm->mi_rows) {
|
|
|
|
// Second half
|
|
|
|
dec_predict_b_extend(pbi, xd, tile, 0, mi_row + hbs, mi_col,
|
2016-08-12 04:53:26 +03:00
|
|
|
mi_row + hbs, mi_col, mi_row_top, mi_col_top,
|
|
|
|
dst_buf1, dst_stride1, top_bsize, subsize, 0, 0);
|
2015-11-20 03:51:16 +03:00
|
|
|
if (bsize < top_bsize)
|
2016-08-12 04:53:26 +03:00
|
|
|
dec_extend_all(pbi, xd, tile, 0, subsize, top_bsize, mi_row + hbs,
|
|
|
|
mi_col, mi_row_top, mi_col_top, dst_buf1,
|
|
|
|
dst_stride1);
|
2015-11-20 03:51:16 +03:00
|
|
|
else
|
2016-08-12 04:53:26 +03:00
|
|
|
dec_extend_dir(pbi, xd, tile, 0, subsize, top_bsize, mi_row + hbs,
|
|
|
|
mi_col, mi_row_top, mi_col_top, dst_buf1,
|
|
|
|
dst_stride1, 1);
|
2015-11-20 03:51:16 +03:00
|
|
|
|
|
|
|
// weighted average to smooth the boundary
|
|
|
|
for (i = 0; i < MAX_MB_PLANE; i++) {
|
|
|
|
xd->plane[i].dst.buf = dst_buf[i];
|
|
|
|
xd->plane[i].dst.stride = dst_stride[i];
|
2016-08-31 00:01:10 +03:00
|
|
|
av1_build_masked_inter_predictor_complex(
|
2015-11-20 03:51:16 +03:00
|
|
|
xd, dst_buf[i], dst_stride[i], dst_buf1[i], dst_stride1[i],
|
2016-08-12 04:53:26 +03:00
|
|
|
mi_row, mi_col, mi_row_top, mi_col_top, bsize, top_bsize,
|
|
|
|
PARTITION_HORZ, i);
|
2015-11-20 03:51:16 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case PARTITION_VERT:
|
|
|
|
if (bsize == BLOCK_8X8) {
|
|
|
|
// First half
|
|
|
|
dec_predict_b_extend(pbi, xd, tile, 0, mi_row, mi_col, mi_row, mi_col,
|
|
|
|
mi_row_top, mi_col_top, dst_buf, dst_stride,
|
|
|
|
top_bsize, BLOCK_8X8, 1, 0);
|
|
|
|
if (bsize < top_bsize)
|
|
|
|
dec_extend_all(pbi, xd, tile, 0, subsize, top_bsize, mi_row, mi_col,
|
|
|
|
mi_row_top, mi_col_top, dst_buf, dst_stride);
|
|
|
|
|
|
|
|
// Second half
|
|
|
|
dec_predict_b_extend(pbi, xd, tile, 1, mi_row, mi_col, mi_row, mi_col,
|
|
|
|
mi_row_top, mi_col_top, dst_buf1, dst_stride1,
|
|
|
|
top_bsize, BLOCK_8X8, 1, 1);
|
|
|
|
if (bsize < top_bsize)
|
|
|
|
dec_extend_all(pbi, xd, tile, 1, subsize, top_bsize, mi_row, mi_col,
|
|
|
|
mi_row_top, mi_col_top, dst_buf1, dst_stride1);
|
|
|
|
|
|
|
|
// Smooth
|
|
|
|
xd->plane[0].dst.buf = dst_buf[0];
|
|
|
|
xd->plane[0].dst.stride = dst_stride[0];
|
2016-08-31 00:01:10 +03:00
|
|
|
av1_build_masked_inter_predictor_complex(
|
2016-08-12 04:53:26 +03:00
|
|
|
xd, dst_buf[0], dst_stride[0], dst_buf1[0], dst_stride1[0], mi_row,
|
|
|
|
mi_col, mi_row_top, mi_col_top, bsize, top_bsize, PARTITION_VERT,
|
|
|
|
0);
|
2015-11-20 03:51:16 +03:00
|
|
|
} else {
|
|
|
|
// First half
|
|
|
|
dec_predict_b_extend(pbi, xd, tile, 0, mi_row, mi_col, mi_row, mi_col,
|
|
|
|
mi_row_top, mi_col_top, dst_buf, dst_stride,
|
|
|
|
top_bsize, subsize, 0, 0);
|
|
|
|
if (bsize < top_bsize)
|
|
|
|
dec_extend_all(pbi, xd, tile, 0, subsize, top_bsize, mi_row, mi_col,
|
|
|
|
mi_row_top, mi_col_top, dst_buf, dst_stride);
|
|
|
|
else
|
|
|
|
dec_extend_dir(pbi, xd, tile, 0, subsize, top_bsize, mi_row, mi_col,
|
|
|
|
mi_row_top, mi_col_top, dst_buf, dst_stride, 3);
|
|
|
|
|
|
|
|
// Second half
|
|
|
|
if (mi_col + hbs < cm->mi_cols) {
|
2016-08-12 04:53:26 +03:00
|
|
|
dec_predict_b_extend(pbi, xd, tile, 0, mi_row, mi_col + hbs, mi_row,
|
|
|
|
mi_col + hbs, mi_row_top, mi_col_top, dst_buf1,
|
|
|
|
dst_stride1, top_bsize, subsize, 0, 0);
|
2015-11-20 03:51:16 +03:00
|
|
|
if (bsize < top_bsize)
|
2016-08-12 04:53:26 +03:00
|
|
|
dec_extend_all(pbi, xd, tile, 0, subsize, top_bsize, mi_row,
|
|
|
|
mi_col + hbs, mi_row_top, mi_col_top, dst_buf1,
|
|
|
|
dst_stride1);
|
2015-11-20 03:51:16 +03:00
|
|
|
else
|
2016-08-12 04:53:26 +03:00
|
|
|
dec_extend_dir(pbi, xd, tile, 0, subsize, top_bsize, mi_row,
|
|
|
|
mi_col + hbs, mi_row_top, mi_col_top, dst_buf1,
|
|
|
|
dst_stride1, 2);
|
2015-11-20 03:51:16 +03:00
|
|
|
|
|
|
|
// Smooth
|
|
|
|
for (i = 0; i < MAX_MB_PLANE; i++) {
|
|
|
|
xd->plane[i].dst.buf = dst_buf[i];
|
|
|
|
xd->plane[i].dst.stride = dst_stride[i];
|
2016-08-31 00:01:10 +03:00
|
|
|
av1_build_masked_inter_predictor_complex(
|
2015-11-20 03:51:16 +03:00
|
|
|
xd, dst_buf[i], dst_stride[i], dst_buf1[i], dst_stride1[i],
|
2016-08-12 04:53:26 +03:00
|
|
|
mi_row, mi_col, mi_row_top, mi_col_top, bsize, top_bsize,
|
|
|
|
PARTITION_VERT, i);
|
2015-11-20 03:51:16 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case PARTITION_SPLIT:
|
|
|
|
if (bsize == BLOCK_8X8) {
|
|
|
|
dec_predict_b_extend(pbi, xd, tile, 0, mi_row, mi_col, mi_row, mi_col,
|
|
|
|
mi_row_top, mi_col_top, dst_buf, dst_stride,
|
|
|
|
top_bsize, BLOCK_8X8, 1, 0);
|
|
|
|
dec_predict_b_extend(pbi, xd, tile, 1, mi_row, mi_col, mi_row, mi_col,
|
|
|
|
mi_row_top, mi_col_top, dst_buf1, dst_stride1,
|
|
|
|
top_bsize, BLOCK_8X8, 1, 1);
|
|
|
|
dec_predict_b_extend(pbi, xd, tile, 2, mi_row, mi_col, mi_row, mi_col,
|
|
|
|
mi_row_top, mi_col_top, dst_buf2, dst_stride2,
|
|
|
|
top_bsize, BLOCK_8X8, 1, 1);
|
|
|
|
dec_predict_b_extend(pbi, xd, tile, 3, mi_row, mi_col, mi_row, mi_col,
|
|
|
|
mi_row_top, mi_col_top, dst_buf3, dst_stride3,
|
|
|
|
top_bsize, BLOCK_8X8, 1, 1);
|
|
|
|
if (bsize < top_bsize) {
|
|
|
|
dec_extend_all(pbi, xd, tile, 0, subsize, top_bsize, mi_row, mi_col,
|
|
|
|
mi_row_top, mi_col_top, dst_buf, dst_stride);
|
|
|
|
dec_extend_all(pbi, xd, tile, 1, subsize, top_bsize, mi_row, mi_col,
|
|
|
|
mi_row_top, mi_col_top, dst_buf1, dst_stride1);
|
|
|
|
dec_extend_all(pbi, xd, tile, 2, subsize, top_bsize, mi_row, mi_col,
|
|
|
|
mi_row_top, mi_col_top, dst_buf2, dst_stride2);
|
|
|
|
dec_extend_all(pbi, xd, tile, 3, subsize, top_bsize, mi_row, mi_col,
|
|
|
|
mi_row_top, mi_col_top, dst_buf3, dst_stride3);
|
|
|
|
}
|
|
|
|
} else {
|
2016-08-12 04:53:26 +03:00
|
|
|
dec_predict_sb_complex(pbi, xd, tile, mi_row, mi_col, mi_row_top,
|
|
|
|
mi_col_top, subsize, top_bsize, dst_buf,
|
|
|
|
dst_stride);
|
2015-11-20 03:51:16 +03:00
|
|
|
if (mi_row < cm->mi_rows && mi_col + hbs < cm->mi_cols)
|
|
|
|
dec_predict_sb_complex(pbi, xd, tile, mi_row, mi_col + hbs,
|
|
|
|
mi_row_top, mi_col_top, subsize, top_bsize,
|
|
|
|
dst_buf1, dst_stride1);
|
|
|
|
if (mi_row + hbs < cm->mi_rows && mi_col < cm->mi_cols)
|
|
|
|
dec_predict_sb_complex(pbi, xd, tile, mi_row + hbs, mi_col,
|
|
|
|
mi_row_top, mi_col_top, subsize, top_bsize,
|
|
|
|
dst_buf2, dst_stride2);
|
|
|
|
if (mi_row + hbs < cm->mi_rows && mi_col + hbs < cm->mi_cols)
|
|
|
|
dec_predict_sb_complex(pbi, xd, tile, mi_row + hbs, mi_col + hbs,
|
|
|
|
mi_row_top, mi_col_top, subsize, top_bsize,
|
|
|
|
dst_buf3, dst_stride3);
|
|
|
|
}
|
2016-08-12 04:53:26 +03:00
|
|
|
for (i = 0; i < MAX_MB_PLANE; i++) {
|
|
|
|
if (bsize == BLOCK_8X8 && i != 0)
|
|
|
|
continue; // Skip <4x4 chroma smoothing
|
|
|
|
if (mi_row < cm->mi_rows && mi_col + hbs < cm->mi_cols) {
|
2016-08-31 00:01:10 +03:00
|
|
|
av1_build_masked_inter_predictor_complex(
|
2016-08-12 04:53:26 +03:00
|
|
|
xd, dst_buf[i], dst_stride[i], dst_buf1[i], dst_stride1[i],
|
|
|
|
mi_row, mi_col, mi_row_top, mi_col_top, bsize, top_bsize,
|
|
|
|
PARTITION_VERT, i);
|
|
|
|
if (mi_row + hbs < cm->mi_rows) {
|
2016-08-31 00:01:10 +03:00
|
|
|
av1_build_masked_inter_predictor_complex(
|
2016-08-12 04:53:26 +03:00
|
|
|
xd, dst_buf2[i], dst_stride2[i], dst_buf3[i], dst_stride3[i],
|
|
|
|
mi_row, mi_col, mi_row_top, mi_col_top, bsize, top_bsize,
|
|
|
|
PARTITION_VERT, i);
|
2016-08-31 00:01:10 +03:00
|
|
|
av1_build_masked_inter_predictor_complex(
|
2016-08-12 04:53:26 +03:00
|
|
|
xd, dst_buf[i], dst_stride[i], dst_buf2[i], dst_stride2[i],
|
|
|
|
mi_row, mi_col, mi_row_top, mi_col_top, bsize, top_bsize,
|
|
|
|
PARTITION_HORZ, i);
|
2015-11-20 03:51:16 +03:00
|
|
|
}
|
2016-08-12 04:53:26 +03:00
|
|
|
} else if (mi_row + hbs < cm->mi_rows && mi_col < cm->mi_cols) {
|
2016-08-31 00:01:10 +03:00
|
|
|
av1_build_masked_inter_predictor_complex(
|
2016-08-12 04:53:26 +03:00
|
|
|
xd, dst_buf[i], dst_stride[i], dst_buf2[i], dst_stride2[i],
|
|
|
|
mi_row, mi_col, mi_row_top, mi_col_top, bsize, top_bsize,
|
|
|
|
PARTITION_HORZ, i);
|
2015-11-20 03:51:16 +03:00
|
|
|
}
|
2016-08-12 04:53:26 +03:00
|
|
|
}
|
2015-11-20 03:51:16 +03:00
|
|
|
break;
|
2016-03-17 19:50:28 +03:00
|
|
|
#if CONFIG_EXT_PARTITION_TYPES
|
|
|
|
case PARTITION_HORZ_A:
|
|
|
|
dec_predict_b_extend(pbi, xd, tile, 0, mi_row, mi_col, mi_row, mi_col,
|
|
|
|
mi_row_top, mi_col_top, dst_buf, dst_stride,
|
|
|
|
top_bsize, bsize2, 0, 0);
|
|
|
|
dec_extend_all(pbi, xd, tile, 0, bsize2, top_bsize, mi_row, mi_col,
|
|
|
|
mi_row_top, mi_col_top, dst_buf, dst_stride);
|
|
|
|
|
|
|
|
dec_predict_b_extend(pbi, xd, tile, 0, mi_row, mi_col + hbs, mi_row,
|
2016-08-12 04:53:26 +03:00
|
|
|
mi_col + hbs, mi_row_top, mi_col_top, dst_buf1,
|
|
|
|
dst_stride1, top_bsize, bsize2, 0, 0);
|
2016-03-17 19:50:28 +03:00
|
|
|
dec_extend_all(pbi, xd, tile, 0, bsize2, top_bsize, mi_row, mi_col + hbs,
|
|
|
|
mi_row_top, mi_col_top, dst_buf1, dst_stride1);
|
|
|
|
|
2016-08-12 04:53:26 +03:00
|
|
|
dec_predict_b_extend(pbi, xd, tile, 0, mi_row + hbs, mi_col, mi_row + hbs,
|
|
|
|
mi_col, mi_row_top, mi_col_top, dst_buf2,
|
|
|
|
dst_stride2, top_bsize, subsize, 0, 0);
|
2016-03-17 19:50:28 +03:00
|
|
|
if (bsize < top_bsize)
|
2016-08-12 04:53:26 +03:00
|
|
|
dec_extend_all(pbi, xd, tile, 0, subsize, top_bsize, mi_row + hbs,
|
|
|
|
mi_col, mi_row_top, mi_col_top, dst_buf2, dst_stride2);
|
2016-03-17 19:50:28 +03:00
|
|
|
else
|
2016-08-12 04:53:26 +03:00
|
|
|
dec_extend_dir(pbi, xd, tile, 0, subsize, top_bsize, mi_row + hbs,
|
|
|
|
mi_col, mi_row_top, mi_col_top, dst_buf2, dst_stride2,
|
|
|
|
1);
|
2016-03-17 19:50:28 +03:00
|
|
|
|
|
|
|
for (i = 0; i < MAX_MB_PLANE; i++) {
|
|
|
|
xd->plane[i].dst.buf = dst_buf[i];
|
|
|
|
xd->plane[i].dst.stride = dst_stride[i];
|
2016-08-31 00:01:10 +03:00
|
|
|
av1_build_masked_inter_predictor_complex(
|
2016-08-12 04:53:26 +03:00
|
|
|
xd, dst_buf[i], dst_stride[i], dst_buf1[i], dst_stride1[i], mi_row,
|
|
|
|
mi_col, mi_row_top, mi_col_top, bsize, top_bsize, PARTITION_VERT,
|
|
|
|
i);
|
2016-03-17 19:50:28 +03:00
|
|
|
}
|
|
|
|
for (i = 0; i < MAX_MB_PLANE; i++) {
|
2016-08-31 00:01:10 +03:00
|
|
|
av1_build_masked_inter_predictor_complex(
|
2016-08-12 04:53:26 +03:00
|
|
|
xd, dst_buf[i], dst_stride[i], dst_buf2[i], dst_stride2[i], mi_row,
|
|
|
|
mi_col, mi_row_top, mi_col_top, bsize, top_bsize, PARTITION_HORZ,
|
|
|
|
i);
|
2016-03-17 19:50:28 +03:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
case PARTITION_VERT_A:
|
|
|
|
|
|
|
|
dec_predict_b_extend(pbi, xd, tile, 0, mi_row, mi_col, mi_row, mi_col,
|
|
|
|
mi_row_top, mi_col_top, dst_buf, dst_stride,
|
|
|
|
top_bsize, bsize2, 0, 0);
|
|
|
|
dec_extend_all(pbi, xd, tile, 0, bsize2, top_bsize, mi_row, mi_col,
|
|
|
|
mi_row_top, mi_col_top, dst_buf, dst_stride);
|
|
|
|
|
2016-08-12 04:53:26 +03:00
|
|
|
dec_predict_b_extend(pbi, xd, tile, 0, mi_row + hbs, mi_col, mi_row + hbs,
|
|
|
|
mi_col, mi_row_top, mi_col_top, dst_buf1,
|
|
|
|
dst_stride1, top_bsize, bsize2, 0, 0);
|
2016-03-17 19:50:28 +03:00
|
|
|
dec_extend_all(pbi, xd, tile, 0, bsize2, top_bsize, mi_row + hbs, mi_col,
|
|
|
|
mi_row_top, mi_col_top, dst_buf1, dst_stride1);
|
|
|
|
|
2016-08-12 04:53:26 +03:00
|
|
|
dec_predict_b_extend(pbi, xd, tile, 0, mi_row, mi_col + hbs, mi_row,
|
|
|
|
mi_col + hbs, mi_row_top, mi_col_top, dst_buf2,
|
|
|
|
dst_stride2, top_bsize, subsize, 0, 0);
|
2016-03-17 19:50:28 +03:00
|
|
|
if (bsize < top_bsize)
|
2016-08-12 04:53:26 +03:00
|
|
|
dec_extend_all(pbi, xd, tile, 0, subsize, top_bsize, mi_row,
|
|
|
|
mi_col + hbs, mi_row_top, mi_col_top, dst_buf2,
|
|
|
|
dst_stride2);
|
2016-03-17 19:50:28 +03:00
|
|
|
else
|
2016-08-12 04:53:26 +03:00
|
|
|
dec_extend_dir(pbi, xd, tile, 0, subsize, top_bsize, mi_row,
|
|
|
|
mi_col + hbs, mi_row_top, mi_col_top, dst_buf2,
|
|
|
|
dst_stride2, 2);
|
2016-03-17 19:50:28 +03:00
|
|
|
|
|
|
|
for (i = 0; i < MAX_MB_PLANE; i++) {
|
|
|
|
xd->plane[i].dst.buf = dst_buf[i];
|
|
|
|
xd->plane[i].dst.stride = dst_stride[i];
|
2016-08-31 00:01:10 +03:00
|
|
|
av1_build_masked_inter_predictor_complex(
|
2016-08-12 04:53:26 +03:00
|
|
|
xd, dst_buf[i], dst_stride[i], dst_buf1[i], dst_stride1[i], mi_row,
|
|
|
|
mi_col, mi_row_top, mi_col_top, bsize, top_bsize, PARTITION_HORZ,
|
|
|
|
i);
|
2016-03-17 19:50:28 +03:00
|
|
|
}
|
|
|
|
for (i = 0; i < MAX_MB_PLANE; i++) {
|
2016-08-31 00:01:10 +03:00
|
|
|
av1_build_masked_inter_predictor_complex(
|
2016-08-12 04:53:26 +03:00
|
|
|
xd, dst_buf[i], dst_stride[i], dst_buf2[i], dst_stride2[i], mi_row,
|
|
|
|
mi_col, mi_row_top, mi_col_top, bsize, top_bsize, PARTITION_VERT,
|
|
|
|
i);
|
2016-03-17 19:50:28 +03:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
case PARTITION_HORZ_B:
|
|
|
|
dec_predict_b_extend(pbi, xd, tile, 0, mi_row, mi_col, mi_row, mi_col,
|
|
|
|
mi_row_top, mi_col_top, dst_buf, dst_stride,
|
|
|
|
top_bsize, subsize, 0, 0);
|
|
|
|
if (bsize < top_bsize)
|
|
|
|
dec_extend_all(pbi, xd, tile, 0, subsize, top_bsize, mi_row, mi_col,
|
|
|
|
mi_row_top, mi_col_top, dst_buf, dst_stride);
|
|
|
|
else
|
|
|
|
dec_extend_dir(pbi, xd, tile, 0, subsize, top_bsize, mi_row, mi_col,
|
|
|
|
mi_row_top, mi_col_top, dst_buf, dst_stride, 0);
|
|
|
|
|
|
|
|
dec_predict_b_extend(pbi, xd, tile, 0, mi_row + hbs, mi_col, mi_row + hbs,
|
2016-08-12 04:53:26 +03:00
|
|
|
mi_col, mi_row_top, mi_col_top, dst_buf1,
|
|
|
|
dst_stride1, top_bsize, bsize2, 0, 0);
|
2016-03-17 19:50:28 +03:00
|
|
|
dec_extend_all(pbi, xd, tile, 0, bsize2, top_bsize, mi_row + hbs, mi_col,
|
|
|
|
mi_row_top, mi_col_top, dst_buf1, dst_stride1);
|
|
|
|
|
|
|
|
dec_predict_b_extend(pbi, xd, tile, 0, mi_row + hbs, mi_col + hbs,
|
|
|
|
mi_row + hbs, mi_col + hbs, mi_row_top, mi_col_top,
|
|
|
|
dst_buf2, dst_stride2, top_bsize, bsize2, 0, 0);
|
2016-08-12 04:53:26 +03:00
|
|
|
dec_extend_all(pbi, xd, tile, 0, bsize2, top_bsize, mi_row + hbs,
|
|
|
|
mi_col + hbs, mi_row_top, mi_col_top, dst_buf2,
|
|
|
|
dst_stride2);
|
2016-03-17 19:50:28 +03:00
|
|
|
|
|
|
|
for (i = 0; i < MAX_MB_PLANE; i++) {
|
|
|
|
xd->plane[i].dst.buf = dst_buf1[i];
|
|
|
|
xd->plane[i].dst.stride = dst_stride1[i];
|
2016-08-31 00:01:10 +03:00
|
|
|
av1_build_masked_inter_predictor_complex(
|
2016-08-12 04:53:26 +03:00
|
|
|
xd, dst_buf1[i], dst_stride1[i], dst_buf2[i], dst_stride2[i],
|
|
|
|
mi_row, mi_col, mi_row_top, mi_col_top, bsize, top_bsize,
|
|
|
|
PARTITION_VERT, i);
|
2016-03-17 19:50:28 +03:00
|
|
|
}
|
|
|
|
for (i = 0; i < MAX_MB_PLANE; i++) {
|
|
|
|
xd->plane[i].dst.buf = dst_buf[i];
|
|
|
|
xd->plane[i].dst.stride = dst_stride[i];
|
2016-08-31 00:01:10 +03:00
|
|
|
av1_build_masked_inter_predictor_complex(
|
2016-08-12 04:53:26 +03:00
|
|
|
xd, dst_buf[i], dst_stride[i], dst_buf1[i], dst_stride1[i], mi_row,
|
|
|
|
mi_col, mi_row_top, mi_col_top, bsize, top_bsize, PARTITION_HORZ,
|
|
|
|
i);
|
2016-03-17 19:50:28 +03:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
case PARTITION_VERT_B:
|
|
|
|
dec_predict_b_extend(pbi, xd, tile, 0, mi_row, mi_col, mi_row, mi_col,
|
|
|
|
mi_row_top, mi_col_top, dst_buf, dst_stride,
|
|
|
|
top_bsize, subsize, 0, 0);
|
|
|
|
if (bsize < top_bsize)
|
|
|
|
dec_extend_all(pbi, xd, tile, 0, subsize, top_bsize, mi_row, mi_col,
|
|
|
|
mi_row_top, mi_col_top, dst_buf, dst_stride);
|
|
|
|
else
|
|
|
|
dec_extend_dir(pbi, xd, tile, 0, subsize, top_bsize, mi_row, mi_col,
|
|
|
|
mi_row_top, mi_col_top, dst_buf, dst_stride, 3);
|
|
|
|
|
2016-08-12 04:53:26 +03:00
|
|
|
dec_predict_b_extend(pbi, xd, tile, 0, mi_row, mi_col + hbs, mi_row,
|
|
|
|
mi_col + hbs, mi_row_top, mi_col_top, dst_buf1,
|
|
|
|
dst_stride1, top_bsize, bsize2, 0, 0);
|
2016-03-17 19:50:28 +03:00
|
|
|
dec_extend_all(pbi, xd, tile, 0, bsize2, top_bsize, mi_row, mi_col + hbs,
|
|
|
|
mi_row_top, mi_col_top, dst_buf1, dst_stride1);
|
|
|
|
|
|
|
|
dec_predict_b_extend(pbi, xd, tile, 0, mi_row + hbs, mi_col + hbs,
|
|
|
|
mi_row + hbs, mi_col + hbs, mi_row_top, mi_col_top,
|
|
|
|
dst_buf2, dst_stride2, top_bsize, bsize2, 0, 0);
|
2016-08-12 04:53:26 +03:00
|
|
|
dec_extend_all(pbi, xd, tile, 0, bsize2, top_bsize, mi_row + hbs,
|
|
|
|
mi_col + hbs, mi_row_top, mi_col_top, dst_buf2,
|
|
|
|
dst_stride2);
|
2016-03-17 19:50:28 +03:00
|
|
|
|
|
|
|
for (i = 0; i < MAX_MB_PLANE; i++) {
|
|
|
|
xd->plane[i].dst.buf = dst_buf1[i];
|
|
|
|
xd->plane[i].dst.stride = dst_stride1[i];
|
2016-08-31 00:01:10 +03:00
|
|
|
av1_build_masked_inter_predictor_complex(
|
2016-08-12 04:53:26 +03:00
|
|
|
xd, dst_buf1[i], dst_stride1[i], dst_buf2[i], dst_stride2[i],
|
|
|
|
mi_row, mi_col, mi_row_top, mi_col_top, bsize, top_bsize,
|
|
|
|
PARTITION_HORZ, i);
|
2016-03-17 19:50:28 +03:00
|
|
|
}
|
|
|
|
for (i = 0; i < MAX_MB_PLANE; i++) {
|
|
|
|
xd->plane[i].dst.buf = dst_buf[i];
|
|
|
|
xd->plane[i].dst.stride = dst_stride[i];
|
2016-08-31 00:01:10 +03:00
|
|
|
av1_build_masked_inter_predictor_complex(
|
2016-08-12 04:53:26 +03:00
|
|
|
xd, dst_buf[i], dst_stride[i], dst_buf1[i], dst_stride1[i], mi_row,
|
|
|
|
mi_col, mi_row_top, mi_col_top, bsize, top_bsize, PARTITION_VERT,
|
|
|
|
i);
|
2016-03-17 19:50:28 +03:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
#endif // CONFIG_EXT_PARTITION_TYPES
|
2016-08-12 04:53:26 +03:00
|
|
|
default: assert(0);
|
2015-11-20 03:51:16 +03:00
|
|
|
}
|
|
|
|
}
|
2016-06-09 19:06:02 +03:00
|
|
|
|
2016-08-31 00:01:10 +03:00
|
|
|
static void set_segment_id_supertx(const AV1_COMMON *const cm, const int mi_row,
|
|
|
|
const int mi_col, const BLOCK_SIZE bsize) {
|
2016-06-09 19:06:02 +03:00
|
|
|
const struct segmentation *seg = &cm->seg;
|
|
|
|
const int miw =
|
2016-08-31 00:01:10 +03:00
|
|
|
AOMMIN(num_8x8_blocks_wide_lookup[bsize], cm->mi_cols - mi_col);
|
2016-06-09 19:06:02 +03:00
|
|
|
const int mih =
|
2016-08-31 00:01:10 +03:00
|
|
|
AOMMIN(num_8x8_blocks_high_lookup[bsize], cm->mi_rows - mi_row);
|
2016-06-09 19:06:02 +03:00
|
|
|
const int mi_offset = mi_row * cm->mi_stride + mi_col;
|
|
|
|
MODE_INFO **const mip = cm->mi_grid_visible + mi_offset;
|
|
|
|
int r, c;
|
|
|
|
int seg_id_supertx = MAX_SEGMENTS;
|
|
|
|
|
|
|
|
if (!seg->enabled) {
|
|
|
|
seg_id_supertx = 0;
|
|
|
|
} else {
|
|
|
|
// Find the minimum segment_id
|
2016-08-12 04:53:26 +03:00
|
|
|
for (r = 0; r < mih; r++)
|
|
|
|
for (c = 0; c < miw; c++)
|
|
|
|
seg_id_supertx =
|
2016-08-31 00:01:10 +03:00
|
|
|
AOMMIN(mip[r * cm->mi_stride + c]->mbmi.segment_id, seg_id_supertx);
|
2016-06-09 19:06:02 +03:00
|
|
|
assert(0 <= seg_id_supertx && seg_id_supertx < MAX_SEGMENTS);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Assign the the segment_id back to segment_id_supertx
|
2016-08-12 04:53:26 +03:00
|
|
|
for (r = 0; r < mih; r++)
|
|
|
|
for (c = 0; c < miw; c++)
|
2016-06-09 19:06:02 +03:00
|
|
|
mip[r * cm->mi_stride + c]->mbmi.segment_id_supertx = seg_id_supertx;
|
|
|
|
}
|
2015-11-20 03:51:16 +03:00
|
|
|
#endif // CONFIG_SUPERTX
|
|
|
|
|
2016-08-31 00:01:10 +03:00
|
|
|
static void decode_block(AV1Decoder *const pbi, MACROBLOCKD *const xd,
|
2015-11-20 03:51:16 +03:00
|
|
|
#if CONFIG_SUPERTX
|
|
|
|
int supertx_enabled,
|
|
|
|
#endif // CONFIG_SUPERTX
|
2016-08-31 00:01:10 +03:00
|
|
|
int mi_row, int mi_col, aom_reader *r,
|
2016-03-17 19:50:28 +03:00
|
|
|
#if CONFIG_EXT_PARTITION_TYPES
|
|
|
|
PARTITION_TYPE partition,
|
|
|
|
#endif // CONFIG_EXT_PARTITION_TYPES
|
2016-08-12 04:53:26 +03:00
|
|
|
BLOCK_SIZE bsize, int bwl, int bhl) {
|
2016-08-31 00:01:10 +03:00
|
|
|
AV1_COMMON *const cm = &pbi->common;
|
2015-08-06 05:00:31 +03:00
|
|
|
const int less8x8 = bsize < BLOCK_8X8;
|
|
|
|
const int bw = 1 << (bwl - 1);
|
|
|
|
const int bh = 1 << (bhl - 1);
|
2016-08-31 00:01:10 +03:00
|
|
|
const int x_mis = AOMMIN(bw, cm->mi_cols - mi_col);
|
|
|
|
const int y_mis = AOMMIN(bh, cm->mi_rows - mi_row);
|
2015-08-06 05:00:31 +03:00
|
|
|
|
2015-11-20 03:51:16 +03:00
|
|
|
#if CONFIG_SUPERTX
|
|
|
|
MB_MODE_INFO *mbmi;
|
|
|
|
if (supertx_enabled) {
|
2016-08-12 04:53:26 +03:00
|
|
|
mbmi = set_mb_offsets(cm, xd, bsize, mi_row, mi_col, bw, bh, x_mis, y_mis);
|
2015-11-20 03:51:16 +03:00
|
|
|
} else {
|
2016-08-12 04:53:26 +03:00
|
|
|
mbmi = set_offsets(cm, xd, bsize, mi_row, mi_col, bw, bh, x_mis, y_mis, bwl,
|
|
|
|
bhl);
|
2015-11-20 03:51:16 +03:00
|
|
|
}
|
2016-03-17 19:50:28 +03:00
|
|
|
#if CONFIG_EXT_PARTITION_TYPES
|
|
|
|
xd->mi[0]->mbmi.partition = partition;
|
|
|
|
#endif
|
2016-08-31 00:01:10 +03:00
|
|
|
av1_read_mode_info(pbi, xd, supertx_enabled, mi_row, mi_col, r, x_mis, y_mis);
|
2015-11-20 03:51:16 +03:00
|
|
|
#else
|
2016-08-12 04:53:26 +03:00
|
|
|
MB_MODE_INFO *mbmi = set_offsets(cm, xd, bsize, mi_row, mi_col, bw, bh, x_mis,
|
|
|
|
y_mis, bwl, bhl);
|
2016-03-17 19:50:28 +03:00
|
|
|
#if CONFIG_EXT_PARTITION_TYPES
|
|
|
|
xd->mi[0]->mbmi.partition = partition;
|
|
|
|
#endif
|
2016-08-31 00:01:10 +03:00
|
|
|
av1_read_mode_info(pbi, xd, mi_row, mi_col, r, x_mis, y_mis);
|
2015-11-20 03:51:16 +03:00
|
|
|
#endif // CONFIG_SUPERTX
|
2015-08-06 05:00:31 +03:00
|
|
|
|
|
|
|
if (bsize >= BLOCK_8X8 && (cm->subsampling_x || cm->subsampling_y)) {
|
|
|
|
const BLOCK_SIZE uv_subsize =
|
|
|
|
ss_size_lookup[bsize][cm->subsampling_x][cm->subsampling_y];
|
|
|
|
if (uv_subsize == BLOCK_INVALID)
|
2016-08-31 00:01:10 +03:00
|
|
|
aom_internal_error(xd->error_info, AOM_CODEC_CORRUPT_FRAME,
|
2016-08-12 04:53:26 +03:00
|
|
|
"Invalid block size.");
|
2015-08-06 05:00:31 +03:00
|
|
|
}
|
|
|
|
|
2015-11-20 03:51:16 +03:00
|
|
|
#if CONFIG_SUPERTX
|
2016-06-10 11:32:21 +03:00
|
|
|
mbmi->segment_id_supertx = MAX_SEGMENTS;
|
|
|
|
|
2016-06-09 19:02:10 +03:00
|
|
|
if (supertx_enabled) {
|
2016-08-31 00:01:10 +03:00
|
|
|
xd->corrupted |= aom_reader_has_error(r);
|
2016-06-09 19:02:10 +03:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
#endif // CONFIG_SUPERTX
|
|
|
|
|
|
|
|
if (mbmi->skip) {
|
|
|
|
dec_reset_skip_context(xd);
|
|
|
|
}
|
|
|
|
if (!is_inter_block(mbmi)) {
|
|
|
|
int plane;
|
|
|
|
for (plane = 0; plane <= 1; ++plane) {
|
|
|
|
if (mbmi->palette_mode_info.palette_size[plane])
|
2016-08-31 00:01:10 +03:00
|
|
|
av1_decode_palette_tokens(xd, plane, r);
|
2015-08-06 05:00:31 +03:00
|
|
|
}
|
2016-06-09 19:02:10 +03:00
|
|
|
for (plane = 0; plane < MAX_MB_PLANE; ++plane) {
|
|
|
|
const struct macroblockd_plane *const pd = &xd->plane[plane];
|
2016-08-31 03:43:38 +03:00
|
|
|
const TX_SIZE tx_size = plane ? get_uv_tx_size(mbmi, pd) : mbmi->tx_size;
|
2016-06-09 19:02:10 +03:00
|
|
|
const int num_4x4_w = pd->n4_w;
|
|
|
|
const int num_4x4_h = pd->n4_h;
|
2016-07-01 22:57:14 +03:00
|
|
|
const int stepr = num_4x4_blocks_high_txsize_lookup[tx_size];
|
|
|
|
const int stepc = num_4x4_blocks_wide_txsize_lookup[tx_size];
|
2016-06-09 19:02:10 +03:00
|
|
|
int row, col;
|
2016-08-12 04:53:26 +03:00
|
|
|
const int max_blocks_wide =
|
|
|
|
num_4x4_w + (xd->mb_to_right_edge >= 0
|
|
|
|
? 0
|
|
|
|
: xd->mb_to_right_edge >> (5 + pd->subsampling_x));
|
|
|
|
const int max_blocks_high =
|
|
|
|
num_4x4_h + (xd->mb_to_bottom_edge >= 0
|
|
|
|
? 0
|
|
|
|
: xd->mb_to_bottom_edge >> (5 + pd->subsampling_y));
|
2016-06-09 19:02:10 +03:00
|
|
|
|
2016-07-01 22:57:14 +03:00
|
|
|
for (row = 0; row < max_blocks_high; row += stepr)
|
|
|
|
for (col = 0; col < max_blocks_wide; col += stepc)
|
2016-08-12 04:53:26 +03:00
|
|
|
predict_and_reconstruct_intra_block(xd, r, mbmi, plane, row, col,
|
|
|
|
tx_size);
|
2016-06-09 19:02:10 +03:00
|
|
|
}
|
|
|
|
} else {
|
|
|
|
// Prediction
|
2016-08-31 00:01:10 +03:00
|
|
|
av1_build_inter_predictors_sb(xd, mi_row, mi_col, AOMMAX(bsize, BLOCK_8X8));
|
2016-06-09 19:02:10 +03:00
|
|
|
#if CONFIG_OBMC
|
|
|
|
if (mbmi->motion_variation == OBMC_CAUSAL) {
|
2016-08-31 00:01:10 +03:00
|
|
|
#if CONFIG_AOM_HIGHBITDEPTH
|
2016-08-12 04:53:26 +03:00
|
|
|
DECLARE_ALIGNED(16, uint8_t, tmp_buf1[2 * MAX_MB_PLANE * MAX_SB_SQUARE]);
|
|
|
|
DECLARE_ALIGNED(16, uint8_t, tmp_buf2[2 * MAX_MB_PLANE * MAX_SB_SQUARE]);
|
2016-06-09 19:02:10 +03:00
|
|
|
#else
|
2016-08-12 04:53:26 +03:00
|
|
|
DECLARE_ALIGNED(16, uint8_t, tmp_buf1[MAX_MB_PLANE * MAX_SB_SQUARE]);
|
|
|
|
DECLARE_ALIGNED(16, uint8_t, tmp_buf2[MAX_MB_PLANE * MAX_SB_SQUARE]);
|
2016-08-31 00:01:10 +03:00
|
|
|
#endif // CONFIG_AOM_HIGHBITDEPTH
|
2016-06-09 19:02:10 +03:00
|
|
|
uint8_t *dst_buf1[MAX_MB_PLANE], *dst_buf2[MAX_MB_PLANE];
|
2016-08-12 04:53:26 +03:00
|
|
|
int dst_width1[MAX_MB_PLANE] = { MAX_SB_SIZE, MAX_SB_SIZE, MAX_SB_SIZE };
|
|
|
|
int dst_width2[MAX_MB_PLANE] = { MAX_SB_SIZE, MAX_SB_SIZE, MAX_SB_SIZE };
|
|
|
|
int dst_height1[MAX_MB_PLANE] = { MAX_SB_SIZE, MAX_SB_SIZE, MAX_SB_SIZE };
|
|
|
|
int dst_height2[MAX_MB_PLANE] = { MAX_SB_SIZE, MAX_SB_SIZE, MAX_SB_SIZE };
|
|
|
|
int dst_stride1[MAX_MB_PLANE] = { MAX_SB_SIZE, MAX_SB_SIZE, MAX_SB_SIZE };
|
|
|
|
int dst_stride2[MAX_MB_PLANE] = { MAX_SB_SIZE, MAX_SB_SIZE, MAX_SB_SIZE };
|
2016-06-09 19:02:10 +03:00
|
|
|
|
|
|
|
assert(mbmi->sb_type >= BLOCK_8X8);
|
2016-08-31 00:01:10 +03:00
|
|
|
#if CONFIG_AOM_HIGHBITDEPTH
|
2016-06-09 19:02:10 +03:00
|
|
|
if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
|
|
|
|
int len = sizeof(uint16_t);
|
|
|
|
dst_buf1[0] = CONVERT_TO_BYTEPTR(tmp_buf1);
|
|
|
|
dst_buf1[1] = CONVERT_TO_BYTEPTR(tmp_buf1 + MAX_SB_SQUARE * len);
|
|
|
|
dst_buf1[2] = CONVERT_TO_BYTEPTR(tmp_buf1 + MAX_SB_SQUARE * 2 * len);
|
|
|
|
dst_buf2[0] = CONVERT_TO_BYTEPTR(tmp_buf2);
|
|
|
|
dst_buf2[1] = CONVERT_TO_BYTEPTR(tmp_buf2 + MAX_SB_SQUARE * len);
|
|
|
|
dst_buf2[2] = CONVERT_TO_BYTEPTR(tmp_buf2 + MAX_SB_SQUARE * 2 * len);
|
|
|
|
} else {
|
2016-08-31 00:01:10 +03:00
|
|
|
#endif // CONFIG_AOM_HIGHBITDEPTH
|
2016-06-09 19:02:10 +03:00
|
|
|
dst_buf1[0] = tmp_buf1;
|
|
|
|
dst_buf1[1] = tmp_buf1 + MAX_SB_SQUARE;
|
|
|
|
dst_buf1[2] = tmp_buf1 + MAX_SB_SQUARE * 2;
|
|
|
|
dst_buf2[0] = tmp_buf2;
|
|
|
|
dst_buf2[1] = tmp_buf2 + MAX_SB_SQUARE;
|
|
|
|
dst_buf2[2] = tmp_buf2 + MAX_SB_SQUARE * 2;
|
2016-08-31 00:01:10 +03:00
|
|
|
#if CONFIG_AOM_HIGHBITDEPTH
|
2016-02-24 02:22:25 +03:00
|
|
|
}
|
2016-08-31 00:01:10 +03:00
|
|
|
#endif // CONFIG_AOM_HIGHBITDEPTH
|
|
|
|
av1_build_prediction_by_above_preds(cm, xd, mi_row, mi_col, dst_buf1,
|
|
|
|
dst_width1, dst_height1, dst_stride1);
|
|
|
|
av1_build_prediction_by_left_preds(cm, xd, mi_row, mi_col, dst_buf2,
|
|
|
|
dst_width2, dst_height2, dst_stride2);
|
|
|
|
av1_setup_dst_planes(xd->plane, get_frame_new_buffer(cm), mi_row, mi_col);
|
|
|
|
av1_build_obmc_inter_prediction(cm, xd, mi_row, mi_col, dst_buf1,
|
|
|
|
dst_stride1, dst_buf2, dst_stride2);
|
2016-06-09 19:02:10 +03:00
|
|
|
}
|
|
|
|
#endif // CONFIG_OBMC
|
|
|
|
|
|
|
|
// Reconstruction
|
|
|
|
if (!mbmi->skip) {
|
|
|
|
int eobtotal = 0;
|
|
|
|
int plane;
|
|
|
|
|
2015-08-06 05:00:31 +03:00
|
|
|
for (plane = 0; plane < MAX_MB_PLANE; ++plane) {
|
|
|
|
const struct macroblockd_plane *const pd = &xd->plane[plane];
|
2016-06-09 19:02:10 +03:00
|
|
|
const int num_4x4_w = pd->n4_w;
|
|
|
|
const int num_4x4_h = pd->n4_h;
|
|
|
|
int row, col;
|
|
|
|
#if CONFIG_VAR_TX
|
|
|
|
// TODO(jingning): This can be simplified for decoder performance.
|
2016-08-12 04:53:26 +03:00
|
|
|
const BLOCK_SIZE plane_bsize =
|
2016-08-31 00:01:10 +03:00
|
|
|
get_plane_block_size(AOMMAX(bsize, BLOCK_8X8), pd);
|
2016-06-09 19:02:10 +03:00
|
|
|
const TX_SIZE max_tx_size = max_txsize_lookup[plane_bsize];
|
2016-07-01 22:57:14 +03:00
|
|
|
int bw = num_4x4_blocks_wide_txsize_lookup[max_tx_size];
|
|
|
|
int bh = num_4x4_blocks_high_txsize_lookup[max_tx_size];
|
|
|
|
const int step = num_4x4_blocks_txsize_lookup[max_tx_size];
|
2016-06-09 19:02:10 +03:00
|
|
|
int block = 0;
|
2016-08-12 02:42:08 +03:00
|
|
|
#if CONFIG_EXT_TX && CONFIG_RECT_TX
|
2016-08-30 03:29:33 +03:00
|
|
|
if (is_rect_tx(mbmi->tx_size)) {
|
|
|
|
const TX_SIZE tx_size =
|
|
|
|
plane ? get_uv_tx_size(mbmi, pd) : mbmi->tx_size;
|
2016-08-12 02:42:08 +03:00
|
|
|
const int stepr = num_4x4_blocks_high_txsize_lookup[tx_size];
|
|
|
|
const int stepc = num_4x4_blocks_wide_txsize_lookup[tx_size];
|
|
|
|
const int max_blocks_wide =
|
|
|
|
num_4x4_w +
|
|
|
|
(xd->mb_to_right_edge >= 0 ? 0 : xd->mb_to_right_edge >>
|
|
|
|
(5 + pd->subsampling_x));
|
|
|
|
const int max_blocks_high =
|
|
|
|
num_4x4_h +
|
|
|
|
(xd->mb_to_bottom_edge >= 0 ? 0 : xd->mb_to_bottom_edge >>
|
|
|
|
(5 + pd->subsampling_y));
|
|
|
|
|
|
|
|
for (row = 0; row < max_blocks_high; row += stepr)
|
|
|
|
for (col = 0; col < max_blocks_wide; col += stepc)
|
|
|
|
eobtotal += reconstruct_inter_block(xd, r, mbmi->segment_id,
|
|
|
|
plane, row, col, tx_size);
|
|
|
|
} else {
|
|
|
|
#endif
|
|
|
|
for (row = 0; row < num_4x4_h; row += bh) {
|
|
|
|
for (col = 0; col < num_4x4_w; col += bw) {
|
|
|
|
decode_reconstruct_tx(xd, r, mbmi, plane, plane_bsize, block, row,
|
|
|
|
col, max_tx_size, &eobtotal);
|
|
|
|
block += step;
|
|
|
|
}
|
2016-06-09 19:02:10 +03:00
|
|
|
}
|
2016-08-12 02:42:08 +03:00
|
|
|
#if CONFIG_EXT_TX && CONFIG_RECT_TX
|
2016-06-09 19:02:10 +03:00
|
|
|
}
|
2016-08-12 02:42:08 +03:00
|
|
|
#endif
|
2016-06-09 19:02:10 +03:00
|
|
|
#else
|
2015-08-06 05:00:31 +03:00
|
|
|
const TX_SIZE tx_size =
|
2016-08-31 03:43:38 +03:00
|
|
|
plane ? get_uv_tx_size(mbmi, pd) : mbmi->tx_size;
|
2016-07-01 22:57:14 +03:00
|
|
|
const int stepr = num_4x4_blocks_high_txsize_lookup[tx_size];
|
|
|
|
const int stepc = num_4x4_blocks_wide_txsize_lookup[tx_size];
|
2016-08-12 04:53:26 +03:00
|
|
|
const int max_blocks_wide =
|
|
|
|
num_4x4_w + (xd->mb_to_right_edge >= 0
|
|
|
|
? 0
|
|
|
|
: xd->mb_to_right_edge >> (5 + pd->subsampling_x));
|
|
|
|
const int max_blocks_high =
|
|
|
|
num_4x4_h +
|
|
|
|
(xd->mb_to_bottom_edge >= 0 ? 0 : xd->mb_to_bottom_edge >>
|
|
|
|
(5 + pd->subsampling_y));
|
2015-08-06 05:00:31 +03:00
|
|
|
|
2016-07-01 22:57:14 +03:00
|
|
|
for (row = 0; row < max_blocks_high; row += stepr)
|
|
|
|
for (col = 0; col < max_blocks_wide; col += stepc)
|
2016-08-12 04:53:26 +03:00
|
|
|
eobtotal += reconstruct_inter_block(xd, r, mbmi->segment_id, plane,
|
|
|
|
row, col, tx_size);
|
2015-11-20 03:51:16 +03:00
|
|
|
#endif
|
|
|
|
}
|
2016-06-09 19:02:10 +03:00
|
|
|
|
|
|
|
if (!less8x8 && eobtotal == 0)
|
|
|
|
mbmi->has_no_coeffs = 1; // skip loopfilter
|
2015-08-06 05:00:31 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-08-31 00:01:10 +03:00
|
|
|
xd->corrupted |= aom_reader_has_error(r);
|
2015-08-06 05:00:31 +03:00
|
|
|
}
|
|
|
|
|
2016-08-12 04:53:26 +03:00
|
|
|
static INLINE int dec_partition_plane_context(const MACROBLOCKD *xd, int mi_row,
|
|
|
|
int mi_col, int bsl) {
|
2015-08-06 05:00:31 +03:00
|
|
|
const PARTITION_CONTEXT *above_ctx = xd->above_seg_context + mi_col;
|
2016-03-24 14:20:25 +03:00
|
|
|
const PARTITION_CONTEXT *left_ctx =
|
2016-08-12 04:53:26 +03:00
|
|
|
xd->left_seg_context + (mi_row & MAX_MIB_MASK);
|
|
|
|
int above = (*above_ctx >> bsl) & 1, left = (*left_ctx >> bsl) & 1;
|
2015-08-06 05:00:31 +03:00
|
|
|
|
2016-08-12 04:53:26 +03:00
|
|
|
// assert(bsl >= 0);
|
2015-08-06 05:00:31 +03:00
|
|
|
|
|
|
|
return (left * 2 + above) + bsl * PARTITION_PLOFFSET;
|
|
|
|
}
|
|
|
|
|
2016-03-17 19:50:28 +03:00
|
|
|
#if !CONFIG_EXT_PARTITION_TYPES
|
2016-08-12 04:53:26 +03:00
|
|
|
static INLINE void dec_update_partition_context(MACROBLOCKD *xd, int mi_row,
|
|
|
|
int mi_col, BLOCK_SIZE subsize,
|
2015-08-06 05:00:31 +03:00
|
|
|
int bw) {
|
|
|
|
PARTITION_CONTEXT *const above_ctx = xd->above_seg_context + mi_col;
|
2016-03-24 14:20:25 +03:00
|
|
|
PARTITION_CONTEXT *const left_ctx =
|
2016-08-12 04:53:26 +03:00
|
|
|
xd->left_seg_context + (mi_row & MAX_MIB_MASK);
|
2015-08-06 05:00:31 +03:00
|
|
|
|
|
|
|
// update the partition context at the end notes. set partition bits
|
|
|
|
// of block sizes larger than the current one to be one, and partition
|
|
|
|
// bits of smaller block sizes to be zero.
|
|
|
|
memset(above_ctx, partition_context_lookup[subsize].above, bw);
|
|
|
|
memset(left_ctx, partition_context_lookup[subsize].left, bw);
|
|
|
|
}
|
2016-03-17 19:50:28 +03:00
|
|
|
#endif // !CONFIG_EXT_PARTITION_TYPES
|
2015-08-06 05:00:31 +03:00
|
|
|
|
2016-08-31 00:01:10 +03:00
|
|
|
static PARTITION_TYPE read_partition(AV1_COMMON *cm, MACROBLOCKD *xd,
|
|
|
|
int mi_row, int mi_col, aom_reader *r,
|
2016-03-17 19:50:28 +03:00
|
|
|
int has_rows, int has_cols,
|
|
|
|
#if CONFIG_EXT_PARTITION_TYPES
|
|
|
|
BLOCK_SIZE bsize,
|
|
|
|
#endif
|
|
|
|
int bsl) {
|
2015-08-06 05:00:31 +03:00
|
|
|
const int ctx = dec_partition_plane_context(xd, mi_row, mi_col, bsl);
|
2016-08-31 00:01:10 +03:00
|
|
|
const aom_prob *const probs = cm->fc->partition_prob[ctx];
|
2015-08-06 05:00:31 +03:00
|
|
|
FRAME_COUNTS *counts = xd->counts;
|
|
|
|
PARTITION_TYPE p;
|
|
|
|
|
|
|
|
if (has_rows && has_cols)
|
2016-03-17 19:50:28 +03:00
|
|
|
#if CONFIG_EXT_PARTITION_TYPES
|
|
|
|
if (bsize <= BLOCK_8X8)
|
2016-08-31 00:01:10 +03:00
|
|
|
p = (PARTITION_TYPE)aom_read_tree(r, av1_partition_tree, probs);
|
2016-03-17 19:50:28 +03:00
|
|
|
else
|
2016-08-31 00:01:10 +03:00
|
|
|
p = (PARTITION_TYPE)aom_read_tree(r, av1_ext_partition_tree, probs);
|
2016-03-17 19:50:28 +03:00
|
|
|
#else
|
2016-08-31 00:01:10 +03:00
|
|
|
p = (PARTITION_TYPE)aom_read_tree(r, av1_partition_tree, probs);
|
2016-03-17 19:50:28 +03:00
|
|
|
#endif // CONFIG_EXT_PARTITION_TYPES
|
2015-08-06 05:00:31 +03:00
|
|
|
else if (!has_rows && has_cols)
|
2016-08-31 00:01:10 +03:00
|
|
|
p = aom_read(r, probs[1]) ? PARTITION_SPLIT : PARTITION_HORZ;
|
2015-08-06 05:00:31 +03:00
|
|
|
else if (has_rows && !has_cols)
|
2016-08-31 00:01:10 +03:00
|
|
|
p = aom_read(r, probs[2]) ? PARTITION_SPLIT : PARTITION_VERT;
|
2015-08-06 05:00:31 +03:00
|
|
|
else
|
|
|
|
p = PARTITION_SPLIT;
|
|
|
|
|
2016-08-12 04:53:26 +03:00
|
|
|
if (counts) ++counts->partition[ctx][p];
|
2015-08-06 05:00:31 +03:00
|
|
|
|
|
|
|
return p;
|
|
|
|
}
|
|
|
|
|
2015-11-20 03:51:16 +03:00
|
|
|
#if CONFIG_SUPERTX
|
2016-08-31 00:01:10 +03:00
|
|
|
static int read_skip(AV1_COMMON *cm, const MACROBLOCKD *xd, int segment_id,
|
|
|
|
aom_reader *r) {
|
2016-06-16 19:26:23 +03:00
|
|
|
if (segfeature_active(&cm->seg, segment_id, SEG_LVL_SKIP)) {
|
|
|
|
return 1;
|
|
|
|
} else {
|
2016-08-31 00:01:10 +03:00
|
|
|
const int ctx = av1_get_skip_context(xd);
|
|
|
|
const int skip = aom_read(r, cm->fc->skip_probs[ctx]);
|
2016-06-16 19:26:23 +03:00
|
|
|
FRAME_COUNTS *counts = xd->counts;
|
2016-08-12 04:53:26 +03:00
|
|
|
if (counts) ++counts->skip[ctx][skip];
|
2016-06-16 19:26:23 +03:00
|
|
|
return skip;
|
|
|
|
}
|
2015-11-20 03:51:16 +03:00
|
|
|
}
|
|
|
|
#endif // CONFIG_SUPERTX
|
|
|
|
|
2015-08-06 05:00:31 +03:00
|
|
|
// TODO(slavarnway): eliminate bsize and subsize in future commits
|
2016-08-31 00:01:10 +03:00
|
|
|
static void decode_partition(AV1Decoder *const pbi, MACROBLOCKD *const xd,
|
2015-11-20 03:51:16 +03:00
|
|
|
#if CONFIG_SUPERTX
|
|
|
|
int supertx_enabled,
|
|
|
|
#endif
|
2016-08-31 00:01:10 +03:00
|
|
|
int mi_row, int mi_col, aom_reader *r,
|
2015-12-16 22:17:25 +03:00
|
|
|
BLOCK_SIZE bsize, int n4x4_l2) {
|
2016-08-31 00:01:10 +03:00
|
|
|
AV1_COMMON *const cm = &pbi->common;
|
2015-08-06 05:00:31 +03:00
|
|
|
const int n8x8_l2 = n4x4_l2 - 1;
|
|
|
|
const int num_8x8_wh = 1 << n8x8_l2;
|
|
|
|
const int hbs = num_8x8_wh >> 1;
|
|
|
|
PARTITION_TYPE partition;
|
|
|
|
BLOCK_SIZE subsize;
|
2016-03-17 19:50:28 +03:00
|
|
|
#if CONFIG_EXT_PARTITION_TYPES
|
|
|
|
BLOCK_SIZE bsize2 = get_subsize(bsize, PARTITION_SPLIT);
|
|
|
|
#endif
|
2015-08-06 05:00:31 +03:00
|
|
|
const int has_rows = (mi_row + hbs) < cm->mi_rows;
|
|
|
|
const int has_cols = (mi_col + hbs) < cm->mi_cols;
|
2015-11-20 03:51:16 +03:00
|
|
|
#if CONFIG_SUPERTX
|
|
|
|
const int read_token = !supertx_enabled;
|
|
|
|
int skip = 0;
|
|
|
|
TX_SIZE supertx_size = b_width_log2_lookup[bsize];
|
|
|
|
const TileInfo *const tile = &xd->tile;
|
|
|
|
int txfm = DCT_DCT;
|
|
|
|
#endif // CONFIG_SUPERTX
|
2015-08-06 05:00:31 +03:00
|
|
|
|
2016-08-12 04:53:26 +03:00
|
|
|
if (mi_row >= cm->mi_rows || mi_col >= cm->mi_cols) return;
|
2015-08-06 05:00:31 +03:00
|
|
|
|
2015-10-13 21:07:47 +03:00
|
|
|
partition = read_partition(cm, xd, mi_row, mi_col, r, has_rows, has_cols,
|
2016-03-17 19:50:28 +03:00
|
|
|
#if CONFIG_EXT_PARTITION_TYPES
|
|
|
|
bsize,
|
|
|
|
#endif
|
2015-08-06 05:00:31 +03:00
|
|
|
n8x8_l2);
|
|
|
|
subsize = subsize_lookup[partition][bsize]; // get_subsize(bsize, partition);
|
2015-11-20 03:51:16 +03:00
|
|
|
#if CONFIG_SUPERTX
|
2016-08-12 04:53:26 +03:00
|
|
|
if (!frame_is_intra_only(cm) && partition != PARTITION_NONE &&
|
|
|
|
bsize <= MAX_SUPERTX_BLOCK_SIZE && !supertx_enabled && !xd->lossless[0]) {
|
|
|
|
const int supertx_context = partition_supertx_context_lookup[partition];
|
|
|
|
supertx_enabled =
|
2016-08-31 00:01:10 +03:00
|
|
|
aom_read(r, cm->fc->supertx_prob[supertx_context][supertx_size]);
|
2015-11-20 03:51:16 +03:00
|
|
|
if (xd->counts)
|
|
|
|
xd->counts->supertx[supertx_context][supertx_size][supertx_enabled]++;
|
2016-01-21 13:46:33 +03:00
|
|
|
#if CONFIG_VAR_TX
|
2016-08-12 04:53:26 +03:00
|
|
|
if (supertx_enabled) xd->supertx_size = supertx_size;
|
2016-01-21 13:46:33 +03:00
|
|
|
#endif
|
2015-11-20 03:51:16 +03:00
|
|
|
}
|
|
|
|
#endif // CONFIG_SUPERTX
|
2015-08-06 05:00:31 +03:00
|
|
|
if (!hbs) {
|
|
|
|
// calculate bmode block dimensions (log 2)
|
|
|
|
xd->bmode_blocks_wl = 1 >> !!(partition & PARTITION_VERT);
|
|
|
|
xd->bmode_blocks_hl = 1 >> !!(partition & PARTITION_HORZ);
|
2015-11-20 03:51:16 +03:00
|
|
|
decode_block(pbi, xd,
|
|
|
|
#if CONFIG_SUPERTX
|
|
|
|
supertx_enabled,
|
|
|
|
#endif // CONFIG_SUPERTX
|
2015-12-16 22:17:25 +03:00
|
|
|
mi_row, mi_col, r,
|
2016-03-17 19:50:28 +03:00
|
|
|
#if CONFIG_EXT_PARTITION_TYPES
|
|
|
|
partition,
|
|
|
|
#endif // CONFIG_EXT_PARTITION_TYPES
|
2015-12-16 22:17:25 +03:00
|
|
|
subsize, 1, 1);
|
2015-08-06 05:00:31 +03:00
|
|
|
} else {
|
|
|
|
switch (partition) {
|
|
|
|
case PARTITION_NONE:
|
2015-11-20 03:51:16 +03:00
|
|
|
decode_block(pbi, xd,
|
|
|
|
#if CONFIG_SUPERTX
|
|
|
|
supertx_enabled,
|
|
|
|
#endif // CONFIG_SUPERTX
|
2015-12-16 22:17:25 +03:00
|
|
|
mi_row, mi_col, r,
|
2016-03-17 19:50:28 +03:00
|
|
|
#if CONFIG_EXT_PARTITION_TYPES
|
2016-08-12 04:53:26 +03:00
|
|
|
partition,
|
2016-03-17 19:50:28 +03:00
|
|
|
#endif // CONFIG_EXT_PARTITION_TYPES
|
2015-12-16 22:17:25 +03:00
|
|
|
subsize, n4x4_l2, n4x4_l2);
|
2015-08-06 05:00:31 +03:00
|
|
|
break;
|
|
|
|
case PARTITION_HORZ:
|
2015-11-20 03:51:16 +03:00
|
|
|
decode_block(pbi, xd,
|
|
|
|
#if CONFIG_SUPERTX
|
|
|
|
supertx_enabled,
|
|
|
|
#endif // CONFIG_SUPERTX
|
2015-12-16 22:17:25 +03:00
|
|
|
mi_row, mi_col, r,
|
2016-03-17 19:50:28 +03:00
|
|
|
#if CONFIG_EXT_PARTITION_TYPES
|
2016-08-12 04:53:26 +03:00
|
|
|
partition,
|
2016-03-17 19:50:28 +03:00
|
|
|
#endif // CONFIG_EXT_PARTITION_TYPES
|
2015-12-16 22:17:25 +03:00
|
|
|
subsize, n4x4_l2, n8x8_l2);
|
2015-08-06 05:00:31 +03:00
|
|
|
if (has_rows)
|
2015-11-20 03:51:16 +03:00
|
|
|
decode_block(pbi, xd,
|
|
|
|
#if CONFIG_SUPERTX
|
|
|
|
supertx_enabled,
|
|
|
|
#endif // CONFIG_SUPERTX
|
2015-12-16 22:17:25 +03:00
|
|
|
mi_row + hbs, mi_col, r,
|
2016-03-17 19:50:28 +03:00
|
|
|
#if CONFIG_EXT_PARTITION_TYPES
|
2016-08-12 04:53:26 +03:00
|
|
|
partition,
|
2016-03-17 19:50:28 +03:00
|
|
|
#endif // CONFIG_EXT_PARTITION_TYPES
|
2015-12-16 22:17:25 +03:00
|
|
|
subsize, n4x4_l2, n8x8_l2);
|
2015-08-06 05:00:31 +03:00
|
|
|
break;
|
|
|
|
case PARTITION_VERT:
|
2015-11-20 03:51:16 +03:00
|
|
|
decode_block(pbi, xd,
|
|
|
|
#if CONFIG_SUPERTX
|
|
|
|
supertx_enabled,
|
|
|
|
#endif // CONFIG_SUPERTX
|
2015-12-16 22:17:25 +03:00
|
|
|
mi_row, mi_col, r,
|
2016-03-17 19:50:28 +03:00
|
|
|
#if CONFIG_EXT_PARTITION_TYPES
|
2016-08-12 04:53:26 +03:00
|
|
|
partition,
|
2016-03-17 19:50:28 +03:00
|
|
|
#endif // CONFIG_EXT_PARTITION_TYPES
|
2015-12-16 22:17:25 +03:00
|
|
|
subsize, n8x8_l2, n4x4_l2);
|
2015-08-06 05:00:31 +03:00
|
|
|
if (has_cols)
|
2015-11-20 03:51:16 +03:00
|
|
|
decode_block(pbi, xd,
|
|
|
|
#if CONFIG_SUPERTX
|
|
|
|
supertx_enabled,
|
|
|
|
#endif // CONFIG_SUPERTX
|
2015-12-16 22:17:25 +03:00
|
|
|
mi_row, mi_col + hbs, r,
|
2016-03-17 19:50:28 +03:00
|
|
|
#if CONFIG_EXT_PARTITION_TYPES
|
2016-08-12 04:53:26 +03:00
|
|
|
partition,
|
2016-03-17 19:50:28 +03:00
|
|
|
#endif // CONFIG_EXT_PARTITION_TYPES
|
2015-12-16 22:17:25 +03:00
|
|
|
subsize, n8x8_l2, n4x4_l2);
|
2015-08-06 05:00:31 +03:00
|
|
|
break;
|
|
|
|
case PARTITION_SPLIT:
|
2015-11-20 03:51:16 +03:00
|
|
|
decode_partition(pbi, xd,
|
|
|
|
#if CONFIG_SUPERTX
|
|
|
|
supertx_enabled,
|
|
|
|
#endif // CONFIG_SUPERTX
|
2016-08-12 04:53:26 +03:00
|
|
|
mi_row, mi_col, r, subsize, n8x8_l2);
|
2015-11-20 03:51:16 +03:00
|
|
|
decode_partition(pbi, xd,
|
|
|
|
#if CONFIG_SUPERTX
|
|
|
|
supertx_enabled,
|
|
|
|
#endif // CONFIG_SUPERTX
|
2016-08-12 04:53:26 +03:00
|
|
|
mi_row, mi_col + hbs, r, subsize, n8x8_l2);
|
2015-11-20 03:51:16 +03:00
|
|
|
decode_partition(pbi, xd,
|
|
|
|
#if CONFIG_SUPERTX
|
|
|
|
supertx_enabled,
|
|
|
|
#endif // CONFIG_SUPERTX
|
2016-08-12 04:53:26 +03:00
|
|
|
mi_row + hbs, mi_col, r, subsize, n8x8_l2);
|
2015-11-20 03:51:16 +03:00
|
|
|
decode_partition(pbi, xd,
|
|
|
|
#if CONFIG_SUPERTX
|
|
|
|
supertx_enabled,
|
|
|
|
#endif // CONFIG_SUPERTX
|
2016-08-12 04:53:26 +03:00
|
|
|
mi_row + hbs, mi_col + hbs, r, subsize, n8x8_l2);
|
2015-08-06 05:00:31 +03:00
|
|
|
break;
|
2016-03-17 19:50:28 +03:00
|
|
|
#if CONFIG_EXT_PARTITION_TYPES
|
|
|
|
case PARTITION_HORZ_A:
|
|
|
|
decode_block(pbi, xd,
|
|
|
|
#if CONFIG_SUPERTX
|
|
|
|
supertx_enabled,
|
|
|
|
#endif
|
2016-08-12 04:53:26 +03:00
|
|
|
mi_row, mi_col, r, partition, bsize2, n8x8_l2, n8x8_l2);
|
2016-03-17 19:50:28 +03:00
|
|
|
decode_block(pbi, xd,
|
|
|
|
#if CONFIG_SUPERTX
|
|
|
|
supertx_enabled,
|
|
|
|
#endif
|
2016-08-12 04:53:26 +03:00
|
|
|
mi_row, mi_col + hbs, r, partition, bsize2, n8x8_l2,
|
|
|
|
n8x8_l2);
|
2016-03-17 19:50:28 +03:00
|
|
|
decode_block(pbi, xd,
|
|
|
|
#if CONFIG_SUPERTX
|
|
|
|
supertx_enabled,
|
|
|
|
#endif
|
2016-08-12 04:53:26 +03:00
|
|
|
mi_row + hbs, mi_col, r, partition, subsize, n4x4_l2,
|
|
|
|
n8x8_l2);
|
2016-03-17 19:50:28 +03:00
|
|
|
break;
|
|
|
|
case PARTITION_HORZ_B:
|
|
|
|
decode_block(pbi, xd,
|
|
|
|
#if CONFIG_SUPERTX
|
|
|
|
supertx_enabled,
|
|
|
|
#endif
|
2016-08-12 04:53:26 +03:00
|
|
|
mi_row, mi_col, r, partition, subsize, n4x4_l2, n8x8_l2);
|
2016-03-17 19:50:28 +03:00
|
|
|
decode_block(pbi, xd,
|
|
|
|
#if CONFIG_SUPERTX
|
|
|
|
supertx_enabled,
|
|
|
|
#endif
|
2016-08-12 04:53:26 +03:00
|
|
|
mi_row + hbs, mi_col, r, partition, bsize2, n8x8_l2,
|
|
|
|
n8x8_l2);
|
2016-03-17 19:50:28 +03:00
|
|
|
decode_block(pbi, xd,
|
|
|
|
#if CONFIG_SUPERTX
|
|
|
|
supertx_enabled,
|
|
|
|
#endif
|
2016-08-12 04:53:26 +03:00
|
|
|
mi_row + hbs, mi_col + hbs, r, partition, bsize2, n8x8_l2,
|
|
|
|
n8x8_l2);
|
2016-03-17 19:50:28 +03:00
|
|
|
break;
|
|
|
|
case PARTITION_VERT_A:
|
|
|
|
decode_block(pbi, xd,
|
|
|
|
#if CONFIG_SUPERTX
|
|
|
|
supertx_enabled,
|
|
|
|
#endif
|
2016-08-12 04:53:26 +03:00
|
|
|
mi_row, mi_col, r, partition, bsize2, n8x8_l2, n8x8_l2);
|
2016-03-17 19:50:28 +03:00
|
|
|
decode_block(pbi, xd,
|
|
|
|
#if CONFIG_SUPERTX
|
|
|
|
supertx_enabled,
|
|
|
|
#endif
|
2016-08-12 04:53:26 +03:00
|
|
|
mi_row + hbs, mi_col, r, partition, bsize2, n8x8_l2,
|
|
|
|
n8x8_l2);
|
2016-03-17 19:50:28 +03:00
|
|
|
decode_block(pbi, xd,
|
|
|
|
#if CONFIG_SUPERTX
|
|
|
|
supertx_enabled,
|
|
|
|
#endif
|
2016-08-12 04:53:26 +03:00
|
|
|
mi_row, mi_col + hbs, r, partition, subsize, n8x8_l2,
|
|
|
|
n4x4_l2);
|
2016-03-17 19:50:28 +03:00
|
|
|
break;
|
|
|
|
case PARTITION_VERT_B:
|
|
|
|
decode_block(pbi, xd,
|
|
|
|
#if CONFIG_SUPERTX
|
|
|
|
supertx_enabled,
|
|
|
|
#endif
|
2016-08-12 04:53:26 +03:00
|
|
|
mi_row, mi_col, r, partition, subsize, n8x8_l2, n4x4_l2);
|
2016-03-17 19:50:28 +03:00
|
|
|
decode_block(pbi, xd,
|
|
|
|
#if CONFIG_SUPERTX
|
|
|
|
supertx_enabled,
|
|
|
|
#endif
|
2016-08-12 04:53:26 +03:00
|
|
|
mi_row, mi_col + hbs, r, partition, bsize2, n8x8_l2,
|
|
|
|
n8x8_l2);
|
2016-03-17 19:50:28 +03:00
|
|
|
decode_block(pbi, xd,
|
|
|
|
#if CONFIG_SUPERTX
|
|
|
|
supertx_enabled,
|
|
|
|
#endif
|
2016-08-12 04:53:26 +03:00
|
|
|
mi_row + hbs, mi_col + hbs, r, partition, bsize2, n8x8_l2,
|
|
|
|
n8x8_l2);
|
2016-03-17 19:50:28 +03:00
|
|
|
break;
|
|
|
|
#endif
|
2016-08-12 04:53:26 +03:00
|
|
|
default: assert(0 && "Invalid partition type");
|
2015-08-06 05:00:31 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-11-20 03:51:16 +03:00
|
|
|
#if CONFIG_SUPERTX
|
|
|
|
if (supertx_enabled && read_token) {
|
|
|
|
uint8_t *dst_buf[3];
|
|
|
|
int dst_stride[3], i;
|
2016-06-16 19:13:55 +03:00
|
|
|
int offset = mi_row * cm->mi_stride + mi_col;
|
|
|
|
|
2016-06-16 19:26:23 +03:00
|
|
|
set_segment_id_supertx(cm, mi_row, mi_col, bsize);
|
|
|
|
|
2016-06-16 19:13:55 +03:00
|
|
|
xd->mi = cm->mi_grid_visible + offset;
|
|
|
|
xd->mi[0] = cm->mi + offset;
|
2016-08-12 04:53:26 +03:00
|
|
|
set_mi_row_col(xd, tile, mi_row, num_8x8_blocks_high_lookup[bsize], mi_col,
|
|
|
|
num_8x8_blocks_wide_lookup[bsize], cm->mi_rows, cm->mi_cols);
|
2016-06-16 19:13:55 +03:00
|
|
|
set_skip_context(xd, mi_row, mi_col);
|
2016-06-16 19:26:23 +03:00
|
|
|
skip = read_skip(cm, xd, xd->mi[0]->mbmi.segment_id_supertx, r);
|
2016-06-16 19:13:55 +03:00
|
|
|
if (skip) {
|
|
|
|
reset_skip_context(xd, bsize);
|
|
|
|
} else {
|
|
|
|
#if CONFIG_EXT_TX
|
|
|
|
if (get_ext_tx_types(supertx_size, bsize, 1) > 1) {
|
|
|
|
int eset = get_ext_tx_set(supertx_size, bsize, 1);
|
|
|
|
if (eset > 0) {
|
2016-08-31 00:01:10 +03:00
|
|
|
txfm = aom_read_tree(r, av1_ext_tx_inter_tree[eset],
|
|
|
|
cm->fc->inter_ext_tx_prob[eset][supertx_size]);
|
2016-08-12 04:53:26 +03:00
|
|
|
if (xd->counts) ++xd->counts->inter_ext_tx[eset][supertx_size][txfm];
|
2016-06-16 19:13:55 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
#else
|
|
|
|
if (supertx_size < TX_32X32) {
|
2016-08-31 00:01:10 +03:00
|
|
|
txfm = aom_read_tree(r, av1_ext_tx_tree,
|
|
|
|
cm->fc->inter_ext_tx_prob[supertx_size]);
|
2016-08-12 04:53:26 +03:00
|
|
|
if (xd->counts) ++xd->counts->inter_ext_tx[supertx_size][txfm];
|
2016-06-16 19:13:55 +03:00
|
|
|
}
|
|
|
|
#endif // CONFIG_EXT_TX
|
|
|
|
}
|
2015-11-20 03:51:16 +03:00
|
|
|
|
2016-08-31 00:01:10 +03:00
|
|
|
av1_setup_dst_planes(xd->plane, get_frame_new_buffer(cm), mi_row, mi_col);
|
2015-11-20 03:51:16 +03:00
|
|
|
for (i = 0; i < MAX_MB_PLANE; i++) {
|
|
|
|
dst_buf[i] = xd->plane[i].dst.buf;
|
|
|
|
dst_stride[i] = xd->plane[i].dst.stride;
|
|
|
|
}
|
2016-08-12 04:53:26 +03:00
|
|
|
dec_predict_sb_complex(pbi, xd, tile, mi_row, mi_col, mi_row, mi_col, bsize,
|
|
|
|
bsize, dst_buf, dst_stride);
|
2015-11-20 03:51:16 +03:00
|
|
|
|
|
|
|
if (!skip) {
|
|
|
|
int eobtotal = 0;
|
2016-06-07 21:30:01 +03:00
|
|
|
MB_MODE_INFO *mbmi;
|
2015-11-20 03:51:16 +03:00
|
|
|
set_offsets_topblock(cm, xd, tile, bsize, mi_row, mi_col);
|
2016-06-07 21:30:01 +03:00
|
|
|
mbmi = &xd->mi[0]->mbmi;
|
|
|
|
mbmi->tx_type = txfm;
|
2016-06-09 19:06:02 +03:00
|
|
|
assert(mbmi->segment_id_supertx != MAX_SEGMENTS);
|
2015-11-20 03:51:16 +03:00
|
|
|
for (i = 0; i < MAX_MB_PLANE; ++i) {
|
|
|
|
const struct macroblockd_plane *const pd = &xd->plane[i];
|
|
|
|
const int num_4x4_w = pd->n4_w;
|
|
|
|
const int num_4x4_h = pd->n4_h;
|
|
|
|
int row, col;
|
2016-08-31 03:43:38 +03:00
|
|
|
const TX_SIZE tx_size = i ? get_uv_tx_size(mbmi, pd) : mbmi->tx_size;
|
2016-07-01 22:57:14 +03:00
|
|
|
const int stepr = num_4x4_blocks_high_txsize_lookup[tx_size];
|
|
|
|
const int stepc = num_4x4_blocks_wide_txsize_lookup[tx_size];
|
2016-08-12 04:53:26 +03:00
|
|
|
const int max_blocks_wide =
|
|
|
|
num_4x4_w + (xd->mb_to_right_edge >= 0
|
|
|
|
? 0
|
|
|
|
: xd->mb_to_right_edge >> (5 + pd->subsampling_x));
|
|
|
|
const int max_blocks_high =
|
|
|
|
num_4x4_h +
|
|
|
|
(xd->mb_to_bottom_edge >= 0 ? 0 : xd->mb_to_bottom_edge >>
|
|
|
|
(5 + pd->subsampling_y));
|
2015-11-20 03:51:16 +03:00
|
|
|
|
2016-07-01 22:57:14 +03:00
|
|
|
for (row = 0; row < max_blocks_high; row += stepr)
|
|
|
|
for (col = 0; col < max_blocks_wide; col += stepc)
|
2016-08-12 04:53:26 +03:00
|
|
|
eobtotal += reconstruct_inter_block(xd, r, mbmi->segment_id_supertx,
|
|
|
|
i, row, col, tx_size);
|
2015-11-20 03:51:16 +03:00
|
|
|
}
|
2016-08-12 04:53:26 +03:00
|
|
|
if (!(subsize < BLOCK_8X8) && eobtotal == 0) skip = 1;
|
2015-11-20 03:51:16 +03:00
|
|
|
}
|
2016-01-23 01:52:38 +03:00
|
|
|
set_param_topblock(cm, xd, bsize, mi_row, mi_col, txfm, skip);
|
2015-11-20 03:51:16 +03:00
|
|
|
}
|
|
|
|
#endif // CONFIG_SUPERTX
|
|
|
|
|
2016-03-17 19:50:28 +03:00
|
|
|
#if CONFIG_EXT_PARTITION_TYPES
|
|
|
|
if (bsize >= BLOCK_8X8) {
|
|
|
|
switch (partition) {
|
|
|
|
case PARTITION_SPLIT:
|
2016-08-12 04:53:26 +03:00
|
|
|
if (bsize > BLOCK_8X8) break;
|
2016-03-17 19:50:28 +03:00
|
|
|
case PARTITION_NONE:
|
|
|
|
case PARTITION_HORZ:
|
|
|
|
case PARTITION_VERT:
|
|
|
|
update_partition_context(xd, mi_row, mi_col, subsize, bsize);
|
|
|
|
break;
|
|
|
|
case PARTITION_HORZ_A:
|
|
|
|
update_partition_context(xd, mi_row, mi_col, bsize2, subsize);
|
|
|
|
update_partition_context(xd, mi_row + hbs, mi_col, subsize, subsize);
|
|
|
|
break;
|
|
|
|
case PARTITION_HORZ_B:
|
|
|
|
update_partition_context(xd, mi_row, mi_col, subsize, subsize);
|
|
|
|
update_partition_context(xd, mi_row + hbs, mi_col, bsize2, subsize);
|
|
|
|
break;
|
|
|
|
case PARTITION_VERT_A:
|
|
|
|
update_partition_context(xd, mi_row, mi_col, bsize2, subsize);
|
|
|
|
update_partition_context(xd, mi_row, mi_col + hbs, subsize, subsize);
|
|
|
|
break;
|
|
|
|
case PARTITION_VERT_B:
|
|
|
|
update_partition_context(xd, mi_row, mi_col, subsize, subsize);
|
|
|
|
update_partition_context(xd, mi_row, mi_col + hbs, bsize2, subsize);
|
|
|
|
break;
|
2016-08-12 04:53:26 +03:00
|
|
|
default: assert(0 && "Invalid partition type");
|
2016-03-17 19:50:28 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
#else
|
2015-08-06 05:00:31 +03:00
|
|
|
// update partition context
|
|
|
|
if (bsize >= BLOCK_8X8 &&
|
|
|
|
(bsize == BLOCK_8X8 || partition != PARTITION_SPLIT))
|
|
|
|
dec_update_partition_context(xd, mi_row, mi_col, subsize, num_8x8_wh);
|
2016-08-15 20:27:19 +03:00
|
|
|
#if DERING_REFINEMENT
|
|
|
|
if (bsize == BLOCK_64X64) {
|
|
|
|
if (cm->dering_level != 0 && !sb_all_skip(cm, mi_row, mi_col)) {
|
2016-08-19 01:10:22 +03:00
|
|
|
cm->mi_grid_visible[mi_row * cm->mi_stride + mi_col]->mbmi.dering_gain =
|
2016-08-31 00:01:10 +03:00
|
|
|
aom_read_literal(r, DERING_REFINEMENT_BITS);
|
2016-08-15 20:27:19 +03:00
|
|
|
} else {
|
2016-08-19 01:10:22 +03:00
|
|
|
cm->mi_grid_visible[mi_row * cm->mi_stride + mi_col]->mbmi.dering_gain =
|
|
|
|
0;
|
2016-08-15 20:27:19 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
#endif // DERGING_REFINEMENT
|
2016-03-17 19:50:28 +03:00
|
|
|
#endif // CONFIG_EXT_PARTITION_TYPES
|
2015-08-06 05:00:31 +03:00
|
|
|
}
|
|
|
|
|
2016-03-22 20:33:34 +03:00
|
|
|
#if !CONFIG_ANS
|
2016-08-12 04:53:26 +03:00
|
|
|
static void setup_bool_decoder(const uint8_t *data, const uint8_t *data_end,
|
2015-12-16 22:17:25 +03:00
|
|
|
const size_t read_size,
|
2016-08-31 00:01:10 +03:00
|
|
|
struct aom_internal_error_info *error_info,
|
|
|
|
aom_reader *r, aom_decrypt_cb decrypt_cb,
|
2015-12-16 22:17:25 +03:00
|
|
|
void *decrypt_state) {
|
|
|
|
// Validate the calculated partition length. If the buffer
|
|
|
|
// described by the partition can't be fully read, then restrict
|
|
|
|
// it to the portion that can be (for EC mode) or throw an error.
|
|
|
|
if (!read_is_valid(data, read_size, data_end))
|
2016-08-31 00:01:10 +03:00
|
|
|
aom_internal_error(error_info, AOM_CODEC_CORRUPT_FRAME,
|
2015-12-16 22:17:25 +03:00
|
|
|
"Truncated packet or corrupt tile length");
|
|
|
|
|
2016-08-31 00:01:10 +03:00
|
|
|
if (aom_reader_init(r, data, read_size, decrypt_cb, decrypt_state))
|
|
|
|
aom_internal_error(error_info, AOM_CODEC_MEM_ERROR,
|
2015-12-16 22:17:25 +03:00
|
|
|
"Failed to allocate bool decoder %d", 1);
|
|
|
|
}
|
2016-03-22 20:33:34 +03:00
|
|
|
#else
|
2016-08-12 04:53:26 +03:00
|
|
|
static void setup_token_decoder(const uint8_t *data, const uint8_t *data_end,
|
2015-12-16 22:17:25 +03:00
|
|
|
const size_t read_size,
|
2016-08-31 00:01:10 +03:00
|
|
|
struct aom_internal_error_info *error_info,
|
2015-12-16 22:17:25 +03:00
|
|
|
struct AnsDecoder *const ans,
|
2016-08-31 00:01:10 +03:00
|
|
|
aom_decrypt_cb decrypt_cb,
|
2015-08-06 05:00:31 +03:00
|
|
|
void *decrypt_state) {
|
2016-08-12 04:53:26 +03:00
|
|
|
(void)decrypt_cb;
|
|
|
|
(void)decrypt_state;
|
2015-08-06 05:00:31 +03:00
|
|
|
// Validate the calculated partition length. If the buffer
|
|
|
|
// described by the partition can't be fully read, then restrict
|
|
|
|
// it to the portion that can be (for EC mode) or throw an error.
|
|
|
|
if (!read_is_valid(data, read_size, data_end))
|
2016-08-31 00:01:10 +03:00
|
|
|
aom_internal_error(error_info, AOM_CODEC_CORRUPT_FRAME,
|
2015-08-06 05:00:31 +03:00
|
|
|
"Truncated packet or corrupt tile length");
|
|
|
|
|
2015-12-16 22:17:25 +03:00
|
|
|
if (read_size > INT_MAX || ans_read_init(ans, data, (int)read_size))
|
2016-08-31 00:01:10 +03:00
|
|
|
aom_internal_error(error_info, AOM_CODEC_MEM_ERROR,
|
2015-12-16 22:17:25 +03:00
|
|
|
"Failed to allocate token decoder %d", 1);
|
2015-08-06 05:00:31 +03:00
|
|
|
}
|
2016-02-05 18:50:57 +03:00
|
|
|
#endif
|
2015-08-06 05:00:31 +03:00
|
|
|
|
2016-08-31 00:01:10 +03:00
|
|
|
static void read_coef_probs_common(av1_coeff_probs_model *coef_probs,
|
|
|
|
aom_reader *r) {
|
2015-08-06 05:00:31 +03:00
|
|
|
int i, j, k, l, m;
|
|
|
|
|
2016-08-31 00:01:10 +03:00
|
|
|
if (aom_read_bit(r))
|
2015-08-06 05:00:31 +03:00
|
|
|
for (i = 0; i < PLANE_TYPES; ++i)
|
|
|
|
for (j = 0; j < REF_TYPES; ++j)
|
|
|
|
for (k = 0; k < COEF_BANDS; ++k)
|
|
|
|
for (l = 0; l < BAND_COEFF_CONTEXTS(k); ++l)
|
|
|
|
for (m = 0; m < UNCONSTRAINED_NODES; ++m)
|
2016-08-31 00:01:10 +03:00
|
|
|
av1_diff_update_prob(r, &coef_probs[i][j][k][l][m]);
|
2015-08-06 05:00:31 +03:00
|
|
|
}
|
|
|
|
|
2016-08-31 00:01:10 +03:00
|
|
|
static void read_coef_probs(FRAME_CONTEXT *fc, TX_MODE tx_mode, aom_reader *r) {
|
2016-08-12 04:53:26 +03:00
|
|
|
const TX_SIZE max_tx_size = tx_mode_to_biggest_tx_size[tx_mode];
|
|
|
|
TX_SIZE tx_size;
|
|
|
|
for (tx_size = TX_4X4; tx_size <= max_tx_size; ++tx_size)
|
|
|
|
read_coef_probs_common(fc->coef_probs[tx_size], r);
|
2016-02-19 23:51:15 +03:00
|
|
|
#if CONFIG_ANS
|
2016-08-31 00:01:10 +03:00
|
|
|
av1_coef_pareto_cdfs(fc);
|
2016-02-19 23:51:15 +03:00
|
|
|
#endif // CONFIG_ANS
|
2015-08-06 05:00:31 +03:00
|
|
|
}
|
|
|
|
|
2016-08-31 00:01:10 +03:00
|
|
|
static void setup_segmentation(AV1_COMMON *const cm,
|
|
|
|
struct aom_read_bit_buffer *rb) {
|
2015-09-03 23:08:29 +03:00
|
|
|
struct segmentation *const seg = &cm->seg;
|
2015-08-06 05:00:31 +03:00
|
|
|
int i, j;
|
|
|
|
|
|
|
|
seg->update_map = 0;
|
|
|
|
seg->update_data = 0;
|
|
|
|
|
2016-08-31 00:01:10 +03:00
|
|
|
seg->enabled = aom_rb_read_bit(rb);
|
2016-08-12 04:53:26 +03:00
|
|
|
if (!seg->enabled) return;
|
2015-08-06 05:00:31 +03:00
|
|
|
|
|
|
|
// Segmentation map update
|
2015-09-03 23:08:29 +03:00
|
|
|
if (frame_is_intra_only(cm) || cm->error_resilient_mode) {
|
|
|
|
seg->update_map = 1;
|
|
|
|
} else {
|
2016-08-31 00:01:10 +03:00
|
|
|
seg->update_map = aom_rb_read_bit(rb);
|
2015-09-03 23:08:29 +03:00
|
|
|
}
|
2015-08-06 05:00:31 +03:00
|
|
|
if (seg->update_map) {
|
2015-09-03 23:08:29 +03:00
|
|
|
if (frame_is_intra_only(cm) || cm->error_resilient_mode) {
|
|
|
|
seg->temporal_update = 0;
|
|
|
|
} else {
|
2016-08-31 00:01:10 +03:00
|
|
|
seg->temporal_update = aom_rb_read_bit(rb);
|
2015-09-03 23:08:29 +03:00
|
|
|
}
|
2015-08-06 05:00:31 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
// Segmentation data update
|
2016-08-31 00:01:10 +03:00
|
|
|
seg->update_data = aom_rb_read_bit(rb);
|
2015-08-06 05:00:31 +03:00
|
|
|
if (seg->update_data) {
|
2016-08-31 00:01:10 +03:00
|
|
|
seg->abs_delta = aom_rb_read_bit(rb);
|
2015-08-06 05:00:31 +03:00
|
|
|
|
2016-08-31 00:01:10 +03:00
|
|
|
av1_clearall_segfeatures(seg);
|
2015-08-06 05:00:31 +03:00
|
|
|
|
|
|
|
for (i = 0; i < MAX_SEGMENTS; i++) {
|
|
|
|
for (j = 0; j < SEG_LVL_MAX; j++) {
|
|
|
|
int data = 0;
|
2016-08-31 00:01:10 +03:00
|
|
|
const int feature_enabled = aom_rb_read_bit(rb);
|
2015-08-06 05:00:31 +03:00
|
|
|
if (feature_enabled) {
|
2016-08-31 00:01:10 +03:00
|
|
|
av1_enable_segfeature(seg, i, j);
|
|
|
|
data = decode_unsigned_max(rb, av1_seg_feature_data_max(j));
|
|
|
|
if (av1_is_segfeature_signed(j))
|
|
|
|
data = aom_rb_read_bit(rb) ? -data : data;
|
2015-08-06 05:00:31 +03:00
|
|
|
}
|
2016-08-31 00:01:10 +03:00
|
|
|
av1_set_segdata(seg, i, j, data);
|
2015-08-06 05:00:31 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-02-09 23:24:33 +03:00
|
|
|
#if CONFIG_LOOP_RESTORATION
|
2016-09-09 01:15:17 +03:00
|
|
|
static void decode_restoration_mode(AV1_COMMON *cm,
|
|
|
|
struct aom_read_bit_buffer *rb) {
|
2016-07-21 07:29:45 +03:00
|
|
|
RestorationInfo *rsi = &cm->rst_info;
|
2016-08-31 00:01:10 +03:00
|
|
|
if (aom_rb_read_bit(rb)) {
|
2016-09-09 01:15:17 +03:00
|
|
|
rsi->frame_restoration_type =
|
|
|
|
aom_rb_read_bit(rb) ? RESTORE_WIENER : RESTORE_BILATERAL;
|
|
|
|
} else {
|
|
|
|
rsi->frame_restoration_type =
|
|
|
|
aom_rb_read_bit(rb) ? RESTORE_SWITCHABLE : RESTORE_NONE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void decode_restoration(AV1_COMMON *cm, aom_reader *rb) {
|
|
|
|
int i;
|
|
|
|
RestorationInfo *rsi = &cm->rst_info;
|
2016-09-20 01:55:46 +03:00
|
|
|
const int ntiles =
|
|
|
|
av1_get_rest_ntiles(cm->width, cm->height, NULL, NULL, NULL, NULL);
|
2016-09-09 01:15:17 +03:00
|
|
|
if (rsi->frame_restoration_type != RESTORE_NONE) {
|
|
|
|
rsi->restoration_type = (RestorationType *)aom_realloc(
|
|
|
|
rsi->restoration_type, sizeof(*rsi->restoration_type) * ntiles);
|
|
|
|
if (rsi->frame_restoration_type == RESTORE_SWITCHABLE) {
|
2016-08-31 00:01:10 +03:00
|
|
|
rsi->bilateral_level = (int *)aom_realloc(
|
2016-09-09 01:15:17 +03:00
|
|
|
rsi->bilateral_level,
|
|
|
|
sizeof(*rsi->bilateral_level) * ntiles * BILATERAL_SUBTILES);
|
2016-07-21 07:29:45 +03:00
|
|
|
assert(rsi->bilateral_level != NULL);
|
2016-09-09 01:15:17 +03:00
|
|
|
rsi->wiener_level = (int *)aom_realloc(
|
|
|
|
rsi->wiener_level, sizeof(*rsi->wiener_level) * ntiles);
|
|
|
|
assert(rsi->wiener_level != NULL);
|
|
|
|
rsi->vfilter = (int(*)[RESTORATION_WIN])aom_realloc(
|
|
|
|
rsi->vfilter, sizeof(*rsi->vfilter) * ntiles);
|
|
|
|
assert(rsi->vfilter != NULL);
|
|
|
|
rsi->hfilter = (int(*)[RESTORATION_WIN])aom_realloc(
|
|
|
|
rsi->hfilter, sizeof(*rsi->hfilter) * ntiles);
|
|
|
|
assert(rsi->hfilter != NULL);
|
2016-07-21 07:29:45 +03:00
|
|
|
for (i = 0; i < ntiles; ++i) {
|
2016-09-09 01:15:17 +03:00
|
|
|
rsi->restoration_type[i] = aom_read_tree(
|
|
|
|
rb, av1_switchable_restore_tree, cm->fc->switchable_restore_prob);
|
|
|
|
if (rsi->restoration_type[i] == RESTORE_WIENER) {
|
|
|
|
rsi->wiener_level[i] = 1;
|
2016-09-20 01:55:46 +03:00
|
|
|
rsi->vfilter[i][0] = aom_read_literal(rb, WIENER_FILT_TAP0_BITS) +
|
|
|
|
WIENER_FILT_TAP0_MINV;
|
|
|
|
rsi->vfilter[i][1] = aom_read_literal(rb, WIENER_FILT_TAP1_BITS) +
|
|
|
|
WIENER_FILT_TAP1_MINV;
|
|
|
|
rsi->vfilter[i][2] = aom_read_literal(rb, WIENER_FILT_TAP2_BITS) +
|
|
|
|
WIENER_FILT_TAP2_MINV;
|
|
|
|
rsi->hfilter[i][0] = aom_read_literal(rb, WIENER_FILT_TAP0_BITS) +
|
|
|
|
WIENER_FILT_TAP0_MINV;
|
|
|
|
rsi->hfilter[i][1] = aom_read_literal(rb, WIENER_FILT_TAP1_BITS) +
|
|
|
|
WIENER_FILT_TAP1_MINV;
|
|
|
|
rsi->hfilter[i][2] = aom_read_literal(rb, WIENER_FILT_TAP2_BITS) +
|
|
|
|
WIENER_FILT_TAP2_MINV;
|
2016-09-09 01:15:17 +03:00
|
|
|
} else if (rsi->restoration_type[i] == RESTORE_BILATERAL) {
|
|
|
|
int s;
|
|
|
|
for (s = 0; s < BILATERAL_SUBTILES; ++s) {
|
|
|
|
const int j = i * BILATERAL_SUBTILES + s;
|
|
|
|
#if BILATERAL_SUBTILES == 0
|
|
|
|
rsi->bilateral_level[j] =
|
|
|
|
aom_read_literal(rb, av1_bilateral_level_bits(cm));
|
|
|
|
#else
|
|
|
|
if (aom_read(rb, RESTORE_NONE_BILATERAL_PROB)) {
|
|
|
|
rsi->bilateral_level[j] =
|
|
|
|
aom_read_literal(rb, av1_bilateral_level_bits(cm));
|
|
|
|
} else {
|
|
|
|
rsi->bilateral_level[j] = -1;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
}
|
2016-07-21 07:29:45 +03:00
|
|
|
}
|
|
|
|
}
|
2016-09-09 01:15:17 +03:00
|
|
|
} else if (rsi->frame_restoration_type == RESTORE_WIENER) {
|
2016-08-31 00:01:10 +03:00
|
|
|
rsi->wiener_level = (int *)aom_realloc(
|
2016-07-21 07:29:45 +03:00
|
|
|
rsi->wiener_level, sizeof(*rsi->wiener_level) * ntiles);
|
|
|
|
assert(rsi->wiener_level != NULL);
|
2016-09-09 01:15:17 +03:00
|
|
|
rsi->vfilter = (int(*)[RESTORATION_WIN])aom_realloc(
|
2016-07-21 07:29:45 +03:00
|
|
|
rsi->vfilter, sizeof(*rsi->vfilter) * ntiles);
|
|
|
|
assert(rsi->vfilter != NULL);
|
2016-09-09 01:15:17 +03:00
|
|
|
rsi->hfilter = (int(*)[RESTORATION_WIN])aom_realloc(
|
2016-07-21 07:29:45 +03:00
|
|
|
rsi->hfilter, sizeof(*rsi->hfilter) * ntiles);
|
|
|
|
assert(rsi->hfilter != NULL);
|
|
|
|
for (i = 0; i < ntiles; ++i) {
|
2016-09-09 01:15:17 +03:00
|
|
|
if (aom_read(rb, RESTORE_NONE_WIENER_PROB)) {
|
|
|
|
rsi->wiener_level[i] = 1;
|
|
|
|
rsi->restoration_type[i] = RESTORE_WIENER;
|
|
|
|
rsi->vfilter[i][0] = aom_read_literal(rb, WIENER_FILT_TAP0_BITS) +
|
2016-07-21 07:29:45 +03:00
|
|
|
WIENER_FILT_TAP0_MINV;
|
2016-09-09 01:15:17 +03:00
|
|
|
rsi->vfilter[i][1] = aom_read_literal(rb, WIENER_FILT_TAP1_BITS) +
|
2016-07-21 07:29:45 +03:00
|
|
|
WIENER_FILT_TAP1_MINV;
|
2016-09-09 01:15:17 +03:00
|
|
|
rsi->vfilter[i][2] = aom_read_literal(rb, WIENER_FILT_TAP2_BITS) +
|
2016-07-21 07:29:45 +03:00
|
|
|
WIENER_FILT_TAP2_MINV;
|
2016-09-09 01:15:17 +03:00
|
|
|
rsi->hfilter[i][0] = aom_read_literal(rb, WIENER_FILT_TAP0_BITS) +
|
2016-07-21 07:29:45 +03:00
|
|
|
WIENER_FILT_TAP0_MINV;
|
2016-09-09 01:15:17 +03:00
|
|
|
rsi->hfilter[i][1] = aom_read_literal(rb, WIENER_FILT_TAP1_BITS) +
|
2016-07-21 07:29:45 +03:00
|
|
|
WIENER_FILT_TAP1_MINV;
|
2016-09-09 01:15:17 +03:00
|
|
|
rsi->hfilter[i][2] = aom_read_literal(rb, WIENER_FILT_TAP2_BITS) +
|
2016-07-21 07:29:45 +03:00
|
|
|
WIENER_FILT_TAP2_MINV;
|
|
|
|
} else {
|
2016-09-09 01:15:17 +03:00
|
|
|
rsi->wiener_level[i] = 0;
|
|
|
|
rsi->restoration_type[i] = RESTORE_NONE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
rsi->frame_restoration_type = RESTORE_BILATERAL;
|
|
|
|
rsi->bilateral_level = (int *)aom_realloc(
|
|
|
|
rsi->bilateral_level,
|
|
|
|
sizeof(*rsi->bilateral_level) * ntiles * BILATERAL_SUBTILES);
|
|
|
|
assert(rsi->bilateral_level != NULL);
|
|
|
|
for (i = 0; i < ntiles; ++i) {
|
|
|
|
int s;
|
|
|
|
rsi->restoration_type[i] = RESTORE_BILATERAL;
|
|
|
|
for (s = 0; s < BILATERAL_SUBTILES; ++s) {
|
|
|
|
const int j = i * BILATERAL_SUBTILES + s;
|
|
|
|
if (aom_read(rb, RESTORE_NONE_BILATERAL_PROB)) {
|
|
|
|
rsi->bilateral_level[j] =
|
|
|
|
aom_read_literal(rb, av1_bilateral_level_bits(cm));
|
|
|
|
} else {
|
|
|
|
rsi->bilateral_level[j] = -1;
|
|
|
|
}
|
2016-07-21 07:29:45 +03:00
|
|
|
}
|
|
|
|
}
|
2016-02-09 23:24:33 +03:00
|
|
|
}
|
|
|
|
} else {
|
2016-09-09 01:15:17 +03:00
|
|
|
rsi->frame_restoration_type = RESTORE_NONE;
|
2016-02-09 23:24:33 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
#endif // CONFIG_LOOP_RESTORATION
|
|
|
|
|
2016-08-31 00:01:10 +03:00
|
|
|
static void setup_loopfilter(AV1_COMMON *cm, struct aom_read_bit_buffer *rb) {
|
2016-01-20 00:01:01 +03:00
|
|
|
struct loopfilter *lf = &cm->lf;
|
2016-08-31 00:01:10 +03:00
|
|
|
lf->filter_level = aom_rb_read_literal(rb, 6);
|
|
|
|
lf->sharpness_level = aom_rb_read_literal(rb, 3);
|
2015-08-06 05:00:31 +03:00
|
|
|
|
|
|
|
// Read in loop filter deltas applied at the MB level based on mode or ref
|
|
|
|
// frame.
|
|
|
|
lf->mode_ref_delta_update = 0;
|
|
|
|
|
2016-08-31 00:01:10 +03:00
|
|
|
lf->mode_ref_delta_enabled = aom_rb_read_bit(rb);
|
2015-08-06 05:00:31 +03:00
|
|
|
if (lf->mode_ref_delta_enabled) {
|
2016-08-31 00:01:10 +03:00
|
|
|
lf->mode_ref_delta_update = aom_rb_read_bit(rb);
|
2015-08-06 05:00:31 +03:00
|
|
|
if (lf->mode_ref_delta_update) {
|
|
|
|
int i;
|
|
|
|
|
Code refactoring on Macros related to ref frame numbers
We have renamed following Macros to avoid name confusion:
REFS_PER_FRAME --> INTER_REFS_PER_FRAME
(= ALTREF_FRAME - LAST_FRAME + 1)
MAX_REF_FRAMES --> TOTAL_REFS_PER_FRAME
(= ALTREF_FRAME - INTRA_FRAME + 1)
INTER_REFS_PER_FRAME specifies the maximum number of reference frames
that each Inter frame may use.
TOTAL_REFS_PER_FRAME is equal to INTER_REFS_PER_FRAME + 1, which
counts the INTRA_FRAME.
Further, at the encoder side, since REF_FRAMES specifies the maximum
number of the reference frames that the encoder may store, REF_FRAMES
is usually larger than INTER_REFS_PER_FRAME. For example, in the
ext-refs experiment, REF_FRAMES == 8, which allows the encoder to
store maximum 8 reference frames in the buffer, but
INTER_REFS_PER_FRAME equals to 6, which allows each Inter frame may
use up to 6 frames out of the 8 buffered frames as its references.
Hence, in order to explore the possibility to store more reference
frames in future patches, we modified a couple of array sizes to
accomodate the case that the number of buffered reference frames is
not always equal to the number of the references that are being used
by each Inter frame.
Change-Id: I19e42ef608946cc76ebfd3e965a05f4b9b93a0b3
2016-08-04 00:46:43 +03:00
|
|
|
for (i = 0; i < TOTAL_REFS_PER_FRAME; i++)
|
2016-08-31 00:01:10 +03:00
|
|
|
if (aom_rb_read_bit(rb))
|
|
|
|
lf->ref_deltas[i] = aom_rb_read_inv_signed_literal(rb, 6);
|
2015-08-06 05:00:31 +03:00
|
|
|
|
|
|
|
for (i = 0; i < MAX_MODE_LF_DELTAS; i++)
|
2016-08-31 00:01:10 +03:00
|
|
|
if (aom_rb_read_bit(rb))
|
|
|
|
lf->mode_deltas[i] = aom_rb_read_inv_signed_literal(rb, 6);
|
2015-08-06 05:00:31 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-08-11 19:39:47 +03:00
|
|
|
#if CONFIG_CLPF
|
2016-08-31 00:01:10 +03:00
|
|
|
static void setup_clpf(AV1_COMMON *cm, struct aom_read_bit_buffer *rb) {
|
|
|
|
cm->clpf = aom_rb_read_literal(rb, 1);
|
2016-08-11 19:39:47 +03:00
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2016-08-15 20:27:19 +03:00
|
|
|
#if CONFIG_DERING
|
2016-08-31 00:01:10 +03:00
|
|
|
static void setup_dering(AV1_COMMON *cm, struct aom_read_bit_buffer *rb) {
|
|
|
|
cm->dering_level = aom_rb_read_literal(rb, DERING_LEVEL_BITS);
|
2016-08-15 20:27:19 +03:00
|
|
|
}
|
|
|
|
#endif // CONFIG_DERING
|
|
|
|
|
2016-08-31 00:01:10 +03:00
|
|
|
static INLINE int read_delta_q(struct aom_read_bit_buffer *rb) {
|
|
|
|
return aom_rb_read_bit(rb) ? aom_rb_read_inv_signed_literal(rb, 6) : 0;
|
2015-08-06 05:00:31 +03:00
|
|
|
}
|
|
|
|
|
2016-08-31 00:01:10 +03:00
|
|
|
static void setup_quantization(AV1_COMMON *const cm,
|
|
|
|
struct aom_read_bit_buffer *rb) {
|
|
|
|
cm->base_qindex = aom_rb_read_literal(rb, QINDEX_BITS);
|
2015-08-06 05:00:31 +03:00
|
|
|
cm->y_dc_delta_q = read_delta_q(rb);
|
|
|
|
cm->uv_dc_delta_q = read_delta_q(rb);
|
|
|
|
cm->uv_ac_delta_q = read_delta_q(rb);
|
|
|
|
cm->dequant_bit_depth = cm->bit_depth;
|
2016-08-11 19:39:47 +03:00
|
|
|
#if CONFIG_AOM_QM
|
2016-08-31 00:01:10 +03:00
|
|
|
cm->using_qmatrix = aom_rb_read_bit(rb);
|
2016-08-11 19:39:47 +03:00
|
|
|
if (cm->using_qmatrix) {
|
2016-08-31 00:01:10 +03:00
|
|
|
cm->min_qmlevel = aom_rb_read_literal(rb, QM_LEVEL_BITS);
|
|
|
|
cm->max_qmlevel = aom_rb_read_literal(rb, QM_LEVEL_BITS);
|
2016-08-11 19:39:47 +03:00
|
|
|
} else {
|
|
|
|
cm->min_qmlevel = 0;
|
|
|
|
cm->max_qmlevel = 0;
|
|
|
|
}
|
|
|
|
#endif
|
2015-08-06 05:00:31 +03:00
|
|
|
}
|
|
|
|
|
2016-08-31 00:01:10 +03:00
|
|
|
static void setup_segmentation_dequant(AV1_COMMON *const cm) {
|
2016-08-11 19:39:47 +03:00
|
|
|
// Build y/uv dequant values based on segmentation.
|
|
|
|
int i = 0;
|
|
|
|
#if CONFIG_AOM_QM
|
|
|
|
int lossless;
|
|
|
|
int j = 0;
|
|
|
|
int qmlevel;
|
|
|
|
int using_qm = cm->using_qmatrix;
|
|
|
|
int minqm = cm->min_qmlevel;
|
|
|
|
int maxqm = cm->max_qmlevel;
|
|
|
|
#endif
|
2016-05-11 01:32:42 +03:00
|
|
|
#if CONFIG_NEW_QUANT
|
|
|
|
int b;
|
2016-06-11 01:29:10 +03:00
|
|
|
int dq;
|
|
|
|
#endif // CONFIG_NEW_QUANT
|
2015-08-06 05:00:31 +03:00
|
|
|
if (cm->seg.enabled) {
|
|
|
|
for (i = 0; i < MAX_SEGMENTS; ++i) {
|
2016-08-31 00:01:10 +03:00
|
|
|
const int qindex = av1_get_qindex(&cm->seg, i, cm->base_qindex);
|
2016-08-12 04:53:26 +03:00
|
|
|
cm->y_dequant[i][0] =
|
2016-08-31 00:01:10 +03:00
|
|
|
av1_dc_quant(qindex, cm->y_dc_delta_q, cm->bit_depth);
|
|
|
|
cm->y_dequant[i][1] = av1_ac_quant(qindex, 0, cm->bit_depth);
|
2016-08-12 04:53:26 +03:00
|
|
|
cm->uv_dequant[i][0] =
|
2016-08-31 00:01:10 +03:00
|
|
|
av1_dc_quant(qindex, cm->uv_dc_delta_q, cm->bit_depth);
|
2016-08-12 04:53:26 +03:00
|
|
|
cm->uv_dequant[i][1] =
|
2016-08-31 00:01:10 +03:00
|
|
|
av1_ac_quant(qindex, cm->uv_ac_delta_q, cm->bit_depth);
|
2016-08-11 19:39:47 +03:00
|
|
|
#if CONFIG_AOM_QM
|
|
|
|
lossless = qindex == 0 && cm->y_dc_delta_q == 0 &&
|
|
|
|
cm->uv_dc_delta_q == 0 && cm->uv_ac_delta_q == 0;
|
|
|
|
// NB: depends on base index so there is only 1 set per frame
|
|
|
|
// No quant weighting when lossless or signalled not using QM
|
|
|
|
qmlevel = (lossless || using_qm == 0)
|
|
|
|
? NUM_QM_LEVELS - 1
|
|
|
|
: aom_get_qmlevel(cm->base_qindex, minqm, maxqm);
|
|
|
|
for (j = 0; j < TX_SIZES; ++j) {
|
|
|
|
cm->y_iqmatrix[i][1][j] = aom_iqmatrix(cm, qmlevel, 0, j, 1);
|
|
|
|
cm->y_iqmatrix[i][0][j] = aom_iqmatrix(cm, qmlevel, 0, j, 0);
|
|
|
|
cm->uv_iqmatrix[i][1][j] = aom_iqmatrix(cm, qmlevel, 1, j, 1);
|
|
|
|
cm->uv_iqmatrix[i][0][j] = aom_iqmatrix(cm, qmlevel, 1, j, 0);
|
|
|
|
}
|
|
|
|
#endif // CONFIG_AOM_QM
|
2016-05-11 01:32:42 +03:00
|
|
|
#if CONFIG_NEW_QUANT
|
2016-08-12 04:53:26 +03:00
|
|
|
for (dq = 0; dq < QUANT_PROFILES; dq++) {
|
2016-06-11 01:29:10 +03:00
|
|
|
for (b = 0; b < COEF_BANDS; ++b) {
|
2016-08-31 00:01:10 +03:00
|
|
|
av1_get_dequant_val_nuq(cm->y_dequant[i][b != 0], qindex, b,
|
|
|
|
cm->y_dequant_nuq[i][dq][b], NULL, dq);
|
|
|
|
av1_get_dequant_val_nuq(cm->uv_dequant[i][b != 0], qindex, b,
|
|
|
|
cm->uv_dequant_nuq[i][dq][b], NULL, dq);
|
2016-06-11 01:29:10 +03:00
|
|
|
}
|
2016-05-11 01:32:42 +03:00
|
|
|
}
|
2016-06-11 01:29:10 +03:00
|
|
|
#endif // CONFIG_NEW_QUANT
|
2015-08-06 05:00:31 +03:00
|
|
|
}
|
|
|
|
} else {
|
|
|
|
const int qindex = cm->base_qindex;
|
|
|
|
// When segmentation is disabled, only the first value is used. The
|
|
|
|
// remaining are don't cares.
|
2016-08-31 00:01:10 +03:00
|
|
|
cm->y_dequant[0][0] = av1_dc_quant(qindex, cm->y_dc_delta_q, cm->bit_depth);
|
|
|
|
cm->y_dequant[0][1] = av1_ac_quant(qindex, 0, cm->bit_depth);
|
2016-08-12 04:53:26 +03:00
|
|
|
cm->uv_dequant[0][0] =
|
2016-08-31 00:01:10 +03:00
|
|
|
av1_dc_quant(qindex, cm->uv_dc_delta_q, cm->bit_depth);
|
2016-08-12 04:53:26 +03:00
|
|
|
cm->uv_dequant[0][1] =
|
2016-08-31 00:01:10 +03:00
|
|
|
av1_ac_quant(qindex, cm->uv_ac_delta_q, cm->bit_depth);
|
2016-08-11 19:39:47 +03:00
|
|
|
#if CONFIG_AOM_QM
|
|
|
|
lossless = qindex == 0 && cm->y_dc_delta_q == 0 && cm->uv_dc_delta_q == 0 &&
|
|
|
|
cm->uv_ac_delta_q == 0;
|
|
|
|
// No quant weighting when lossless or signalled not using QM
|
|
|
|
qmlevel = (lossless || using_qm == 0)
|
|
|
|
? NUM_QM_LEVELS - 1
|
|
|
|
: aom_get_qmlevel(cm->base_qindex, minqm, maxqm);
|
|
|
|
for (j = 0; j < TX_SIZES; ++j) {
|
|
|
|
cm->y_iqmatrix[i][1][j] = aom_iqmatrix(cm, qmlevel, 0, j, 1);
|
|
|
|
cm->y_iqmatrix[i][0][j] = aom_iqmatrix(cm, qmlevel, 0, j, 0);
|
|
|
|
cm->uv_iqmatrix[i][1][j] = aom_iqmatrix(cm, qmlevel, 1, j, 1);
|
|
|
|
cm->uv_iqmatrix[i][0][j] = aom_iqmatrix(cm, qmlevel, 1, j, 0);
|
|
|
|
}
|
|
|
|
#endif
|
2016-05-11 01:32:42 +03:00
|
|
|
#if CONFIG_NEW_QUANT
|
2016-08-12 04:53:26 +03:00
|
|
|
for (dq = 0; dq < QUANT_PROFILES; dq++) {
|
2016-06-11 01:29:10 +03:00
|
|
|
for (b = 0; b < COEF_BANDS; ++b) {
|
2016-08-31 00:01:10 +03:00
|
|
|
av1_get_dequant_val_nuq(cm->y_dequant[0][b != 0], qindex, b,
|
|
|
|
cm->y_dequant_nuq[0][dq][b], NULL, dq);
|
|
|
|
av1_get_dequant_val_nuq(cm->uv_dequant[0][b != 0], qindex, b,
|
|
|
|
cm->uv_dequant_nuq[0][dq][b], NULL, dq);
|
2016-06-11 01:29:10 +03:00
|
|
|
}
|
2016-05-11 01:32:42 +03:00
|
|
|
}
|
2016-06-11 01:29:10 +03:00
|
|
|
#endif // CONFIG_NEW_QUANT
|
2015-08-06 05:00:31 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-05-19 09:48:05 +03:00
|
|
|
static InterpFilter read_interp_filter(struct aom_read_bit_buffer *rb) {
|
2016-08-31 00:01:10 +03:00
|
|
|
return aom_rb_read_bit(rb) ? SWITCHABLE
|
|
|
|
: aom_rb_read_literal(rb, 2 + CONFIG_EXT_INTERP);
|
2015-08-06 05:00:31 +03:00
|
|
|
}
|
|
|
|
|
2016-08-31 00:01:10 +03:00
|
|
|
static void setup_render_size(AV1_COMMON *cm, struct aom_read_bit_buffer *rb) {
|
2015-09-29 01:55:46 +03:00
|
|
|
cm->render_width = cm->width;
|
|
|
|
cm->render_height = cm->height;
|
2016-08-31 00:01:10 +03:00
|
|
|
if (aom_rb_read_bit(rb))
|
|
|
|
av1_read_frame_size(rb, &cm->render_width, &cm->render_height);
|
2015-08-06 05:00:31 +03:00
|
|
|
}
|
|
|
|
|
2016-08-31 00:01:10 +03:00
|
|
|
static void resize_mv_buffer(AV1_COMMON *cm) {
|
|
|
|
aom_free(cm->cur_frame->mvs);
|
2015-08-06 05:00:31 +03:00
|
|
|
cm->cur_frame->mi_rows = cm->mi_rows;
|
|
|
|
cm->cur_frame->mi_cols = cm->mi_cols;
|
2016-02-18 01:26:16 +03:00
|
|
|
CHECK_MEM_ERROR(cm, cm->cur_frame->mvs,
|
2016-08-31 00:01:10 +03:00
|
|
|
(MV_REF *)aom_calloc(cm->mi_rows * cm->mi_cols,
|
2016-02-18 01:26:16 +03:00
|
|
|
sizeof(*cm->cur_frame->mvs)));
|
2015-08-06 05:00:31 +03:00
|
|
|
}
|
|
|
|
|
2016-08-31 00:01:10 +03:00
|
|
|
static void resize_context_buffers(AV1_COMMON *cm, int width, int height) {
|
2015-08-06 05:00:31 +03:00
|
|
|
#if CONFIG_SIZE_LIMIT
|
|
|
|
if (width > DECODE_WIDTH_LIMIT || height > DECODE_HEIGHT_LIMIT)
|
2016-08-31 00:01:10 +03:00
|
|
|
aom_internal_error(&cm->error, AOM_CODEC_CORRUPT_FRAME,
|
2015-08-06 05:00:31 +03:00
|
|
|
"Dimensions of %dx%d beyond allowed size of %dx%d.",
|
|
|
|
width, height, DECODE_WIDTH_LIMIT, DECODE_HEIGHT_LIMIT);
|
|
|
|
#endif
|
|
|
|
if (cm->width != width || cm->height != height) {
|
|
|
|
const int new_mi_rows =
|
|
|
|
ALIGN_POWER_OF_TWO(height, MI_SIZE_LOG2) >> MI_SIZE_LOG2;
|
|
|
|
const int new_mi_cols =
|
2016-08-12 04:53:26 +03:00
|
|
|
ALIGN_POWER_OF_TWO(width, MI_SIZE_LOG2) >> MI_SIZE_LOG2;
|
2015-08-06 05:00:31 +03:00
|
|
|
|
2016-08-31 00:01:10 +03:00
|
|
|
// Allocations in av1_alloc_context_buffers() depend on individual
|
2015-08-06 05:00:31 +03:00
|
|
|
// dimensions as well as the overall size.
|
|
|
|
if (new_mi_cols > cm->mi_cols || new_mi_rows > cm->mi_rows) {
|
2016-08-31 00:01:10 +03:00
|
|
|
if (av1_alloc_context_buffers(cm, width, height))
|
|
|
|
aom_internal_error(&cm->error, AOM_CODEC_MEM_ERROR,
|
2015-08-06 05:00:31 +03:00
|
|
|
"Failed to allocate context buffers");
|
|
|
|
} else {
|
2016-08-31 00:01:10 +03:00
|
|
|
av1_set_mb_mi(cm, width, height);
|
2015-08-06 05:00:31 +03:00
|
|
|
}
|
2016-08-31 00:01:10 +03:00
|
|
|
av1_init_context_buffers(cm);
|
2015-08-06 05:00:31 +03:00
|
|
|
cm->width = width;
|
|
|
|
cm->height = height;
|
|
|
|
}
|
|
|
|
if (cm->cur_frame->mvs == NULL || cm->mi_rows > cm->cur_frame->mi_rows ||
|
|
|
|
cm->mi_cols > cm->cur_frame->mi_cols) {
|
|
|
|
resize_mv_buffer(cm);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-08-31 00:01:10 +03:00
|
|
|
static void setup_frame_size(AV1_COMMON *cm, struct aom_read_bit_buffer *rb) {
|
2015-08-06 05:00:31 +03:00
|
|
|
int width, height;
|
|
|
|
BufferPool *const pool = cm->buffer_pool;
|
2016-08-31 00:01:10 +03:00
|
|
|
av1_read_frame_size(rb, &width, &height);
|
2015-08-06 05:00:31 +03:00
|
|
|
resize_context_buffers(cm, width, height);
|
2015-09-29 01:55:46 +03:00
|
|
|
setup_render_size(cm, rb);
|
2015-08-06 05:00:31 +03:00
|
|
|
|
|
|
|
lock_buffer_pool(pool);
|
2016-08-31 00:01:10 +03:00
|
|
|
if (aom_realloc_frame_buffer(
|
2016-08-12 04:53:26 +03:00
|
|
|
get_frame_new_buffer(cm), cm->width, cm->height, cm->subsampling_x,
|
|
|
|
cm->subsampling_y,
|
2016-08-31 00:01:10 +03:00
|
|
|
#if CONFIG_AOM_HIGHBITDEPTH
|
2015-08-06 05:00:31 +03:00
|
|
|
cm->use_highbitdepth,
|
|
|
|
#endif
|
2016-08-31 00:01:10 +03:00
|
|
|
AOM_DEC_BORDER_IN_PIXELS, cm->byte_alignment,
|
2015-08-06 05:00:31 +03:00
|
|
|
&pool->frame_bufs[cm->new_fb_idx].raw_frame_buffer, pool->get_fb_cb,
|
|
|
|
pool->cb_priv)) {
|
|
|
|
unlock_buffer_pool(pool);
|
2016-08-31 00:01:10 +03:00
|
|
|
aom_internal_error(&cm->error, AOM_CODEC_MEM_ERROR,
|
2015-08-06 05:00:31 +03:00
|
|
|
"Failed to allocate frame buffer");
|
|
|
|
}
|
|
|
|
unlock_buffer_pool(pool);
|
|
|
|
|
|
|
|
pool->frame_bufs[cm->new_fb_idx].buf.subsampling_x = cm->subsampling_x;
|
|
|
|
pool->frame_bufs[cm->new_fb_idx].buf.subsampling_y = cm->subsampling_y;
|
|
|
|
pool->frame_bufs[cm->new_fb_idx].buf.bit_depth = (unsigned int)cm->bit_depth;
|
|
|
|
pool->frame_bufs[cm->new_fb_idx].buf.color_space = cm->color_space;
|
2015-09-16 04:56:51 +03:00
|
|
|
pool->frame_bufs[cm->new_fb_idx].buf.color_range = cm->color_range;
|
2016-08-12 04:53:26 +03:00
|
|
|
pool->frame_bufs[cm->new_fb_idx].buf.render_width = cm->render_width;
|
2015-09-29 01:55:46 +03:00
|
|
|
pool->frame_bufs[cm->new_fb_idx].buf.render_height = cm->render_height;
|
2015-08-06 05:00:31 +03:00
|
|
|
}
|
|
|
|
|
2016-08-31 00:01:10 +03:00
|
|
|
static INLINE int valid_ref_frame_img_fmt(aom_bit_depth_t ref_bit_depth,
|
2015-08-06 05:00:31 +03:00
|
|
|
int ref_xss, int ref_yss,
|
2016-08-31 00:01:10 +03:00
|
|
|
aom_bit_depth_t this_bit_depth,
|
2015-08-06 05:00:31 +03:00
|
|
|
int this_xss, int this_yss) {
|
|
|
|
return ref_bit_depth == this_bit_depth && ref_xss == this_xss &&
|
|
|
|
ref_yss == this_yss;
|
|
|
|
}
|
|
|
|
|
2016-08-31 00:01:10 +03:00
|
|
|
static void setup_frame_size_with_refs(AV1_COMMON *cm,
|
|
|
|
struct aom_read_bit_buffer *rb) {
|
2015-08-06 05:00:31 +03:00
|
|
|
int width, height;
|
|
|
|
int found = 0, i;
|
|
|
|
int has_valid_ref_frame = 0;
|
|
|
|
BufferPool *const pool = cm->buffer_pool;
|
Code refactoring on Macros related to ref frame numbers
We have renamed following Macros to avoid name confusion:
REFS_PER_FRAME --> INTER_REFS_PER_FRAME
(= ALTREF_FRAME - LAST_FRAME + 1)
MAX_REF_FRAMES --> TOTAL_REFS_PER_FRAME
(= ALTREF_FRAME - INTRA_FRAME + 1)
INTER_REFS_PER_FRAME specifies the maximum number of reference frames
that each Inter frame may use.
TOTAL_REFS_PER_FRAME is equal to INTER_REFS_PER_FRAME + 1, which
counts the INTRA_FRAME.
Further, at the encoder side, since REF_FRAMES specifies the maximum
number of the reference frames that the encoder may store, REF_FRAMES
is usually larger than INTER_REFS_PER_FRAME. For example, in the
ext-refs experiment, REF_FRAMES == 8, which allows the encoder to
store maximum 8 reference frames in the buffer, but
INTER_REFS_PER_FRAME equals to 6, which allows each Inter frame may
use up to 6 frames out of the 8 buffered frames as its references.
Hence, in order to explore the possibility to store more reference
frames in future patches, we modified a couple of array sizes to
accomodate the case that the number of buffered reference frames is
not always equal to the number of the references that are being used
by each Inter frame.
Change-Id: I19e42ef608946cc76ebfd3e965a05f4b9b93a0b3
2016-08-04 00:46:43 +03:00
|
|
|
for (i = 0; i < INTER_REFS_PER_FRAME; ++i) {
|
2016-08-31 00:01:10 +03:00
|
|
|
if (aom_rb_read_bit(rb)) {
|
2015-08-06 05:00:31 +03:00
|
|
|
YV12_BUFFER_CONFIG *const buf = cm->frame_refs[i].buf;
|
|
|
|
width = buf->y_crop_width;
|
|
|
|
height = buf->y_crop_height;
|
2015-10-01 04:57:26 +03:00
|
|
|
cm->render_width = buf->render_width;
|
|
|
|
cm->render_height = buf->render_height;
|
2015-08-06 05:00:31 +03:00
|
|
|
found = 1;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-10-01 04:57:26 +03:00
|
|
|
if (!found) {
|
2016-08-31 00:01:10 +03:00
|
|
|
av1_read_frame_size(rb, &width, &height);
|
2015-10-01 04:57:26 +03:00
|
|
|
setup_render_size(cm, rb);
|
|
|
|
}
|
2015-08-06 05:00:31 +03:00
|
|
|
|
|
|
|
if (width <= 0 || height <= 0)
|
2016-08-31 00:01:10 +03:00
|
|
|
aom_internal_error(&cm->error, AOM_CODEC_CORRUPT_FRAME,
|
2015-08-06 05:00:31 +03:00
|
|
|
"Invalid frame size");
|
|
|
|
|
|
|
|
// Check to make sure at least one of frames that this frame references
|
|
|
|
// has valid dimensions.
|
Code refactoring on Macros related to ref frame numbers
We have renamed following Macros to avoid name confusion:
REFS_PER_FRAME --> INTER_REFS_PER_FRAME
(= ALTREF_FRAME - LAST_FRAME + 1)
MAX_REF_FRAMES --> TOTAL_REFS_PER_FRAME
(= ALTREF_FRAME - INTRA_FRAME + 1)
INTER_REFS_PER_FRAME specifies the maximum number of reference frames
that each Inter frame may use.
TOTAL_REFS_PER_FRAME is equal to INTER_REFS_PER_FRAME + 1, which
counts the INTRA_FRAME.
Further, at the encoder side, since REF_FRAMES specifies the maximum
number of the reference frames that the encoder may store, REF_FRAMES
is usually larger than INTER_REFS_PER_FRAME. For example, in the
ext-refs experiment, REF_FRAMES == 8, which allows the encoder to
store maximum 8 reference frames in the buffer, but
INTER_REFS_PER_FRAME equals to 6, which allows each Inter frame may
use up to 6 frames out of the 8 buffered frames as its references.
Hence, in order to explore the possibility to store more reference
frames in future patches, we modified a couple of array sizes to
accomodate the case that the number of buffered reference frames is
not always equal to the number of the references that are being used
by each Inter frame.
Change-Id: I19e42ef608946cc76ebfd3e965a05f4b9b93a0b3
2016-08-04 00:46:43 +03:00
|
|
|
for (i = 0; i < INTER_REFS_PER_FRAME; ++i) {
|
2015-08-06 05:00:31 +03:00
|
|
|
RefBuffer *const ref_frame = &cm->frame_refs[i];
|
2016-08-12 04:53:26 +03:00
|
|
|
has_valid_ref_frame |=
|
|
|
|
valid_ref_frame_size(ref_frame->buf->y_crop_width,
|
|
|
|
ref_frame->buf->y_crop_height, width, height);
|
2015-08-06 05:00:31 +03:00
|
|
|
}
|
|
|
|
if (!has_valid_ref_frame)
|
2016-08-31 00:01:10 +03:00
|
|
|
aom_internal_error(&cm->error, AOM_CODEC_CORRUPT_FRAME,
|
2015-08-06 05:00:31 +03:00
|
|
|
"Referenced frame has invalid size");
|
Code refactoring on Macros related to ref frame numbers
We have renamed following Macros to avoid name confusion:
REFS_PER_FRAME --> INTER_REFS_PER_FRAME
(= ALTREF_FRAME - LAST_FRAME + 1)
MAX_REF_FRAMES --> TOTAL_REFS_PER_FRAME
(= ALTREF_FRAME - INTRA_FRAME + 1)
INTER_REFS_PER_FRAME specifies the maximum number of reference frames
that each Inter frame may use.
TOTAL_REFS_PER_FRAME is equal to INTER_REFS_PER_FRAME + 1, which
counts the INTRA_FRAME.
Further, at the encoder side, since REF_FRAMES specifies the maximum
number of the reference frames that the encoder may store, REF_FRAMES
is usually larger than INTER_REFS_PER_FRAME. For example, in the
ext-refs experiment, REF_FRAMES == 8, which allows the encoder to
store maximum 8 reference frames in the buffer, but
INTER_REFS_PER_FRAME equals to 6, which allows each Inter frame may
use up to 6 frames out of the 8 buffered frames as its references.
Hence, in order to explore the possibility to store more reference
frames in future patches, we modified a couple of array sizes to
accomodate the case that the number of buffered reference frames is
not always equal to the number of the references that are being used
by each Inter frame.
Change-Id: I19e42ef608946cc76ebfd3e965a05f4b9b93a0b3
2016-08-04 00:46:43 +03:00
|
|
|
for (i = 0; i < INTER_REFS_PER_FRAME; ++i) {
|
2015-08-06 05:00:31 +03:00
|
|
|
RefBuffer *const ref_frame = &cm->frame_refs[i];
|
2016-08-12 04:53:26 +03:00
|
|
|
if (!valid_ref_frame_img_fmt(ref_frame->buf->bit_depth,
|
|
|
|
ref_frame->buf->subsampling_x,
|
|
|
|
ref_frame->buf->subsampling_y, cm->bit_depth,
|
|
|
|
cm->subsampling_x, cm->subsampling_y))
|
2016-08-31 00:01:10 +03:00
|
|
|
aom_internal_error(&cm->error, AOM_CODEC_CORRUPT_FRAME,
|
2015-08-06 05:00:31 +03:00
|
|
|
"Referenced frame has incompatible color format");
|
|
|
|
}
|
|
|
|
|
|
|
|
resize_context_buffers(cm, width, height);
|
|
|
|
|
|
|
|
lock_buffer_pool(pool);
|
2016-08-31 00:01:10 +03:00
|
|
|
if (aom_realloc_frame_buffer(
|
2016-08-12 04:53:26 +03:00
|
|
|
get_frame_new_buffer(cm), cm->width, cm->height, cm->subsampling_x,
|
|
|
|
cm->subsampling_y,
|
2016-08-31 00:01:10 +03:00
|
|
|
#if CONFIG_AOM_HIGHBITDEPTH
|
2015-08-06 05:00:31 +03:00
|
|
|
cm->use_highbitdepth,
|
|
|
|
#endif
|
2016-08-31 00:01:10 +03:00
|
|
|
AOM_DEC_BORDER_IN_PIXELS, cm->byte_alignment,
|
2015-08-06 05:00:31 +03:00
|
|
|
&pool->frame_bufs[cm->new_fb_idx].raw_frame_buffer, pool->get_fb_cb,
|
|
|
|
pool->cb_priv)) {
|
|
|
|
unlock_buffer_pool(pool);
|
2016-08-31 00:01:10 +03:00
|
|
|
aom_internal_error(&cm->error, AOM_CODEC_MEM_ERROR,
|
2015-08-06 05:00:31 +03:00
|
|
|
"Failed to allocate frame buffer");
|
|
|
|
}
|
|
|
|
unlock_buffer_pool(pool);
|
|
|
|
|
|
|
|
pool->frame_bufs[cm->new_fb_idx].buf.subsampling_x = cm->subsampling_x;
|
|
|
|
pool->frame_bufs[cm->new_fb_idx].buf.subsampling_y = cm->subsampling_y;
|
|
|
|
pool->frame_bufs[cm->new_fb_idx].buf.bit_depth = (unsigned int)cm->bit_depth;
|
|
|
|
pool->frame_bufs[cm->new_fb_idx].buf.color_space = cm->color_space;
|
2015-09-16 04:56:51 +03:00
|
|
|
pool->frame_bufs[cm->new_fb_idx].buf.color_range = cm->color_range;
|
2016-08-12 04:53:26 +03:00
|
|
|
pool->frame_bufs[cm->new_fb_idx].buf.render_width = cm->render_width;
|
2015-09-29 01:55:46 +03:00
|
|
|
pool->frame_bufs[cm->new_fb_idx].buf.render_height = cm->render_height;
|
2015-08-06 05:00:31 +03:00
|
|
|
}
|
|
|
|
|
2016-08-31 00:01:10 +03:00
|
|
|
static void read_tile_info(AV1Decoder *const pbi,
|
|
|
|
struct aom_read_bit_buffer *const rb) {
|
|
|
|
AV1_COMMON *const cm = &pbi->common;
|
2016-03-11 20:42:49 +03:00
|
|
|
#if CONFIG_EXT_TILE
|
2016-08-12 04:53:26 +03:00
|
|
|
// Read the tile width/height
|
Make superblock size variable at the frame level.
The uncompressed frame header contains a bit to signal whether the
frame is encoded using 64x64 or 128x128 superblocks. This can vary
between any 2 frames.
vpxenc gained the --sb-size={64,128,dynamic} option, which allows the
configuration of the superblock size used (default is dynamic). 64/128
will force the encoder to always use the specified superblock size.
Dynamic would enable the encoder to choose the sb size for each
frame, but this is not implemented yet (dynamic does the same as 128
for now).
Constraints on tile sizes depend on the superblock size, the following
is a summary of the current bitstream syntax and semantics:
If both --enable-ext-tile is OFF and --enable-ext-partition is OFF:
The tile coding in this case is the same as VP9. In particular,
tiles have a minimum width of 256 pixels and a maximum width of
4096 pixels. The tile width must be multiples of 64 pixels
(except for the rightmost tile column). There can be a maximum
of 64 tile columns and 4 tile rows.
If --enable-ext-tile is OFF and --enable-ext-partition is ON:
Same constraints as above, except that tile width must be
multiples of 128 pixels (except for the rightmost tile column).
There is no change in the bitstream syntax used for coding the tile
configuration if --enable-ext-tile is OFF.
If --enable-ext-tile is ON and --enable-ext-partition is ON:
This is the new large scale tile coding configuration. The
minimum/maximum tile width and height are 64/4096 pixels. Tile
width and height must be multiples of 64 pixels. The uncompressed
header contains two 6 bit fields that hold the tile width/heigh
in units of 64 pixels. The maximum number of tile rows/columns
is only limited by the maximum frame size of 65536x65536 pixels
that can be coded in the bitstream. This yields a maximum of
1024x1024 tile rows and columns (of 64x64 tiles in a 65536x65536
frame).
If both --enable-ext-tile is ON and --enable-ext-partition is ON:
Same applies as above, except that in the bitstream the 2 fields
containing the tile width/height are in units of the superblock
size, and the superblock size itself is also coded in the bitstream.
If the uncompressed header signals the use of 64x64 superblocks,
then the tile width/height fields are 6 bits wide and are in units
of 64 pixels. If the uncompressed header signals the use of 128x128
superblocks, then the tile width/height fields are 5 bits wide and
are in units of 128 pixels.
The above is a summary of the bitstream. The user interface to vpxenc
(and the equivalent encoder API) behaves a follows:
If --enable-ext-tile is OFF:
No change in the user interface. --tile-columns and --tile-rows
specify the base 2 logarithm of the desired number of tile columns
and tile rows. The actual number of tile rows and tile columns,
and the particular tile width and tile height are computed by the
codec ensuring all of the above constraints are respected.
If --enable-ext-tile is ON, but --enable-ext-partition is OFF:
No change in the user interface. --tile-columns and --tile-rows
specify the WIDTH and HEIGHT of the tiles in unit of 64 pixels.
The valid values are in the range [1, 64] (which corresponds to
[64, 4096] pixels in increments of 64.
If both --enable-ext-tile is ON and --enable-ext-partition is ON:
If --sb-size=64 (default):
The user interface is the same as in the previous point.
--tile-columns and --tile-rows specify tile WIDTH and HEIGHT,
in units of 64 pixels, in the range [1, 64] (which corresponds
to [64, 4096] pixels in increments of 64).
If --sb-size=128 or --sb-size=dynamic:
--tile-columns and --tile-rows specify tile WIDTH and HEIGHT,
in units of 128 pixels in the range [1, 32] (which corresponds
to [128, 4096] pixels in increments of 128).
Change-Id: Idc9beee1ad12ff1634e83671985d14c680f9179a
2016-03-24 16:56:05 +03:00
|
|
|
#if CONFIG_EXT_PARTITION
|
|
|
|
if (cm->sb_size == BLOCK_128X128) {
|
2016-08-31 00:01:10 +03:00
|
|
|
cm->tile_width = aom_rb_read_literal(rb, 5) + 1;
|
|
|
|
cm->tile_height = aom_rb_read_literal(rb, 5) + 1;
|
Make superblock size variable at the frame level.
The uncompressed frame header contains a bit to signal whether the
frame is encoded using 64x64 or 128x128 superblocks. This can vary
between any 2 frames.
vpxenc gained the --sb-size={64,128,dynamic} option, which allows the
configuration of the superblock size used (default is dynamic). 64/128
will force the encoder to always use the specified superblock size.
Dynamic would enable the encoder to choose the sb size for each
frame, but this is not implemented yet (dynamic does the same as 128
for now).
Constraints on tile sizes depend on the superblock size, the following
is a summary of the current bitstream syntax and semantics:
If both --enable-ext-tile is OFF and --enable-ext-partition is OFF:
The tile coding in this case is the same as VP9. In particular,
tiles have a minimum width of 256 pixels and a maximum width of
4096 pixels. The tile width must be multiples of 64 pixels
(except for the rightmost tile column). There can be a maximum
of 64 tile columns and 4 tile rows.
If --enable-ext-tile is OFF and --enable-ext-partition is ON:
Same constraints as above, except that tile width must be
multiples of 128 pixels (except for the rightmost tile column).
There is no change in the bitstream syntax used for coding the tile
configuration if --enable-ext-tile is OFF.
If --enable-ext-tile is ON and --enable-ext-partition is ON:
This is the new large scale tile coding configuration. The
minimum/maximum tile width and height are 64/4096 pixels. Tile
width and height must be multiples of 64 pixels. The uncompressed
header contains two 6 bit fields that hold the tile width/heigh
in units of 64 pixels. The maximum number of tile rows/columns
is only limited by the maximum frame size of 65536x65536 pixels
that can be coded in the bitstream. This yields a maximum of
1024x1024 tile rows and columns (of 64x64 tiles in a 65536x65536
frame).
If both --enable-ext-tile is ON and --enable-ext-partition is ON:
Same applies as above, except that in the bitstream the 2 fields
containing the tile width/height are in units of the superblock
size, and the superblock size itself is also coded in the bitstream.
If the uncompressed header signals the use of 64x64 superblocks,
then the tile width/height fields are 6 bits wide and are in units
of 64 pixels. If the uncompressed header signals the use of 128x128
superblocks, then the tile width/height fields are 5 bits wide and
are in units of 128 pixels.
The above is a summary of the bitstream. The user interface to vpxenc
(and the equivalent encoder API) behaves a follows:
If --enable-ext-tile is OFF:
No change in the user interface. --tile-columns and --tile-rows
specify the base 2 logarithm of the desired number of tile columns
and tile rows. The actual number of tile rows and tile columns,
and the particular tile width and tile height are computed by the
codec ensuring all of the above constraints are respected.
If --enable-ext-tile is ON, but --enable-ext-partition is OFF:
No change in the user interface. --tile-columns and --tile-rows
specify the WIDTH and HEIGHT of the tiles in unit of 64 pixels.
The valid values are in the range [1, 64] (which corresponds to
[64, 4096] pixels in increments of 64.
If both --enable-ext-tile is ON and --enable-ext-partition is ON:
If --sb-size=64 (default):
The user interface is the same as in the previous point.
--tile-columns and --tile-rows specify tile WIDTH and HEIGHT,
in units of 64 pixels, in the range [1, 64] (which corresponds
to [64, 4096] pixels in increments of 64).
If --sb-size=128 or --sb-size=dynamic:
--tile-columns and --tile-rows specify tile WIDTH and HEIGHT,
in units of 128 pixels in the range [1, 32] (which corresponds
to [128, 4096] pixels in increments of 128).
Change-Id: Idc9beee1ad12ff1634e83671985d14c680f9179a
2016-03-24 16:56:05 +03:00
|
|
|
} else
|
|
|
|
#endif // CONFIG_EXT_PARTITION
|
|
|
|
{
|
2016-08-31 00:01:10 +03:00
|
|
|
cm->tile_width = aom_rb_read_literal(rb, 6) + 1;
|
|
|
|
cm->tile_height = aom_rb_read_literal(rb, 6) + 1;
|
Make superblock size variable at the frame level.
The uncompressed frame header contains a bit to signal whether the
frame is encoded using 64x64 or 128x128 superblocks. This can vary
between any 2 frames.
vpxenc gained the --sb-size={64,128,dynamic} option, which allows the
configuration of the superblock size used (default is dynamic). 64/128
will force the encoder to always use the specified superblock size.
Dynamic would enable the encoder to choose the sb size for each
frame, but this is not implemented yet (dynamic does the same as 128
for now).
Constraints on tile sizes depend on the superblock size, the following
is a summary of the current bitstream syntax and semantics:
If both --enable-ext-tile is OFF and --enable-ext-partition is OFF:
The tile coding in this case is the same as VP9. In particular,
tiles have a minimum width of 256 pixels and a maximum width of
4096 pixels. The tile width must be multiples of 64 pixels
(except for the rightmost tile column). There can be a maximum
of 64 tile columns and 4 tile rows.
If --enable-ext-tile is OFF and --enable-ext-partition is ON:
Same constraints as above, except that tile width must be
multiples of 128 pixels (except for the rightmost tile column).
There is no change in the bitstream syntax used for coding the tile
configuration if --enable-ext-tile is OFF.
If --enable-ext-tile is ON and --enable-ext-partition is ON:
This is the new large scale tile coding configuration. The
minimum/maximum tile width and height are 64/4096 pixels. Tile
width and height must be multiples of 64 pixels. The uncompressed
header contains two 6 bit fields that hold the tile width/heigh
in units of 64 pixels. The maximum number of tile rows/columns
is only limited by the maximum frame size of 65536x65536 pixels
that can be coded in the bitstream. This yields a maximum of
1024x1024 tile rows and columns (of 64x64 tiles in a 65536x65536
frame).
If both --enable-ext-tile is ON and --enable-ext-partition is ON:
Same applies as above, except that in the bitstream the 2 fields
containing the tile width/height are in units of the superblock
size, and the superblock size itself is also coded in the bitstream.
If the uncompressed header signals the use of 64x64 superblocks,
then the tile width/height fields are 6 bits wide and are in units
of 64 pixels. If the uncompressed header signals the use of 128x128
superblocks, then the tile width/height fields are 5 bits wide and
are in units of 128 pixels.
The above is a summary of the bitstream. The user interface to vpxenc
(and the equivalent encoder API) behaves a follows:
If --enable-ext-tile is OFF:
No change in the user interface. --tile-columns and --tile-rows
specify the base 2 logarithm of the desired number of tile columns
and tile rows. The actual number of tile rows and tile columns,
and the particular tile width and tile height are computed by the
codec ensuring all of the above constraints are respected.
If --enable-ext-tile is ON, but --enable-ext-partition is OFF:
No change in the user interface. --tile-columns and --tile-rows
specify the WIDTH and HEIGHT of the tiles in unit of 64 pixels.
The valid values are in the range [1, 64] (which corresponds to
[64, 4096] pixels in increments of 64.
If both --enable-ext-tile is ON and --enable-ext-partition is ON:
If --sb-size=64 (default):
The user interface is the same as in the previous point.
--tile-columns and --tile-rows specify tile WIDTH and HEIGHT,
in units of 64 pixels, in the range [1, 64] (which corresponds
to [64, 4096] pixels in increments of 64).
If --sb-size=128 or --sb-size=dynamic:
--tile-columns and --tile-rows specify tile WIDTH and HEIGHT,
in units of 128 pixels in the range [1, 32] (which corresponds
to [128, 4096] pixels in increments of 128).
Change-Id: Idc9beee1ad12ff1634e83671985d14c680f9179a
2016-03-24 16:56:05 +03:00
|
|
|
}
|
2016-03-11 20:42:49 +03:00
|
|
|
|
2016-08-12 04:53:26 +03:00
|
|
|
cm->tile_width <<= cm->mib_size_log2;
|
Make superblock size variable at the frame level.
The uncompressed frame header contains a bit to signal whether the
frame is encoded using 64x64 or 128x128 superblocks. This can vary
between any 2 frames.
vpxenc gained the --sb-size={64,128,dynamic} option, which allows the
configuration of the superblock size used (default is dynamic). 64/128
will force the encoder to always use the specified superblock size.
Dynamic would enable the encoder to choose the sb size for each
frame, but this is not implemented yet (dynamic does the same as 128
for now).
Constraints on tile sizes depend on the superblock size, the following
is a summary of the current bitstream syntax and semantics:
If both --enable-ext-tile is OFF and --enable-ext-partition is OFF:
The tile coding in this case is the same as VP9. In particular,
tiles have a minimum width of 256 pixels and a maximum width of
4096 pixels. The tile width must be multiples of 64 pixels
(except for the rightmost tile column). There can be a maximum
of 64 tile columns and 4 tile rows.
If --enable-ext-tile is OFF and --enable-ext-partition is ON:
Same constraints as above, except that tile width must be
multiples of 128 pixels (except for the rightmost tile column).
There is no change in the bitstream syntax used for coding the tile
configuration if --enable-ext-tile is OFF.
If --enable-ext-tile is ON and --enable-ext-partition is ON:
This is the new large scale tile coding configuration. The
minimum/maximum tile width and height are 64/4096 pixels. Tile
width and height must be multiples of 64 pixels. The uncompressed
header contains two 6 bit fields that hold the tile width/heigh
in units of 64 pixels. The maximum number of tile rows/columns
is only limited by the maximum frame size of 65536x65536 pixels
that can be coded in the bitstream. This yields a maximum of
1024x1024 tile rows and columns (of 64x64 tiles in a 65536x65536
frame).
If both --enable-ext-tile is ON and --enable-ext-partition is ON:
Same applies as above, except that in the bitstream the 2 fields
containing the tile width/height are in units of the superblock
size, and the superblock size itself is also coded in the bitstream.
If the uncompressed header signals the use of 64x64 superblocks,
then the tile width/height fields are 6 bits wide and are in units
of 64 pixels. If the uncompressed header signals the use of 128x128
superblocks, then the tile width/height fields are 5 bits wide and
are in units of 128 pixels.
The above is a summary of the bitstream. The user interface to vpxenc
(and the equivalent encoder API) behaves a follows:
If --enable-ext-tile is OFF:
No change in the user interface. --tile-columns and --tile-rows
specify the base 2 logarithm of the desired number of tile columns
and tile rows. The actual number of tile rows and tile columns,
and the particular tile width and tile height are computed by the
codec ensuring all of the above constraints are respected.
If --enable-ext-tile is ON, but --enable-ext-partition is OFF:
No change in the user interface. --tile-columns and --tile-rows
specify the WIDTH and HEIGHT of the tiles in unit of 64 pixels.
The valid values are in the range [1, 64] (which corresponds to
[64, 4096] pixels in increments of 64.
If both --enable-ext-tile is ON and --enable-ext-partition is ON:
If --sb-size=64 (default):
The user interface is the same as in the previous point.
--tile-columns and --tile-rows specify tile WIDTH and HEIGHT,
in units of 64 pixels, in the range [1, 64] (which corresponds
to [64, 4096] pixels in increments of 64).
If --sb-size=128 or --sb-size=dynamic:
--tile-columns and --tile-rows specify tile WIDTH and HEIGHT,
in units of 128 pixels in the range [1, 32] (which corresponds
to [128, 4096] pixels in increments of 128).
Change-Id: Idc9beee1ad12ff1634e83671985d14c680f9179a
2016-03-24 16:56:05 +03:00
|
|
|
cm->tile_height <<= cm->mib_size_log2;
|
2016-03-11 20:42:49 +03:00
|
|
|
|
2016-08-31 00:01:10 +03:00
|
|
|
cm->tile_width = AOMMIN(cm->tile_width, cm->mi_cols);
|
|
|
|
cm->tile_height = AOMMIN(cm->tile_height, cm->mi_rows);
|
2016-03-11 20:42:49 +03:00
|
|
|
|
|
|
|
// Get the number of tiles
|
|
|
|
cm->tile_cols = 1;
|
2016-08-12 04:53:26 +03:00
|
|
|
while (cm->tile_cols * cm->tile_width < cm->mi_cols) ++cm->tile_cols;
|
2016-03-11 20:42:49 +03:00
|
|
|
|
|
|
|
cm->tile_rows = 1;
|
2016-08-12 04:53:26 +03:00
|
|
|
while (cm->tile_rows * cm->tile_height < cm->mi_rows) ++cm->tile_rows;
|
2016-03-11 20:42:49 +03:00
|
|
|
|
|
|
|
if (cm->tile_cols * cm->tile_rows > 1) {
|
|
|
|
// Read the number of bytes used to store tile size
|
2016-08-31 00:01:10 +03:00
|
|
|
pbi->tile_col_size_bytes = aom_rb_read_literal(rb, 2) + 1;
|
|
|
|
pbi->tile_size_bytes = aom_rb_read_literal(rb, 2) + 1;
|
2016-03-11 20:42:49 +03:00
|
|
|
}
|
|
|
|
#else
|
2015-08-06 05:00:31 +03:00
|
|
|
int min_log2_tile_cols, max_log2_tile_cols, max_ones;
|
2016-08-31 00:01:10 +03:00
|
|
|
av1_get_tile_n_bits(cm->mi_cols, &min_log2_tile_cols, &max_log2_tile_cols);
|
2015-08-06 05:00:31 +03:00
|
|
|
|
|
|
|
// columns
|
|
|
|
max_ones = max_log2_tile_cols - min_log2_tile_cols;
|
|
|
|
cm->log2_tile_cols = min_log2_tile_cols;
|
2016-08-31 00:01:10 +03:00
|
|
|
while (max_ones-- && aom_rb_read_bit(rb)) cm->log2_tile_cols++;
|
2015-08-06 05:00:31 +03:00
|
|
|
|
|
|
|
if (cm->log2_tile_cols > 6)
|
2016-08-31 00:01:10 +03:00
|
|
|
aom_internal_error(&cm->error, AOM_CODEC_CORRUPT_FRAME,
|
2015-08-06 05:00:31 +03:00
|
|
|
"Invalid number of tile columns");
|
|
|
|
|
|
|
|
// rows
|
2016-08-31 00:01:10 +03:00
|
|
|
cm->log2_tile_rows = aom_rb_read_bit(rb);
|
|
|
|
if (cm->log2_tile_rows) cm->log2_tile_rows += aom_rb_read_bit(rb);
|
2015-09-30 23:42:59 +03:00
|
|
|
|
2016-03-11 20:42:49 +03:00
|
|
|
cm->tile_cols = 1 << cm->log2_tile_cols;
|
|
|
|
cm->tile_rows = 1 << cm->log2_tile_rows;
|
|
|
|
|
Make superblock size variable at the frame level.
The uncompressed frame header contains a bit to signal whether the
frame is encoded using 64x64 or 128x128 superblocks. This can vary
between any 2 frames.
vpxenc gained the --sb-size={64,128,dynamic} option, which allows the
configuration of the superblock size used (default is dynamic). 64/128
will force the encoder to always use the specified superblock size.
Dynamic would enable the encoder to choose the sb size for each
frame, but this is not implemented yet (dynamic does the same as 128
for now).
Constraints on tile sizes depend on the superblock size, the following
is a summary of the current bitstream syntax and semantics:
If both --enable-ext-tile is OFF and --enable-ext-partition is OFF:
The tile coding in this case is the same as VP9. In particular,
tiles have a minimum width of 256 pixels and a maximum width of
4096 pixels. The tile width must be multiples of 64 pixels
(except for the rightmost tile column). There can be a maximum
of 64 tile columns and 4 tile rows.
If --enable-ext-tile is OFF and --enable-ext-partition is ON:
Same constraints as above, except that tile width must be
multiples of 128 pixels (except for the rightmost tile column).
There is no change in the bitstream syntax used for coding the tile
configuration if --enable-ext-tile is OFF.
If --enable-ext-tile is ON and --enable-ext-partition is ON:
This is the new large scale tile coding configuration. The
minimum/maximum tile width and height are 64/4096 pixels. Tile
width and height must be multiples of 64 pixels. The uncompressed
header contains two 6 bit fields that hold the tile width/heigh
in units of 64 pixels. The maximum number of tile rows/columns
is only limited by the maximum frame size of 65536x65536 pixels
that can be coded in the bitstream. This yields a maximum of
1024x1024 tile rows and columns (of 64x64 tiles in a 65536x65536
frame).
If both --enable-ext-tile is ON and --enable-ext-partition is ON:
Same applies as above, except that in the bitstream the 2 fields
containing the tile width/height are in units of the superblock
size, and the superblock size itself is also coded in the bitstream.
If the uncompressed header signals the use of 64x64 superblocks,
then the tile width/height fields are 6 bits wide and are in units
of 64 pixels. If the uncompressed header signals the use of 128x128
superblocks, then the tile width/height fields are 5 bits wide and
are in units of 128 pixels.
The above is a summary of the bitstream. The user interface to vpxenc
(and the equivalent encoder API) behaves a follows:
If --enable-ext-tile is OFF:
No change in the user interface. --tile-columns and --tile-rows
specify the base 2 logarithm of the desired number of tile columns
and tile rows. The actual number of tile rows and tile columns,
and the particular tile width and tile height are computed by the
codec ensuring all of the above constraints are respected.
If --enable-ext-tile is ON, but --enable-ext-partition is OFF:
No change in the user interface. --tile-columns and --tile-rows
specify the WIDTH and HEIGHT of the tiles in unit of 64 pixels.
The valid values are in the range [1, 64] (which corresponds to
[64, 4096] pixels in increments of 64.
If both --enable-ext-tile is ON and --enable-ext-partition is ON:
If --sb-size=64 (default):
The user interface is the same as in the previous point.
--tile-columns and --tile-rows specify tile WIDTH and HEIGHT,
in units of 64 pixels, in the range [1, 64] (which corresponds
to [64, 4096] pixels in increments of 64).
If --sb-size=128 or --sb-size=dynamic:
--tile-columns and --tile-rows specify tile WIDTH and HEIGHT,
in units of 128 pixels in the range [1, 32] (which corresponds
to [128, 4096] pixels in increments of 128).
Change-Id: Idc9beee1ad12ff1634e83671985d14c680f9179a
2016-03-24 16:56:05 +03:00
|
|
|
cm->tile_width = ALIGN_POWER_OF_TWO(cm->mi_cols, MAX_MIB_SIZE_LOG2);
|
|
|
|
cm->tile_width >>= cm->log2_tile_cols;
|
|
|
|
cm->tile_height = ALIGN_POWER_OF_TWO(cm->mi_rows, MAX_MIB_SIZE_LOG2);
|
|
|
|
cm->tile_height >>= cm->log2_tile_rows;
|
2016-03-11 20:42:49 +03:00
|
|
|
|
Make superblock size variable at the frame level.
The uncompressed frame header contains a bit to signal whether the
frame is encoded using 64x64 or 128x128 superblocks. This can vary
between any 2 frames.
vpxenc gained the --sb-size={64,128,dynamic} option, which allows the
configuration of the superblock size used (default is dynamic). 64/128
will force the encoder to always use the specified superblock size.
Dynamic would enable the encoder to choose the sb size for each
frame, but this is not implemented yet (dynamic does the same as 128
for now).
Constraints on tile sizes depend on the superblock size, the following
is a summary of the current bitstream syntax and semantics:
If both --enable-ext-tile is OFF and --enable-ext-partition is OFF:
The tile coding in this case is the same as VP9. In particular,
tiles have a minimum width of 256 pixels and a maximum width of
4096 pixels. The tile width must be multiples of 64 pixels
(except for the rightmost tile column). There can be a maximum
of 64 tile columns and 4 tile rows.
If --enable-ext-tile is OFF and --enable-ext-partition is ON:
Same constraints as above, except that tile width must be
multiples of 128 pixels (except for the rightmost tile column).
There is no change in the bitstream syntax used for coding the tile
configuration if --enable-ext-tile is OFF.
If --enable-ext-tile is ON and --enable-ext-partition is ON:
This is the new large scale tile coding configuration. The
minimum/maximum tile width and height are 64/4096 pixels. Tile
width and height must be multiples of 64 pixels. The uncompressed
header contains two 6 bit fields that hold the tile width/heigh
in units of 64 pixels. The maximum number of tile rows/columns
is only limited by the maximum frame size of 65536x65536 pixels
that can be coded in the bitstream. This yields a maximum of
1024x1024 tile rows and columns (of 64x64 tiles in a 65536x65536
frame).
If both --enable-ext-tile is ON and --enable-ext-partition is ON:
Same applies as above, except that in the bitstream the 2 fields
containing the tile width/height are in units of the superblock
size, and the superblock size itself is also coded in the bitstream.
If the uncompressed header signals the use of 64x64 superblocks,
then the tile width/height fields are 6 bits wide and are in units
of 64 pixels. If the uncompressed header signals the use of 128x128
superblocks, then the tile width/height fields are 5 bits wide and
are in units of 128 pixels.
The above is a summary of the bitstream. The user interface to vpxenc
(and the equivalent encoder API) behaves a follows:
If --enable-ext-tile is OFF:
No change in the user interface. --tile-columns and --tile-rows
specify the base 2 logarithm of the desired number of tile columns
and tile rows. The actual number of tile rows and tile columns,
and the particular tile width and tile height are computed by the
codec ensuring all of the above constraints are respected.
If --enable-ext-tile is ON, but --enable-ext-partition is OFF:
No change in the user interface. --tile-columns and --tile-rows
specify the WIDTH and HEIGHT of the tiles in unit of 64 pixels.
The valid values are in the range [1, 64] (which corresponds to
[64, 4096] pixels in increments of 64.
If both --enable-ext-tile is ON and --enable-ext-partition is ON:
If --sb-size=64 (default):
The user interface is the same as in the previous point.
--tile-columns and --tile-rows specify tile WIDTH and HEIGHT,
in units of 64 pixels, in the range [1, 64] (which corresponds
to [64, 4096] pixels in increments of 64).
If --sb-size=128 or --sb-size=dynamic:
--tile-columns and --tile-rows specify tile WIDTH and HEIGHT,
in units of 128 pixels in the range [1, 32] (which corresponds
to [128, 4096] pixels in increments of 128).
Change-Id: Idc9beee1ad12ff1634e83671985d14c680f9179a
2016-03-24 16:56:05 +03:00
|
|
|
// round to integer multiples of superblock size
|
2016-08-12 04:53:26 +03:00
|
|
|
cm->tile_width = ALIGN_POWER_OF_TWO(cm->tile_width, MAX_MIB_SIZE_LOG2);
|
Make superblock size variable at the frame level.
The uncompressed frame header contains a bit to signal whether the
frame is encoded using 64x64 or 128x128 superblocks. This can vary
between any 2 frames.
vpxenc gained the --sb-size={64,128,dynamic} option, which allows the
configuration of the superblock size used (default is dynamic). 64/128
will force the encoder to always use the specified superblock size.
Dynamic would enable the encoder to choose the sb size for each
frame, but this is not implemented yet (dynamic does the same as 128
for now).
Constraints on tile sizes depend on the superblock size, the following
is a summary of the current bitstream syntax and semantics:
If both --enable-ext-tile is OFF and --enable-ext-partition is OFF:
The tile coding in this case is the same as VP9. In particular,
tiles have a minimum width of 256 pixels and a maximum width of
4096 pixels. The tile width must be multiples of 64 pixels
(except for the rightmost tile column). There can be a maximum
of 64 tile columns and 4 tile rows.
If --enable-ext-tile is OFF and --enable-ext-partition is ON:
Same constraints as above, except that tile width must be
multiples of 128 pixels (except for the rightmost tile column).
There is no change in the bitstream syntax used for coding the tile
configuration if --enable-ext-tile is OFF.
If --enable-ext-tile is ON and --enable-ext-partition is ON:
This is the new large scale tile coding configuration. The
minimum/maximum tile width and height are 64/4096 pixels. Tile
width and height must be multiples of 64 pixels. The uncompressed
header contains two 6 bit fields that hold the tile width/heigh
in units of 64 pixels. The maximum number of tile rows/columns
is only limited by the maximum frame size of 65536x65536 pixels
that can be coded in the bitstream. This yields a maximum of
1024x1024 tile rows and columns (of 64x64 tiles in a 65536x65536
frame).
If both --enable-ext-tile is ON and --enable-ext-partition is ON:
Same applies as above, except that in the bitstream the 2 fields
containing the tile width/height are in units of the superblock
size, and the superblock size itself is also coded in the bitstream.
If the uncompressed header signals the use of 64x64 superblocks,
then the tile width/height fields are 6 bits wide and are in units
of 64 pixels. If the uncompressed header signals the use of 128x128
superblocks, then the tile width/height fields are 5 bits wide and
are in units of 128 pixels.
The above is a summary of the bitstream. The user interface to vpxenc
(and the equivalent encoder API) behaves a follows:
If --enable-ext-tile is OFF:
No change in the user interface. --tile-columns and --tile-rows
specify the base 2 logarithm of the desired number of tile columns
and tile rows. The actual number of tile rows and tile columns,
and the particular tile width and tile height are computed by the
codec ensuring all of the above constraints are respected.
If --enable-ext-tile is ON, but --enable-ext-partition is OFF:
No change in the user interface. --tile-columns and --tile-rows
specify the WIDTH and HEIGHT of the tiles in unit of 64 pixels.
The valid values are in the range [1, 64] (which corresponds to
[64, 4096] pixels in increments of 64.
If both --enable-ext-tile is ON and --enable-ext-partition is ON:
If --sb-size=64 (default):
The user interface is the same as in the previous point.
--tile-columns and --tile-rows specify tile WIDTH and HEIGHT,
in units of 64 pixels, in the range [1, 64] (which corresponds
to [64, 4096] pixels in increments of 64).
If --sb-size=128 or --sb-size=dynamic:
--tile-columns and --tile-rows specify tile WIDTH and HEIGHT,
in units of 128 pixels in the range [1, 32] (which corresponds
to [128, 4096] pixels in increments of 128).
Change-Id: Idc9beee1ad12ff1634e83671985d14c680f9179a
2016-03-24 16:56:05 +03:00
|
|
|
cm->tile_height = ALIGN_POWER_OF_TWO(cm->tile_height, MAX_MIB_SIZE_LOG2);
|
2016-03-11 20:42:49 +03:00
|
|
|
|
2015-09-30 23:42:59 +03:00
|
|
|
// tile size magnitude
|
2016-03-11 20:42:49 +03:00
|
|
|
if (cm->tile_rows > 1 || cm->tile_cols > 1) {
|
2016-08-31 00:01:10 +03:00
|
|
|
pbi->tile_size_bytes = aom_rb_read_literal(rb, 2) + 1;
|
2015-09-30 23:42:59 +03:00
|
|
|
}
|
2016-03-11 20:42:49 +03:00
|
|
|
#endif // CONFIG_EXT_TILE
|
2015-08-06 05:00:31 +03:00
|
|
|
}
|
|
|
|
|
2016-03-11 20:42:49 +03:00
|
|
|
static int mem_get_varsize(const uint8_t *src, const int sz) {
|
|
|
|
switch (sz) {
|
2016-08-12 04:53:26 +03:00
|
|
|
case 1: return src[0];
|
|
|
|
case 2: return mem_get_le16(src);
|
|
|
|
case 3: return mem_get_le24(src);
|
|
|
|
case 4: return mem_get_le32(src);
|
|
|
|
default: assert("Invalid size" && 0); return -1;
|
2016-03-11 20:42:49 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#if CONFIG_EXT_TILE
|
|
|
|
// Reads the next tile returning its size and adjusting '*data' accordingly
|
|
|
|
// based on 'is_last'.
|
|
|
|
static void get_tile_buffer(const uint8_t *const data_end,
|
2016-08-31 00:01:10 +03:00
|
|
|
struct aom_internal_error_info *error_info,
|
|
|
|
const uint8_t **data, aom_decrypt_cb decrypt_cb,
|
2016-08-12 04:53:26 +03:00
|
|
|
void *decrypt_state,
|
2016-03-11 20:42:49 +03:00
|
|
|
TileBufferDec (*const tile_buffers)[MAX_TILE_COLS],
|
|
|
|
int tile_size_bytes, int col, int row) {
|
|
|
|
size_t size;
|
|
|
|
|
2016-08-12 04:53:26 +03:00
|
|
|
size_t copy_size = 0;
|
2016-03-11 20:42:49 +03:00
|
|
|
const uint8_t *copy_data = NULL;
|
|
|
|
|
|
|
|
if (!read_is_valid(*data, tile_size_bytes, data_end))
|
2016-08-31 00:01:10 +03:00
|
|
|
aom_internal_error(error_info, AOM_CODEC_CORRUPT_FRAME,
|
2016-03-11 20:42:49 +03:00
|
|
|
"Truncated packet or corrupt tile length");
|
|
|
|
if (decrypt_cb) {
|
|
|
|
uint8_t be_data[4];
|
|
|
|
decrypt_cb(decrypt_state, *data, be_data, tile_size_bytes);
|
|
|
|
|
|
|
|
// Only read number of bytes in cm->tile_size_bytes.
|
|
|
|
size = mem_get_varsize(be_data, tile_size_bytes);
|
|
|
|
} else {
|
|
|
|
size = mem_get_varsize(*data, tile_size_bytes);
|
|
|
|
}
|
|
|
|
|
|
|
|
// The top bit indicates copy mode
|
|
|
|
if ((size >> (tile_size_bytes * 8 - 1)) == 1) {
|
|
|
|
// The remaining bits in the top byte signal the row offset
|
|
|
|
int offset = (size >> (tile_size_bytes - 1) * 8) & 0x7f;
|
|
|
|
|
|
|
|
// Currently, only use tiles in same column as reference tiles.
|
|
|
|
copy_data = tile_buffers[row - offset][col].data;
|
|
|
|
copy_size = tile_buffers[row - offset][col].size;
|
|
|
|
size = 0;
|
2015-09-30 23:42:59 +03:00
|
|
|
}
|
|
|
|
|
2016-03-11 20:42:49 +03:00
|
|
|
*data += tile_size_bytes;
|
|
|
|
|
|
|
|
if (size > (size_t)(data_end - *data))
|
2016-08-31 00:01:10 +03:00
|
|
|
aom_internal_error(error_info, AOM_CODEC_CORRUPT_FRAME,
|
2016-03-11 20:42:49 +03:00
|
|
|
"Truncated packet or corrupt tile size");
|
2015-09-30 23:42:59 +03:00
|
|
|
|
2016-03-11 20:42:49 +03:00
|
|
|
if (size > 0) {
|
|
|
|
tile_buffers[row][col].data = *data;
|
|
|
|
tile_buffers[row][col].size = size;
|
|
|
|
} else {
|
|
|
|
tile_buffers[row][col].data = copy_data;
|
|
|
|
tile_buffers[row][col].size = copy_size;
|
|
|
|
}
|
|
|
|
|
|
|
|
*data += size;
|
2016-05-03 20:25:01 +03:00
|
|
|
|
|
|
|
tile_buffers[row][col].raw_data_end = *data;
|
2015-09-30 23:42:59 +03:00
|
|
|
}
|
|
|
|
|
2016-03-11 20:42:49 +03:00
|
|
|
static void get_tile_buffers(
|
2016-08-31 00:01:10 +03:00
|
|
|
AV1Decoder *pbi, const uint8_t *data, const uint8_t *data_end,
|
2016-03-11 20:42:49 +03:00
|
|
|
TileBufferDec (*const tile_buffers)[MAX_TILE_COLS]) {
|
2016-08-31 00:01:10 +03:00
|
|
|
AV1_COMMON *const cm = &pbi->common;
|
2016-03-11 20:42:49 +03:00
|
|
|
const int tile_cols = cm->tile_cols;
|
|
|
|
const int tile_rows = cm->tile_rows;
|
|
|
|
const int have_tiles = tile_cols * tile_rows > 1;
|
|
|
|
|
2016-08-12 04:53:26 +03:00
|
|
|
if (!have_tiles) {
|
2016-03-11 20:42:49 +03:00
|
|
|
const uint32_t tile_size = data_end - data;
|
|
|
|
tile_buffers[0][0].data = data;
|
|
|
|
tile_buffers[0][0].size = tile_size;
|
2016-05-03 20:25:01 +03:00
|
|
|
tile_buffers[0][0].raw_data_end = NULL;
|
2016-03-11 20:42:49 +03:00
|
|
|
} else {
|
2016-05-11 13:07:15 +03:00
|
|
|
// We locate only the tile buffers that are required, which are the ones
|
|
|
|
// specified by pbi->dec_tile_col and pbi->dec_tile_row. Also, we always
|
|
|
|
// need the last (bottom right) tile buffer, as we need to know where the
|
|
|
|
// end of the compressed frame buffer is for proper superframe decoding.
|
|
|
|
|
2016-03-11 20:42:49 +03:00
|
|
|
const uint8_t *tile_col_data_end[MAX_TILE_COLS];
|
|
|
|
const uint8_t *const data_start = data;
|
|
|
|
|
2016-08-31 00:01:10 +03:00
|
|
|
const int dec_tile_row = AOMMIN(pbi->dec_tile_row, tile_rows);
|
2016-03-11 20:42:49 +03:00
|
|
|
const int single_row = pbi->dec_tile_row >= 0;
|
|
|
|
const int tile_rows_start = single_row ? dec_tile_row : 0;
|
|
|
|
const int tile_rows_end = single_row ? tile_rows_start + 1 : tile_rows;
|
2016-08-31 00:01:10 +03:00
|
|
|
const int dec_tile_col = AOMMIN(pbi->dec_tile_col, tile_cols);
|
2016-03-11 20:42:49 +03:00
|
|
|
const int single_col = pbi->dec_tile_col >= 0;
|
|
|
|
const int tile_cols_start = single_col ? dec_tile_col : 0;
|
|
|
|
const int tile_cols_end = single_col ? tile_cols_start + 1 : tile_cols;
|
|
|
|
|
|
|
|
const int tile_col_size_bytes = pbi->tile_col_size_bytes;
|
|
|
|
const int tile_size_bytes = pbi->tile_size_bytes;
|
|
|
|
|
|
|
|
size_t tile_col_size;
|
|
|
|
int r, c;
|
|
|
|
|
2016-05-11 13:07:15 +03:00
|
|
|
// Read tile column sizes for all columns (we need the last tile buffer)
|
|
|
|
for (c = 0; c < tile_cols; ++c) {
|
2016-03-11 20:42:49 +03:00
|
|
|
const int is_last = c == tile_cols - 1;
|
|
|
|
if (!is_last) {
|
|
|
|
tile_col_size = mem_get_varsize(data, tile_col_size_bytes);
|
|
|
|
data += tile_col_size_bytes;
|
|
|
|
tile_col_data_end[c] = data + tile_col_size;
|
|
|
|
} else {
|
|
|
|
tile_col_size = data_end - data;
|
|
|
|
tile_col_data_end[c] = data_end;
|
|
|
|
}
|
|
|
|
data += tile_col_size;
|
|
|
|
}
|
|
|
|
|
|
|
|
data = data_start;
|
|
|
|
|
2016-05-11 13:07:15 +03:00
|
|
|
// Read the required tile sizes.
|
2016-03-11 20:42:49 +03:00
|
|
|
for (c = tile_cols_start; c < tile_cols_end; ++c) {
|
2016-05-11 13:07:15 +03:00
|
|
|
const int is_last = c == tile_cols - 1;
|
|
|
|
|
2016-08-12 04:53:26 +03:00
|
|
|
if (c > 0) data = tile_col_data_end[c - 1];
|
2016-03-11 20:42:49 +03:00
|
|
|
|
2016-08-12 04:53:26 +03:00
|
|
|
if (!is_last) data += tile_col_size_bytes;
|
2016-03-11 20:42:49 +03:00
|
|
|
|
2016-05-11 13:07:15 +03:00
|
|
|
// Get the whole of the last column, otherwise stop at the required tile.
|
|
|
|
for (r = 0; r < (is_last ? tile_rows : tile_rows_end); ++r) {
|
|
|
|
tile_buffers[r][c].col = c;
|
|
|
|
|
2016-08-12 04:53:26 +03:00
|
|
|
get_tile_buffer(tile_col_data_end[c], &pbi->common.error, &data,
|
|
|
|
pbi->decrypt_cb, pbi->decrypt_state, tile_buffers,
|
|
|
|
tile_size_bytes, c, r);
|
2016-05-11 13:07:15 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// If we have not read the last column, then read it to get the last tile.
|
|
|
|
if (tile_cols_end != tile_cols) {
|
|
|
|
c = tile_cols - 1;
|
|
|
|
|
|
|
|
data = tile_col_data_end[c - 1];
|
|
|
|
|
|
|
|
for (r = 0; r < tile_rows; ++r) {
|
2016-03-11 20:42:49 +03:00
|
|
|
tile_buffers[r][c].col = c;
|
|
|
|
|
2016-08-12 04:53:26 +03:00
|
|
|
get_tile_buffer(tile_col_data_end[c], &pbi->common.error, &data,
|
|
|
|
pbi->decrypt_cb, pbi->decrypt_state, tile_buffers,
|
|
|
|
tile_size_bytes, c, r);
|
2016-03-11 20:42:49 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
#else
|
2015-08-06 05:00:31 +03:00
|
|
|
// Reads the next tile returning its size and adjusting '*data' accordingly
|
|
|
|
// based on 'is_last'.
|
|
|
|
static void get_tile_buffer(const uint8_t *const data_end,
|
2016-03-11 20:42:49 +03:00
|
|
|
const int tile_size_bytes, int is_last,
|
2016-08-31 00:01:10 +03:00
|
|
|
struct aom_internal_error_info *error_info,
|
|
|
|
const uint8_t **data, aom_decrypt_cb decrypt_cb,
|
2016-08-12 04:53:26 +03:00
|
|
|
void *decrypt_state, TileBufferDec *const buf) {
|
2015-08-06 05:00:31 +03:00
|
|
|
size_t size;
|
|
|
|
|
|
|
|
if (!is_last) {
|
|
|
|
if (!read_is_valid(*data, 4, data_end))
|
2016-08-31 00:01:10 +03:00
|
|
|
aom_internal_error(error_info, AOM_CODEC_CORRUPT_FRAME,
|
2015-08-06 05:00:31 +03:00
|
|
|
"Truncated packet or corrupt tile length");
|
|
|
|
|
|
|
|
if (decrypt_cb) {
|
|
|
|
uint8_t be_data[4];
|
2016-03-11 20:42:49 +03:00
|
|
|
decrypt_cb(decrypt_state, *data, be_data, tile_size_bytes);
|
|
|
|
size = mem_get_varsize(be_data, tile_size_bytes);
|
2015-08-06 05:00:31 +03:00
|
|
|
} else {
|
2016-03-11 20:42:49 +03:00
|
|
|
size = mem_get_varsize(*data, tile_size_bytes);
|
2015-08-06 05:00:31 +03:00
|
|
|
}
|
2016-03-11 20:42:49 +03:00
|
|
|
*data += tile_size_bytes;
|
2015-08-06 05:00:31 +03:00
|
|
|
|
|
|
|
if (size > (size_t)(data_end - *data))
|
2016-08-31 00:01:10 +03:00
|
|
|
aom_internal_error(error_info, AOM_CODEC_CORRUPT_FRAME,
|
2015-08-06 05:00:31 +03:00
|
|
|
"Truncated packet or corrupt tile size");
|
|
|
|
} else {
|
|
|
|
size = data_end - *data;
|
|
|
|
}
|
|
|
|
|
|
|
|
buf->data = *data;
|
|
|
|
buf->size = size;
|
|
|
|
|
|
|
|
*data += size;
|
|
|
|
}
|
|
|
|
|
2016-03-11 20:42:49 +03:00
|
|
|
static void get_tile_buffers(
|
2016-08-31 00:01:10 +03:00
|
|
|
AV1Decoder *pbi, const uint8_t *data, const uint8_t *data_end,
|
2016-03-11 20:42:49 +03:00
|
|
|
TileBufferDec (*const tile_buffers)[MAX_TILE_COLS]) {
|
2016-08-31 00:01:10 +03:00
|
|
|
AV1_COMMON *const cm = &pbi->common;
|
2015-08-06 05:00:31 +03:00
|
|
|
int r, c;
|
2016-03-11 20:42:49 +03:00
|
|
|
const int tile_cols = cm->tile_cols;
|
|
|
|
const int tile_rows = cm->tile_rows;
|
2015-08-06 05:00:31 +03:00
|
|
|
|
|
|
|
for (r = 0; r < tile_rows; ++r) {
|
|
|
|
for (c = 0; c < tile_cols; ++c) {
|
|
|
|
const int is_last = (r == tile_rows - 1) && (c == tile_cols - 1);
|
2016-03-11 20:42:49 +03:00
|
|
|
TileBufferDec *const buf = &tile_buffers[r][c];
|
2015-08-06 05:00:31 +03:00
|
|
|
buf->col = c;
|
2016-08-12 04:53:26 +03:00
|
|
|
get_tile_buffer(data_end, pbi->tile_size_bytes, is_last, &cm->error,
|
|
|
|
&data, pbi->decrypt_cb, pbi->decrypt_state, buf);
|
2015-08-06 05:00:31 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2016-03-11 20:42:49 +03:00
|
|
|
#endif // CONFIG_EXT_TILE
|
2015-08-06 05:00:31 +03:00
|
|
|
|
2016-08-31 00:01:10 +03:00
|
|
|
static const uint8_t *decode_tiles(AV1Decoder *pbi, const uint8_t *data,
|
2015-08-06 05:00:31 +03:00
|
|
|
const uint8_t *data_end) {
|
2016-08-31 00:01:10 +03:00
|
|
|
AV1_COMMON *const cm = &pbi->common;
|
|
|
|
const AVxWorkerInterface *const winterface = aom_get_worker_interface();
|
2016-03-11 20:42:49 +03:00
|
|
|
const int tile_cols = cm->tile_cols;
|
|
|
|
const int tile_rows = cm->tile_rows;
|
2016-05-03 20:25:01 +03:00
|
|
|
const int n_tiles = tile_cols * tile_rows;
|
2016-09-08 08:40:40 +03:00
|
|
|
TileBufferDec(*const tile_buffers)[MAX_TILE_COLS] = pbi->tile_buffers;
|
2016-03-11 20:42:49 +03:00
|
|
|
#if CONFIG_EXT_TILE
|
2016-08-31 00:01:10 +03:00
|
|
|
const int dec_tile_row = AOMMIN(pbi->dec_tile_row, tile_rows);
|
2016-03-11 20:42:49 +03:00
|
|
|
const int single_row = pbi->dec_tile_row >= 0;
|
|
|
|
const int tile_rows_start = single_row ? dec_tile_row : 0;
|
|
|
|
const int tile_rows_end = single_row ? dec_tile_row + 1 : tile_rows;
|
2016-08-31 00:01:10 +03:00
|
|
|
const int dec_tile_col = AOMMIN(pbi->dec_tile_col, tile_cols);
|
2016-03-11 20:42:49 +03:00
|
|
|
const int single_col = pbi->dec_tile_col >= 0;
|
|
|
|
const int tile_cols_start = single_col ? dec_tile_col : 0;
|
|
|
|
const int tile_cols_end = single_col ? tile_cols_start + 1 : tile_cols;
|
|
|
|
const int inv_col_order = pbi->inv_tile_order && !single_col;
|
2016-05-03 15:55:25 +03:00
|
|
|
const int inv_row_order = pbi->inv_tile_order && !single_row;
|
2016-03-11 20:42:49 +03:00
|
|
|
#else
|
|
|
|
const int tile_rows_start = 0;
|
|
|
|
const int tile_rows_end = tile_rows;
|
|
|
|
const int tile_cols_start = 0;
|
|
|
|
const int tile_cols_end = tile_cols;
|
|
|
|
const int inv_col_order = pbi->inv_tile_order;
|
2016-05-03 15:55:25 +03:00
|
|
|
const int inv_row_order = pbi->inv_tile_order;
|
2016-03-11 20:42:49 +03:00
|
|
|
#endif // CONFIG_EXT_TILE
|
2015-08-06 05:00:31 +03:00
|
|
|
int tile_row, tile_col;
|
|
|
|
|
2016-01-08 01:29:26 +03:00
|
|
|
#if CONFIG_ENTROPY
|
2016-05-03 20:25:01 +03:00
|
|
|
cm->do_subframe_update = n_tiles == 1;
|
2016-01-08 01:29:26 +03:00
|
|
|
#endif // CONFIG_ENTROPY
|
|
|
|
|
2015-08-06 05:00:31 +03:00
|
|
|
if (cm->lf.filter_level && !cm->skip_loop_filter &&
|
|
|
|
pbi->lf_worker.data1 == NULL) {
|
|
|
|
CHECK_MEM_ERROR(cm, pbi->lf_worker.data1,
|
2016-08-31 00:01:10 +03:00
|
|
|
aom_memalign(32, sizeof(LFWorkerData)));
|
|
|
|
pbi->lf_worker.hook = (AVxWorkerHook)av1_loop_filter_worker;
|
2015-08-06 05:00:31 +03:00
|
|
|
if (pbi->max_threads > 1 && !winterface->reset(&pbi->lf_worker)) {
|
2016-08-31 00:01:10 +03:00
|
|
|
aom_internal_error(&cm->error, AOM_CODEC_ERROR,
|
2015-08-06 05:00:31 +03:00
|
|
|
"Loop filter thread creation failed");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (cm->lf.filter_level && !cm->skip_loop_filter) {
|
2016-08-12 04:53:26 +03:00
|
|
|
LFWorkerData *const lf_data = (LFWorkerData *)pbi->lf_worker.data1;
|
2015-08-06 05:00:31 +03:00
|
|
|
// Be sure to sync as we might be resuming after a failed frame decode.
|
|
|
|
winterface->sync(&pbi->lf_worker);
|
2016-08-31 00:01:10 +03:00
|
|
|
av1_loop_filter_data_reset(lf_data, get_frame_new_buffer(cm), cm,
|
|
|
|
pbi->mb.plane);
|
2015-08-06 05:00:31 +03:00
|
|
|
}
|
|
|
|
|
2016-03-11 20:42:49 +03:00
|
|
|
assert(tile_rows <= MAX_TILE_ROWS);
|
|
|
|
assert(tile_cols <= MAX_TILE_COLS);
|
2015-08-06 05:00:31 +03:00
|
|
|
|
2016-03-11 20:42:49 +03:00
|
|
|
get_tile_buffers(pbi, data, data_end, tile_buffers);
|
2015-08-06 05:00:31 +03:00
|
|
|
|
2016-05-03 20:25:01 +03:00
|
|
|
if (pbi->tile_data == NULL || n_tiles != pbi->allocated_tiles) {
|
2016-08-31 00:01:10 +03:00
|
|
|
aom_free(pbi->tile_data);
|
2016-08-12 04:53:26 +03:00
|
|
|
CHECK_MEM_ERROR(cm, pbi->tile_data,
|
2016-08-31 00:01:10 +03:00
|
|
|
aom_memalign(32, n_tiles * (sizeof(*pbi->tile_data))));
|
2016-05-03 20:25:01 +03:00
|
|
|
pbi->allocated_tiles = n_tiles;
|
2015-08-06 05:00:31 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
// Load all tile information into tile_data.
|
2016-03-11 20:42:49 +03:00
|
|
|
for (tile_row = tile_rows_start; tile_row < tile_rows_end; ++tile_row) {
|
|
|
|
for (tile_col = tile_cols_start; tile_col < tile_cols_end; ++tile_col) {
|
|
|
|
const TileBufferDec *const buf = &tile_buffers[tile_row][tile_col];
|
|
|
|
TileData *const td = pbi->tile_data + tile_cols * tile_row + tile_col;
|
|
|
|
|
|
|
|
td->cm = cm;
|
|
|
|
td->xd = pbi->mb;
|
|
|
|
td->xd.corrupted = 0;
|
|
|
|
td->xd.counts =
|
2016-08-12 04:53:26 +03:00
|
|
|
cm->refresh_frame_context == REFRESH_FRAME_CONTEXT_BACKWARD
|
|
|
|
? &cm->counts
|
|
|
|
: NULL;
|
2016-08-31 00:01:10 +03:00
|
|
|
av1_zero(td->dqcoeff);
|
|
|
|
av1_tile_init(&td->xd.tile, td->cm, tile_row, tile_col);
|
2016-03-22 20:33:34 +03:00
|
|
|
#if !CONFIG_ANS
|
2015-12-16 22:17:25 +03:00
|
|
|
setup_bool_decoder(buf->data, data_end, buf->size, &cm->error,
|
2016-08-12 04:53:26 +03:00
|
|
|
&td->bit_reader, pbi->decrypt_cb, pbi->decrypt_state);
|
2016-03-22 20:33:34 +03:00
|
|
|
#else
|
2015-08-06 05:00:31 +03:00
|
|
|
setup_token_decoder(buf->data, data_end, buf->size, &cm->error,
|
2016-08-12 04:53:26 +03:00
|
|
|
&td->bit_reader, pbi->decrypt_cb, pbi->decrypt_state);
|
2016-03-22 20:33:34 +03:00
|
|
|
#endif
|
2016-08-31 00:01:10 +03:00
|
|
|
av1_init_macroblockd(cm, &td->xd, td->dqcoeff);
|
2016-03-11 20:42:49 +03:00
|
|
|
td->xd.plane[0].color_index_map = td->color_index_map[0];
|
|
|
|
td->xd.plane[1].color_index_map = td->color_index_map[1];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
for (tile_row = tile_rows_start; tile_row < tile_rows_end; ++tile_row) {
|
2016-05-03 15:55:25 +03:00
|
|
|
const int row = inv_row_order ? tile_rows - 1 - tile_row : tile_row;
|
2016-03-11 20:42:49 +03:00
|
|
|
int mi_row = 0;
|
|
|
|
TileInfo tile_info;
|
|
|
|
|
2016-08-31 00:01:10 +03:00
|
|
|
av1_tile_set_row(&tile_info, cm, row);
|
2016-03-11 20:42:49 +03:00
|
|
|
|
|
|
|
for (tile_col = tile_cols_start; tile_col < tile_cols_end; ++tile_col) {
|
|
|
|
const int col = inv_col_order ? tile_cols - 1 - tile_col : tile_col;
|
2016-05-03 15:55:25 +03:00
|
|
|
TileData *const td = pbi->tile_data + tile_cols * row + col;
|
2016-03-11 20:42:49 +03:00
|
|
|
|
2016-08-31 00:01:10 +03:00
|
|
|
av1_tile_set_col(&tile_info, cm, col);
|
2016-03-11 20:42:49 +03:00
|
|
|
|
2016-08-31 00:01:10 +03:00
|
|
|
av1_zero_above_context(cm, tile_info.mi_col_start, tile_info.mi_col_end);
|
2016-03-11 20:42:49 +03:00
|
|
|
|
|
|
|
for (mi_row = tile_info.mi_row_start; mi_row < tile_info.mi_row_end;
|
Make superblock size variable at the frame level.
The uncompressed frame header contains a bit to signal whether the
frame is encoded using 64x64 or 128x128 superblocks. This can vary
between any 2 frames.
vpxenc gained the --sb-size={64,128,dynamic} option, which allows the
configuration of the superblock size used (default is dynamic). 64/128
will force the encoder to always use the specified superblock size.
Dynamic would enable the encoder to choose the sb size for each
frame, but this is not implemented yet (dynamic does the same as 128
for now).
Constraints on tile sizes depend on the superblock size, the following
is a summary of the current bitstream syntax and semantics:
If both --enable-ext-tile is OFF and --enable-ext-partition is OFF:
The tile coding in this case is the same as VP9. In particular,
tiles have a minimum width of 256 pixels and a maximum width of
4096 pixels. The tile width must be multiples of 64 pixels
(except for the rightmost tile column). There can be a maximum
of 64 tile columns and 4 tile rows.
If --enable-ext-tile is OFF and --enable-ext-partition is ON:
Same constraints as above, except that tile width must be
multiples of 128 pixels (except for the rightmost tile column).
There is no change in the bitstream syntax used for coding the tile
configuration if --enable-ext-tile is OFF.
If --enable-ext-tile is ON and --enable-ext-partition is ON:
This is the new large scale tile coding configuration. The
minimum/maximum tile width and height are 64/4096 pixels. Tile
width and height must be multiples of 64 pixels. The uncompressed
header contains two 6 bit fields that hold the tile width/heigh
in units of 64 pixels. The maximum number of tile rows/columns
is only limited by the maximum frame size of 65536x65536 pixels
that can be coded in the bitstream. This yields a maximum of
1024x1024 tile rows and columns (of 64x64 tiles in a 65536x65536
frame).
If both --enable-ext-tile is ON and --enable-ext-partition is ON:
Same applies as above, except that in the bitstream the 2 fields
containing the tile width/height are in units of the superblock
size, and the superblock size itself is also coded in the bitstream.
If the uncompressed header signals the use of 64x64 superblocks,
then the tile width/height fields are 6 bits wide and are in units
of 64 pixels. If the uncompressed header signals the use of 128x128
superblocks, then the tile width/height fields are 5 bits wide and
are in units of 128 pixels.
The above is a summary of the bitstream. The user interface to vpxenc
(and the equivalent encoder API) behaves a follows:
If --enable-ext-tile is OFF:
No change in the user interface. --tile-columns and --tile-rows
specify the base 2 logarithm of the desired number of tile columns
and tile rows. The actual number of tile rows and tile columns,
and the particular tile width and tile height are computed by the
codec ensuring all of the above constraints are respected.
If --enable-ext-tile is ON, but --enable-ext-partition is OFF:
No change in the user interface. --tile-columns and --tile-rows
specify the WIDTH and HEIGHT of the tiles in unit of 64 pixels.
The valid values are in the range [1, 64] (which corresponds to
[64, 4096] pixels in increments of 64.
If both --enable-ext-tile is ON and --enable-ext-partition is ON:
If --sb-size=64 (default):
The user interface is the same as in the previous point.
--tile-columns and --tile-rows specify tile WIDTH and HEIGHT,
in units of 64 pixels, in the range [1, 64] (which corresponds
to [64, 4096] pixels in increments of 64).
If --sb-size=128 or --sb-size=dynamic:
--tile-columns and --tile-rows specify tile WIDTH and HEIGHT,
in units of 128 pixels in the range [1, 32] (which corresponds
to [128, 4096] pixels in increments of 128).
Change-Id: Idc9beee1ad12ff1634e83671985d14c680f9179a
2016-03-24 16:56:05 +03:00
|
|
|
mi_row += cm->mib_size) {
|
2016-03-11 20:42:49 +03:00
|
|
|
int mi_col;
|
|
|
|
|
2016-08-31 00:01:10 +03:00
|
|
|
av1_zero_left_context(&td->xd);
|
2016-03-11 20:42:49 +03:00
|
|
|
|
|
|
|
for (mi_col = tile_info.mi_col_start; mi_col < tile_info.mi_col_end;
|
Make superblock size variable at the frame level.
The uncompressed frame header contains a bit to signal whether the
frame is encoded using 64x64 or 128x128 superblocks. This can vary
between any 2 frames.
vpxenc gained the --sb-size={64,128,dynamic} option, which allows the
configuration of the superblock size used (default is dynamic). 64/128
will force the encoder to always use the specified superblock size.
Dynamic would enable the encoder to choose the sb size for each
frame, but this is not implemented yet (dynamic does the same as 128
for now).
Constraints on tile sizes depend on the superblock size, the following
is a summary of the current bitstream syntax and semantics:
If both --enable-ext-tile is OFF and --enable-ext-partition is OFF:
The tile coding in this case is the same as VP9. In particular,
tiles have a minimum width of 256 pixels and a maximum width of
4096 pixels. The tile width must be multiples of 64 pixels
(except for the rightmost tile column). There can be a maximum
of 64 tile columns and 4 tile rows.
If --enable-ext-tile is OFF and --enable-ext-partition is ON:
Same constraints as above, except that tile width must be
multiples of 128 pixels (except for the rightmost tile column).
There is no change in the bitstream syntax used for coding the tile
configuration if --enable-ext-tile is OFF.
If --enable-ext-tile is ON and --enable-ext-partition is ON:
This is the new large scale tile coding configuration. The
minimum/maximum tile width and height are 64/4096 pixels. Tile
width and height must be multiples of 64 pixels. The uncompressed
header contains two 6 bit fields that hold the tile width/heigh
in units of 64 pixels. The maximum number of tile rows/columns
is only limited by the maximum frame size of 65536x65536 pixels
that can be coded in the bitstream. This yields a maximum of
1024x1024 tile rows and columns (of 64x64 tiles in a 65536x65536
frame).
If both --enable-ext-tile is ON and --enable-ext-partition is ON:
Same applies as above, except that in the bitstream the 2 fields
containing the tile width/height are in units of the superblock
size, and the superblock size itself is also coded in the bitstream.
If the uncompressed header signals the use of 64x64 superblocks,
then the tile width/height fields are 6 bits wide and are in units
of 64 pixels. If the uncompressed header signals the use of 128x128
superblocks, then the tile width/height fields are 5 bits wide and
are in units of 128 pixels.
The above is a summary of the bitstream. The user interface to vpxenc
(and the equivalent encoder API) behaves a follows:
If --enable-ext-tile is OFF:
No change in the user interface. --tile-columns and --tile-rows
specify the base 2 logarithm of the desired number of tile columns
and tile rows. The actual number of tile rows and tile columns,
and the particular tile width and tile height are computed by the
codec ensuring all of the above constraints are respected.
If --enable-ext-tile is ON, but --enable-ext-partition is OFF:
No change in the user interface. --tile-columns and --tile-rows
specify the WIDTH and HEIGHT of the tiles in unit of 64 pixels.
The valid values are in the range [1, 64] (which corresponds to
[64, 4096] pixels in increments of 64.
If both --enable-ext-tile is ON and --enable-ext-partition is ON:
If --sb-size=64 (default):
The user interface is the same as in the previous point.
--tile-columns and --tile-rows specify tile WIDTH and HEIGHT,
in units of 64 pixels, in the range [1, 64] (which corresponds
to [64, 4096] pixels in increments of 64).
If --sb-size=128 or --sb-size=dynamic:
--tile-columns and --tile-rows specify tile WIDTH and HEIGHT,
in units of 128 pixels in the range [1, 32] (which corresponds
to [128, 4096] pixels in increments of 128).
Change-Id: Idc9beee1ad12ff1634e83671985d14c680f9179a
2016-03-24 16:56:05 +03:00
|
|
|
mi_col += cm->mib_size) {
|
2016-03-11 20:42:49 +03:00
|
|
|
decode_partition(pbi, &td->xd,
|
2015-11-20 03:51:16 +03:00
|
|
|
#if CONFIG_SUPERTX
|
|
|
|
0,
|
2016-03-11 20:42:49 +03:00
|
|
|
#endif // CONFIG_SUPERTX
|
2016-08-12 04:53:26 +03:00
|
|
|
mi_row, mi_col, &td->bit_reader, cm->sb_size,
|
|
|
|
b_width_log2_lookup[cm->sb_size]);
|
2015-08-06 05:00:31 +03:00
|
|
|
}
|
2016-03-11 20:42:49 +03:00
|
|
|
pbi->mb.corrupted |= td->xd.corrupted;
|
2015-08-06 05:00:31 +03:00
|
|
|
if (pbi->mb.corrupted)
|
2016-08-31 00:01:10 +03:00
|
|
|
aom_internal_error(&cm->error, AOM_CODEC_CORRUPT_FRAME,
|
2016-08-12 04:53:26 +03:00
|
|
|
"Failed to decode tile data");
|
2016-01-08 01:29:26 +03:00
|
|
|
#if CONFIG_ENTROPY
|
|
|
|
if (cm->do_subframe_update &&
|
|
|
|
cm->refresh_frame_context == REFRESH_FRAME_CONTEXT_BACKWARD) {
|
2016-08-12 04:53:26 +03:00
|
|
|
if ((mi_row + MI_SIZE) %
|
|
|
|
(MI_SIZE *
|
2016-08-31 00:01:10 +03:00
|
|
|
AOMMAX(cm->mi_rows / MI_SIZE / COEF_PROBS_BUFS, 1)) ==
|
2016-08-12 04:53:26 +03:00
|
|
|
0 &&
|
2016-01-08 01:29:26 +03:00
|
|
|
mi_row + MI_SIZE < cm->mi_rows &&
|
|
|
|
cm->coef_probs_update_idx < COEF_PROBS_BUFS - 1) {
|
2016-08-31 00:01:10 +03:00
|
|
|
av1_partial_adapt_probs(cm, mi_row, mi_col);
|
2016-01-08 01:29:26 +03:00
|
|
|
++cm->coef_probs_update_idx;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
#endif // CONFIG_ENTROPY
|
2015-08-06 05:00:31 +03:00
|
|
|
}
|
2016-03-11 20:42:49 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
assert(mi_row > 0);
|
|
|
|
|
2015-10-17 01:54:58 +03:00
|
|
|
#if !CONFIG_VAR_TX
|
2016-03-11 20:42:49 +03:00
|
|
|
// Loopfilter one tile row.
|
|
|
|
if (cm->lf.filter_level && !cm->skip_loop_filter) {
|
2016-08-12 04:53:26 +03:00
|
|
|
LFWorkerData *const lf_data = (LFWorkerData *)pbi->lf_worker.data1;
|
2016-08-31 00:01:10 +03:00
|
|
|
const int lf_start = AOMMAX(0, tile_info.mi_row_start - cm->mib_size);
|
Make superblock size variable at the frame level.
The uncompressed frame header contains a bit to signal whether the
frame is encoded using 64x64 or 128x128 superblocks. This can vary
between any 2 frames.
vpxenc gained the --sb-size={64,128,dynamic} option, which allows the
configuration of the superblock size used (default is dynamic). 64/128
will force the encoder to always use the specified superblock size.
Dynamic would enable the encoder to choose the sb size for each
frame, but this is not implemented yet (dynamic does the same as 128
for now).
Constraints on tile sizes depend on the superblock size, the following
is a summary of the current bitstream syntax and semantics:
If both --enable-ext-tile is OFF and --enable-ext-partition is OFF:
The tile coding in this case is the same as VP9. In particular,
tiles have a minimum width of 256 pixels and a maximum width of
4096 pixels. The tile width must be multiples of 64 pixels
(except for the rightmost tile column). There can be a maximum
of 64 tile columns and 4 tile rows.
If --enable-ext-tile is OFF and --enable-ext-partition is ON:
Same constraints as above, except that tile width must be
multiples of 128 pixels (except for the rightmost tile column).
There is no change in the bitstream syntax used for coding the tile
configuration if --enable-ext-tile is OFF.
If --enable-ext-tile is ON and --enable-ext-partition is ON:
This is the new large scale tile coding configuration. The
minimum/maximum tile width and height are 64/4096 pixels. Tile
width and height must be multiples of 64 pixels. The uncompressed
header contains two 6 bit fields that hold the tile width/heigh
in units of 64 pixels. The maximum number of tile rows/columns
is only limited by the maximum frame size of 65536x65536 pixels
that can be coded in the bitstream. This yields a maximum of
1024x1024 tile rows and columns (of 64x64 tiles in a 65536x65536
frame).
If both --enable-ext-tile is ON and --enable-ext-partition is ON:
Same applies as above, except that in the bitstream the 2 fields
containing the tile width/height are in units of the superblock
size, and the superblock size itself is also coded in the bitstream.
If the uncompressed header signals the use of 64x64 superblocks,
then the tile width/height fields are 6 bits wide and are in units
of 64 pixels. If the uncompressed header signals the use of 128x128
superblocks, then the tile width/height fields are 5 bits wide and
are in units of 128 pixels.
The above is a summary of the bitstream. The user interface to vpxenc
(and the equivalent encoder API) behaves a follows:
If --enable-ext-tile is OFF:
No change in the user interface. --tile-columns and --tile-rows
specify the base 2 logarithm of the desired number of tile columns
and tile rows. The actual number of tile rows and tile columns,
and the particular tile width and tile height are computed by the
codec ensuring all of the above constraints are respected.
If --enable-ext-tile is ON, but --enable-ext-partition is OFF:
No change in the user interface. --tile-columns and --tile-rows
specify the WIDTH and HEIGHT of the tiles in unit of 64 pixels.
The valid values are in the range [1, 64] (which corresponds to
[64, 4096] pixels in increments of 64.
If both --enable-ext-tile is ON and --enable-ext-partition is ON:
If --sb-size=64 (default):
The user interface is the same as in the previous point.
--tile-columns and --tile-rows specify tile WIDTH and HEIGHT,
in units of 64 pixels, in the range [1, 64] (which corresponds
to [64, 4096] pixels in increments of 64).
If --sb-size=128 or --sb-size=dynamic:
--tile-columns and --tile-rows specify tile WIDTH and HEIGHT,
in units of 128 pixels in the range [1, 32] (which corresponds
to [128, 4096] pixels in increments of 128).
Change-Id: Idc9beee1ad12ff1634e83671985d14c680f9179a
2016-03-24 16:56:05 +03:00
|
|
|
const int lf_end = tile_info.mi_row_end - cm->mib_size;
|
2016-03-11 20:42:49 +03:00
|
|
|
|
|
|
|
// Delay the loopfilter if the first tile row is only
|
|
|
|
// a single superblock high.
|
2016-08-12 04:53:26 +03:00
|
|
|
if (lf_end <= 0) continue;
|
2016-03-11 20:42:49 +03:00
|
|
|
|
|
|
|
// Decoding has completed. Finish up the loop filter in this thread.
|
2016-08-12 04:53:26 +03:00
|
|
|
if (tile_info.mi_row_end >= cm->mi_rows) continue;
|
2016-03-11 20:42:49 +03:00
|
|
|
|
|
|
|
winterface->sync(&pbi->lf_worker);
|
|
|
|
lf_data->start = lf_start;
|
|
|
|
lf_data->stop = lf_end;
|
|
|
|
if (pbi->max_threads > 1) {
|
|
|
|
winterface->launch(&pbi->lf_worker);
|
|
|
|
} else {
|
|
|
|
winterface->execute(&pbi->lf_worker);
|
2015-08-06 05:00:31 +03:00
|
|
|
}
|
|
|
|
}
|
2016-03-11 20:42:49 +03:00
|
|
|
|
|
|
|
// After loopfiltering, the last 7 row pixels in each superblock row may
|
|
|
|
// still be changed by the longest loopfilter of the next superblock row.
|
|
|
|
if (cm->frame_parallel_decode)
|
2016-08-31 00:01:10 +03:00
|
|
|
av1_frameworker_broadcast(pbi->cur_buf, mi_row << cm->mib_size_log2);
|
2016-03-11 20:42:49 +03:00
|
|
|
#endif // !CONFIG_VAR_TX
|
2015-08-06 05:00:31 +03:00
|
|
|
}
|
|
|
|
|
2015-10-17 01:54:58 +03:00
|
|
|
#if CONFIG_VAR_TX
|
2016-03-11 20:42:49 +03:00
|
|
|
// Loopfilter the whole frame.
|
2016-08-31 00:01:10 +03:00
|
|
|
av1_loop_filter_frame(get_frame_new_buffer(cm), cm, &pbi->mb,
|
|
|
|
cm->lf.filter_level, 0, 0);
|
2015-10-17 01:54:58 +03:00
|
|
|
#else
|
2016-03-11 20:42:49 +03:00
|
|
|
// Loopfilter remaining rows in the frame.
|
2015-08-06 05:00:31 +03:00
|
|
|
if (cm->lf.filter_level && !cm->skip_loop_filter) {
|
2016-08-12 04:53:26 +03:00
|
|
|
LFWorkerData *const lf_data = (LFWorkerData *)pbi->lf_worker.data1;
|
2015-08-06 05:00:31 +03:00
|
|
|
winterface->sync(&pbi->lf_worker);
|
|
|
|
lf_data->start = lf_data->stop;
|
|
|
|
lf_data->stop = cm->mi_rows;
|
|
|
|
winterface->execute(&pbi->lf_worker);
|
|
|
|
}
|
2016-03-11 20:42:49 +03:00
|
|
|
#endif // CONFIG_VAR_TX
|
2015-09-07 17:14:18 +03:00
|
|
|
if (cm->frame_parallel_decode)
|
2016-08-31 00:01:10 +03:00
|
|
|
av1_frameworker_broadcast(pbi->cur_buf, INT_MAX);
|
2016-03-11 20:42:49 +03:00
|
|
|
|
2016-05-03 20:25:01 +03:00
|
|
|
#if CONFIG_EXT_TILE
|
|
|
|
if (n_tiles == 1) {
|
|
|
|
#if CONFIG_ANS
|
|
|
|
return data_end;
|
|
|
|
#else
|
|
|
|
// Find the end of the single tile buffer
|
2016-08-31 00:01:10 +03:00
|
|
|
return aom_reader_find_end(&pbi->tile_data->bit_reader);
|
2016-05-03 20:25:01 +03:00
|
|
|
#endif // CONFIG_ANS
|
|
|
|
} else {
|
|
|
|
// Return the end of the last tile buffer
|
|
|
|
return tile_buffers[tile_rows - 1][tile_cols - 1].raw_data_end;
|
|
|
|
}
|
|
|
|
#else
|
|
|
|
#if CONFIG_ANS
|
2015-12-16 22:17:25 +03:00
|
|
|
return data_end;
|
|
|
|
#else
|
2016-03-11 20:42:49 +03:00
|
|
|
{
|
|
|
|
// Get last tile data.
|
|
|
|
TileData *const td = pbi->tile_data + tile_cols * tile_rows - 1;
|
2016-08-31 00:01:10 +03:00
|
|
|
return aom_reader_find_end(&td->bit_reader);
|
2016-03-11 20:42:49 +03:00
|
|
|
}
|
2016-05-03 20:25:01 +03:00
|
|
|
#endif // CONFIG_ANS
|
|
|
|
#endif // CONFIG_EXT_TILE
|
2015-08-06 05:00:31 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
static int tile_worker_hook(TileWorkerData *const tile_data,
|
|
|
|
const TileInfo *const tile) {
|
2016-08-31 00:01:10 +03:00
|
|
|
AV1Decoder *const pbi = tile_data->pbi;
|
|
|
|
const AV1_COMMON *const cm = &pbi->common;
|
2015-08-06 05:00:31 +03:00
|
|
|
int mi_row, mi_col;
|
|
|
|
|
|
|
|
if (setjmp(tile_data->error_info.jmp)) {
|
|
|
|
tile_data->error_info.setjmp = 0;
|
|
|
|
tile_data->xd.corrupted = 1;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
tile_data->error_info.setjmp = 1;
|
|
|
|
tile_data->xd.error_info = &tile_data->error_info;
|
|
|
|
|
2016-08-31 00:01:10 +03:00
|
|
|
av1_zero_above_context(&pbi->common, tile->mi_col_start, tile->mi_col_end);
|
2016-03-11 20:42:49 +03:00
|
|
|
|
2015-08-06 05:00:31 +03:00
|
|
|
for (mi_row = tile->mi_row_start; mi_row < tile->mi_row_end;
|
Make superblock size variable at the frame level.
The uncompressed frame header contains a bit to signal whether the
frame is encoded using 64x64 or 128x128 superblocks. This can vary
between any 2 frames.
vpxenc gained the --sb-size={64,128,dynamic} option, which allows the
configuration of the superblock size used (default is dynamic). 64/128
will force the encoder to always use the specified superblock size.
Dynamic would enable the encoder to choose the sb size for each
frame, but this is not implemented yet (dynamic does the same as 128
for now).
Constraints on tile sizes depend on the superblock size, the following
is a summary of the current bitstream syntax and semantics:
If both --enable-ext-tile is OFF and --enable-ext-partition is OFF:
The tile coding in this case is the same as VP9. In particular,
tiles have a minimum width of 256 pixels and a maximum width of
4096 pixels. The tile width must be multiples of 64 pixels
(except for the rightmost tile column). There can be a maximum
of 64 tile columns and 4 tile rows.
If --enable-ext-tile is OFF and --enable-ext-partition is ON:
Same constraints as above, except that tile width must be
multiples of 128 pixels (except for the rightmost tile column).
There is no change in the bitstream syntax used for coding the tile
configuration if --enable-ext-tile is OFF.
If --enable-ext-tile is ON and --enable-ext-partition is ON:
This is the new large scale tile coding configuration. The
minimum/maximum tile width and height are 64/4096 pixels. Tile
width and height must be multiples of 64 pixels. The uncompressed
header contains two 6 bit fields that hold the tile width/heigh
in units of 64 pixels. The maximum number of tile rows/columns
is only limited by the maximum frame size of 65536x65536 pixels
that can be coded in the bitstream. This yields a maximum of
1024x1024 tile rows and columns (of 64x64 tiles in a 65536x65536
frame).
If both --enable-ext-tile is ON and --enable-ext-partition is ON:
Same applies as above, except that in the bitstream the 2 fields
containing the tile width/height are in units of the superblock
size, and the superblock size itself is also coded in the bitstream.
If the uncompressed header signals the use of 64x64 superblocks,
then the tile width/height fields are 6 bits wide and are in units
of 64 pixels. If the uncompressed header signals the use of 128x128
superblocks, then the tile width/height fields are 5 bits wide and
are in units of 128 pixels.
The above is a summary of the bitstream. The user interface to vpxenc
(and the equivalent encoder API) behaves a follows:
If --enable-ext-tile is OFF:
No change in the user interface. --tile-columns and --tile-rows
specify the base 2 logarithm of the desired number of tile columns
and tile rows. The actual number of tile rows and tile columns,
and the particular tile width and tile height are computed by the
codec ensuring all of the above constraints are respected.
If --enable-ext-tile is ON, but --enable-ext-partition is OFF:
No change in the user interface. --tile-columns and --tile-rows
specify the WIDTH and HEIGHT of the tiles in unit of 64 pixels.
The valid values are in the range [1, 64] (which corresponds to
[64, 4096] pixels in increments of 64.
If both --enable-ext-tile is ON and --enable-ext-partition is ON:
If --sb-size=64 (default):
The user interface is the same as in the previous point.
--tile-columns and --tile-rows specify tile WIDTH and HEIGHT,
in units of 64 pixels, in the range [1, 64] (which corresponds
to [64, 4096] pixels in increments of 64).
If --sb-size=128 or --sb-size=dynamic:
--tile-columns and --tile-rows specify tile WIDTH and HEIGHT,
in units of 128 pixels in the range [1, 32] (which corresponds
to [128, 4096] pixels in increments of 128).
Change-Id: Idc9beee1ad12ff1634e83671985d14c680f9179a
2016-03-24 16:56:05 +03:00
|
|
|
mi_row += cm->mib_size) {
|
2016-08-31 00:01:10 +03:00
|
|
|
av1_zero_left_context(&tile_data->xd);
|
2016-03-11 20:42:49 +03:00
|
|
|
|
2015-08-06 05:00:31 +03:00
|
|
|
for (mi_col = tile->mi_col_start; mi_col < tile->mi_col_end;
|
Make superblock size variable at the frame level.
The uncompressed frame header contains a bit to signal whether the
frame is encoded using 64x64 or 128x128 superblocks. This can vary
between any 2 frames.
vpxenc gained the --sb-size={64,128,dynamic} option, which allows the
configuration of the superblock size used (default is dynamic). 64/128
will force the encoder to always use the specified superblock size.
Dynamic would enable the encoder to choose the sb size for each
frame, but this is not implemented yet (dynamic does the same as 128
for now).
Constraints on tile sizes depend on the superblock size, the following
is a summary of the current bitstream syntax and semantics:
If both --enable-ext-tile is OFF and --enable-ext-partition is OFF:
The tile coding in this case is the same as VP9. In particular,
tiles have a minimum width of 256 pixels and a maximum width of
4096 pixels. The tile width must be multiples of 64 pixels
(except for the rightmost tile column). There can be a maximum
of 64 tile columns and 4 tile rows.
If --enable-ext-tile is OFF and --enable-ext-partition is ON:
Same constraints as above, except that tile width must be
multiples of 128 pixels (except for the rightmost tile column).
There is no change in the bitstream syntax used for coding the tile
configuration if --enable-ext-tile is OFF.
If --enable-ext-tile is ON and --enable-ext-partition is ON:
This is the new large scale tile coding configuration. The
minimum/maximum tile width and height are 64/4096 pixels. Tile
width and height must be multiples of 64 pixels. The uncompressed
header contains two 6 bit fields that hold the tile width/heigh
in units of 64 pixels. The maximum number of tile rows/columns
is only limited by the maximum frame size of 65536x65536 pixels
that can be coded in the bitstream. This yields a maximum of
1024x1024 tile rows and columns (of 64x64 tiles in a 65536x65536
frame).
If both --enable-ext-tile is ON and --enable-ext-partition is ON:
Same applies as above, except that in the bitstream the 2 fields
containing the tile width/height are in units of the superblock
size, and the superblock size itself is also coded in the bitstream.
If the uncompressed header signals the use of 64x64 superblocks,
then the tile width/height fields are 6 bits wide and are in units
of 64 pixels. If the uncompressed header signals the use of 128x128
superblocks, then the tile width/height fields are 5 bits wide and
are in units of 128 pixels.
The above is a summary of the bitstream. The user interface to vpxenc
(and the equivalent encoder API) behaves a follows:
If --enable-ext-tile is OFF:
No change in the user interface. --tile-columns and --tile-rows
specify the base 2 logarithm of the desired number of tile columns
and tile rows. The actual number of tile rows and tile columns,
and the particular tile width and tile height are computed by the
codec ensuring all of the above constraints are respected.
If --enable-ext-tile is ON, but --enable-ext-partition is OFF:
No change in the user interface. --tile-columns and --tile-rows
specify the WIDTH and HEIGHT of the tiles in unit of 64 pixels.
The valid values are in the range [1, 64] (which corresponds to
[64, 4096] pixels in increments of 64.
If both --enable-ext-tile is ON and --enable-ext-partition is ON:
If --sb-size=64 (default):
The user interface is the same as in the previous point.
--tile-columns and --tile-rows specify tile WIDTH and HEIGHT,
in units of 64 pixels, in the range [1, 64] (which corresponds
to [64, 4096] pixels in increments of 64).
If --sb-size=128 or --sb-size=dynamic:
--tile-columns and --tile-rows specify tile WIDTH and HEIGHT,
in units of 128 pixels in the range [1, 32] (which corresponds
to [128, 4096] pixels in increments of 128).
Change-Id: Idc9beee1ad12ff1634e83671985d14c680f9179a
2016-03-24 16:56:05 +03:00
|
|
|
mi_col += cm->mib_size) {
|
2016-03-11 20:42:49 +03:00
|
|
|
decode_partition(pbi, &tile_data->xd,
|
2015-11-20 03:51:16 +03:00
|
|
|
#if CONFIG_SUPERTX
|
|
|
|
0,
|
|
|
|
#endif
|
2016-08-12 04:53:26 +03:00
|
|
|
mi_row, mi_col, &tile_data->bit_reader, cm->sb_size,
|
|
|
|
b_width_log2_lookup[cm->sb_size]);
|
2015-08-06 05:00:31 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
return !tile_data->xd.corrupted;
|
|
|
|
}
|
|
|
|
|
|
|
|
// sorts in descending order
|
|
|
|
static int compare_tile_buffers(const void *a, const void *b) {
|
2016-08-12 04:53:26 +03:00
|
|
|
const TileBufferDec *const buf1 = (const TileBufferDec *)a;
|
|
|
|
const TileBufferDec *const buf2 = (const TileBufferDec *)b;
|
2015-08-06 05:00:31 +03:00
|
|
|
return (int)(buf2->size - buf1->size);
|
|
|
|
}
|
|
|
|
|
2016-08-31 00:01:10 +03:00
|
|
|
static const uint8_t *decode_tiles_mt(AV1Decoder *pbi, const uint8_t *data,
|
2015-08-06 05:00:31 +03:00
|
|
|
const uint8_t *data_end) {
|
2016-08-31 00:01:10 +03:00
|
|
|
AV1_COMMON *const cm = &pbi->common;
|
|
|
|
const AVxWorkerInterface *const winterface = aom_get_worker_interface();
|
2016-03-11 20:42:49 +03:00
|
|
|
const int tile_cols = cm->tile_cols;
|
|
|
|
const int tile_rows = cm->tile_rows;
|
2016-08-31 00:01:10 +03:00
|
|
|
const int num_workers = AOMMIN(pbi->max_threads & ~1, tile_cols);
|
2016-09-08 08:40:40 +03:00
|
|
|
TileBufferDec(*const tile_buffers)[MAX_TILE_COLS] = pbi->tile_buffers;
|
2016-03-11 20:42:49 +03:00
|
|
|
#if CONFIG_EXT_TILE
|
2016-08-31 00:01:10 +03:00
|
|
|
const int dec_tile_row = AOMMIN(pbi->dec_tile_row, tile_rows);
|
2016-03-11 20:42:49 +03:00
|
|
|
const int single_row = pbi->dec_tile_row >= 0;
|
|
|
|
const int tile_rows_start = single_row ? dec_tile_row : 0;
|
|
|
|
const int tile_rows_end = single_row ? dec_tile_row + 1 : tile_rows;
|
2016-08-31 00:01:10 +03:00
|
|
|
const int dec_tile_col = AOMMIN(pbi->dec_tile_col, tile_cols);
|
2016-03-11 20:42:49 +03:00
|
|
|
const int single_col = pbi->dec_tile_col >= 0;
|
|
|
|
const int tile_cols_start = single_col ? dec_tile_col : 0;
|
|
|
|
const int tile_cols_end = single_col ? tile_cols_start + 1 : tile_cols;
|
|
|
|
#else
|
|
|
|
const int tile_rows_start = 0;
|
|
|
|
const int tile_rows_end = tile_rows;
|
|
|
|
const int tile_cols_start = 0;
|
|
|
|
const int tile_cols_end = tile_cols;
|
|
|
|
#endif // CONFIG_EXT_TILE
|
|
|
|
int tile_row, tile_col;
|
|
|
|
int i;
|
|
|
|
|
|
|
|
#if !(CONFIG_ANS || CONFIG_EXT_TILE)
|
2015-08-06 05:00:31 +03:00
|
|
|
int final_worker = -1;
|
2016-03-11 20:42:49 +03:00
|
|
|
#endif // !(CONFIG_ANS || CONFIG_EXT_TILE)
|
|
|
|
|
|
|
|
assert(tile_rows <= MAX_TILE_ROWS);
|
|
|
|
assert(tile_cols <= MAX_TILE_COLS);
|
2015-08-06 05:00:31 +03:00
|
|
|
|
2016-05-03 20:25:01 +03:00
|
|
|
assert(tile_cols * tile_rows > 1);
|
|
|
|
|
2015-12-16 22:17:25 +03:00
|
|
|
#if CONFIG_ANS
|
2016-03-11 20:42:49 +03:00
|
|
|
// TODO(any): This might just work now. Needs to be tested.
|
2015-12-16 22:17:25 +03:00
|
|
|
abort(); // FIXME: Tile parsing broken
|
2016-08-12 04:53:26 +03:00
|
|
|
#endif // CONFIG_ANS
|
2015-08-06 05:00:31 +03:00
|
|
|
|
|
|
|
// TODO(jzern): See if we can remove the restriction of passing in max
|
|
|
|
// threads to the decoder.
|
|
|
|
if (pbi->num_tile_workers == 0) {
|
|
|
|
const int num_threads = pbi->max_threads & ~1;
|
|
|
|
CHECK_MEM_ERROR(cm, pbi->tile_workers,
|
2016-08-31 00:01:10 +03:00
|
|
|
aom_malloc(num_threads * sizeof(*pbi->tile_workers)));
|
2015-08-06 05:00:31 +03:00
|
|
|
// Ensure tile data offsets will be properly aligned. This may fail on
|
|
|
|
// platforms without DECLARE_ALIGNED().
|
|
|
|
assert((sizeof(*pbi->tile_worker_data) % 16) == 0);
|
2016-08-12 04:53:26 +03:00
|
|
|
CHECK_MEM_ERROR(
|
|
|
|
cm, pbi->tile_worker_data,
|
2016-08-31 00:01:10 +03:00
|
|
|
aom_memalign(32, num_threads * sizeof(*pbi->tile_worker_data)));
|
2015-08-06 05:00:31 +03:00
|
|
|
CHECK_MEM_ERROR(cm, pbi->tile_worker_info,
|
2016-08-31 00:01:10 +03:00
|
|
|
aom_malloc(num_threads * sizeof(*pbi->tile_worker_info)));
|
2015-08-06 05:00:31 +03:00
|
|
|
for (i = 0; i < num_threads; ++i) {
|
2016-08-31 00:01:10 +03:00
|
|
|
AVxWorker *const worker = &pbi->tile_workers[i];
|
2015-08-06 05:00:31 +03:00
|
|
|
++pbi->num_tile_workers;
|
|
|
|
|
|
|
|
winterface->init(worker);
|
|
|
|
if (i < num_threads - 1 && !winterface->reset(worker)) {
|
2016-08-31 00:01:10 +03:00
|
|
|
aom_internal_error(&cm->error, AOM_CODEC_ERROR,
|
2015-08-06 05:00:31 +03:00
|
|
|
"Tile decoder thread creation failed");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Reset tile decoding hook
|
2016-03-11 20:42:49 +03:00
|
|
|
for (i = 0; i < num_workers; ++i) {
|
2016-08-31 00:01:10 +03:00
|
|
|
AVxWorker *const worker = &pbi->tile_workers[i];
|
2015-08-06 05:00:31 +03:00
|
|
|
winterface->sync(worker);
|
2016-08-31 00:01:10 +03:00
|
|
|
worker->hook = (AVxWorkerHook)tile_worker_hook;
|
2016-03-11 20:42:49 +03:00
|
|
|
worker->data1 = &pbi->tile_worker_data[i];
|
|
|
|
worker->data2 = &pbi->tile_worker_info[i];
|
2015-08-06 05:00:31 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
// Initialize thread frame counts.
|
2015-09-08 21:20:48 +03:00
|
|
|
if (cm->refresh_frame_context == REFRESH_FRAME_CONTEXT_BACKWARD) {
|
2015-08-06 05:00:31 +03:00
|
|
|
for (i = 0; i < num_workers; ++i) {
|
2016-08-12 04:53:26 +03:00
|
|
|
TileWorkerData *const twd = (TileWorkerData *)pbi->tile_workers[i].data1;
|
2016-08-31 00:01:10 +03:00
|
|
|
av1_zero(twd->counts);
|
2015-08-06 05:00:31 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-03-11 20:42:49 +03:00
|
|
|
// Load tile data into tile_buffers
|
|
|
|
get_tile_buffers(pbi, data, data_end, tile_buffers);
|
|
|
|
|
2016-08-12 04:53:26 +03:00
|
|
|
for (tile_row = tile_rows_start; tile_row < tile_rows_end; ++tile_row) {
|
2016-03-11 20:42:49 +03:00
|
|
|
// Sort the buffers in this tile row based on size in descending order.
|
|
|
|
qsort(&tile_buffers[tile_row][tile_cols_start],
|
|
|
|
tile_cols_end - tile_cols_start, sizeof(tile_buffers[0][0]),
|
|
|
|
compare_tile_buffers);
|
|
|
|
|
|
|
|
// Rearrange the tile buffers in this tile row such that per-tile group
|
|
|
|
// the largest, and presumably the most difficult tile will be decoded in
|
|
|
|
// the main thread. This should help minimize the number of instances
|
|
|
|
// where the main thread is waiting for a worker to complete.
|
|
|
|
{
|
|
|
|
int group_start;
|
2016-08-12 04:53:26 +03:00
|
|
|
for (group_start = tile_cols_start; group_start < tile_cols_end;
|
2016-03-11 20:42:49 +03:00
|
|
|
group_start += num_workers) {
|
2016-08-31 00:01:10 +03:00
|
|
|
const int group_end = AOMMIN(group_start + num_workers, tile_cols);
|
2016-03-11 20:42:49 +03:00
|
|
|
const TileBufferDec largest = tile_buffers[tile_row][group_start];
|
|
|
|
memmove(&tile_buffers[tile_row][group_start],
|
|
|
|
&tile_buffers[tile_row][group_start + 1],
|
|
|
|
(group_end - group_start - 1) * sizeof(tile_buffers[0][0]));
|
|
|
|
tile_buffers[tile_row][group_end - 1] = largest;
|
2015-08-06 05:00:31 +03:00
|
|
|
}
|
2016-03-11 20:42:49 +03:00
|
|
|
}
|
2015-08-06 05:00:31 +03:00
|
|
|
|
2016-08-12 04:53:26 +03:00
|
|
|
for (tile_col = tile_cols_start; tile_col < tile_cols_end;) {
|
2016-03-11 20:42:49 +03:00
|
|
|
// Launch workers for individual columns
|
|
|
|
for (i = 0; i < num_workers && tile_col < tile_cols_end;
|
|
|
|
++i, ++tile_col) {
|
|
|
|
TileBufferDec *const buf = &tile_buffers[tile_row][tile_col];
|
2016-08-31 00:01:10 +03:00
|
|
|
AVxWorker *const worker = &pbi->tile_workers[i];
|
2016-08-12 04:53:26 +03:00
|
|
|
TileWorkerData *const twd = (TileWorkerData *)worker->data1;
|
|
|
|
TileInfo *const tile_info = (TileInfo *)worker->data2;
|
2016-03-11 20:42:49 +03:00
|
|
|
|
|
|
|
twd->pbi = pbi;
|
|
|
|
twd->xd = pbi->mb;
|
|
|
|
twd->xd.corrupted = 0;
|
|
|
|
twd->xd.counts =
|
2016-08-12 04:53:26 +03:00
|
|
|
cm->refresh_frame_context == REFRESH_FRAME_CONTEXT_BACKWARD
|
|
|
|
? &twd->counts
|
|
|
|
: NULL;
|
2016-08-31 00:01:10 +03:00
|
|
|
av1_zero(twd->dqcoeff);
|
|
|
|
av1_tile_init(tile_info, cm, tile_row, buf->col);
|
|
|
|
av1_tile_init(&twd->xd.tile, cm, tile_row, buf->col);
|
2016-03-22 20:33:34 +03:00
|
|
|
#if !CONFIG_ANS
|
2016-03-11 20:42:49 +03:00
|
|
|
setup_bool_decoder(buf->data, data_end, buf->size, &cm->error,
|
2016-08-12 04:53:26 +03:00
|
|
|
&twd->bit_reader, pbi->decrypt_cb,
|
|
|
|
pbi->decrypt_state);
|
2016-03-22 20:33:34 +03:00
|
|
|
#else
|
2016-03-11 20:42:49 +03:00
|
|
|
setup_token_decoder(buf->data, data_end, buf->size, &cm->error,
|
2016-03-22 20:33:34 +03:00
|
|
|
&twd->bit_reader, pbi->decrypt_cb,
|
2016-03-11 20:42:49 +03:00
|
|
|
pbi->decrypt_state);
|
|
|
|
#endif // CONFIG_ANS
|
2016-08-31 00:01:10 +03:00
|
|
|
av1_init_macroblockd(cm, &twd->xd, twd->dqcoeff);
|
2016-03-11 20:42:49 +03:00
|
|
|
twd->xd.plane[0].color_index_map = twd->color_index_map[0];
|
|
|
|
twd->xd.plane[1].color_index_map = twd->color_index_map[1];
|
2015-08-06 05:00:31 +03:00
|
|
|
|
2016-03-11 20:42:49 +03:00
|
|
|
worker->had_error = 0;
|
|
|
|
if (i == num_workers - 1 || tile_col == tile_cols_end - 1) {
|
|
|
|
winterface->execute(worker);
|
|
|
|
} else {
|
|
|
|
winterface->launch(worker);
|
|
|
|
}
|
2015-08-06 05:00:31 +03:00
|
|
|
|
2016-03-11 20:42:49 +03:00
|
|
|
#if !(CONFIG_ANS || CONFIG_EXT_TILE)
|
|
|
|
if (tile_row == tile_rows - 1 && buf->col == tile_cols - 1) {
|
|
|
|
final_worker = i;
|
|
|
|
}
|
|
|
|
#endif // !(CONFIG_ANS || CONFIG_EXT_TILE)
|
|
|
|
}
|
2015-08-06 05:00:31 +03:00
|
|
|
|
2016-03-11 20:42:49 +03:00
|
|
|
// Sync all workers
|
|
|
|
for (; i > 0; --i) {
|
2016-08-31 00:01:10 +03:00
|
|
|
AVxWorker *const worker = &pbi->tile_workers[i - 1];
|
2016-03-11 20:42:49 +03:00
|
|
|
// TODO(jzern): The tile may have specific error data associated with
|
2016-08-31 00:01:10 +03:00
|
|
|
// its aom_internal_error_info which could be propagated to the main
|
2016-03-11 20:42:49 +03:00
|
|
|
// info in cm. Additionally once the threads have been synced and an
|
|
|
|
// error is detected, there's no point in continuing to decode tiles.
|
|
|
|
pbi->mb.corrupted |= !winterface->sync(worker);
|
2015-08-06 05:00:31 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-03-11 20:42:49 +03:00
|
|
|
// Accumulate thread frame counts.
|
|
|
|
if (cm->refresh_frame_context == REFRESH_FRAME_CONTEXT_BACKWARD) {
|
|
|
|
for (i = 0; i < num_workers; ++i) {
|
2016-08-12 04:53:26 +03:00
|
|
|
TileWorkerData *const twd = (TileWorkerData *)pbi->tile_workers[i].data1;
|
2016-08-31 00:01:10 +03:00
|
|
|
av1_accumulate_frame_counts(cm, &twd->counts);
|
2016-03-11 20:42:49 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-05-03 20:25:01 +03:00
|
|
|
#if CONFIG_EXT_TILE
|
|
|
|
// Return the end of the last tile buffer
|
|
|
|
return tile_buffers[tile_rows - 1][tile_cols - 1].raw_data_end;
|
|
|
|
#else
|
|
|
|
#if CONFIG_ANS
|
2016-03-11 20:42:49 +03:00
|
|
|
return data_end;
|
|
|
|
#else
|
|
|
|
assert(final_worker != -1);
|
|
|
|
{
|
|
|
|
TileWorkerData *const twd =
|
2016-08-12 04:53:26 +03:00
|
|
|
(TileWorkerData *)pbi->tile_workers[final_worker].data1;
|
2016-08-31 00:01:10 +03:00
|
|
|
return aom_reader_find_end(&twd->bit_reader);
|
2016-03-11 20:42:49 +03:00
|
|
|
}
|
2016-05-03 20:25:01 +03:00
|
|
|
#endif // CONFIG_ANS
|
|
|
|
#endif // CONFIG_EXT_TILE
|
2015-08-06 05:00:31 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
static void error_handler(void *data) {
|
2016-08-31 00:01:10 +03:00
|
|
|
AV1_COMMON *const cm = (AV1_COMMON *)data;
|
|
|
|
aom_internal_error(&cm->error, AOM_CODEC_CORRUPT_FRAME, "Truncated packet");
|
2015-08-06 05:00:31 +03:00
|
|
|
}
|
|
|
|
|
2016-08-31 00:01:10 +03:00
|
|
|
static void read_bitdepth_colorspace_sampling(AV1_COMMON *cm,
|
|
|
|
struct aom_read_bit_buffer *rb) {
|
2015-08-06 05:00:31 +03:00
|
|
|
if (cm->profile >= PROFILE_2) {
|
2016-08-31 00:01:10 +03:00
|
|
|
cm->bit_depth = aom_rb_read_bit(rb) ? AOM_BITS_12 : AOM_BITS_10;
|
|
|
|
#if CONFIG_AOM_HIGHBITDEPTH
|
2015-08-06 05:00:31 +03:00
|
|
|
cm->use_highbitdepth = 1;
|
|
|
|
#endif
|
|
|
|
} else {
|
2016-08-31 00:01:10 +03:00
|
|
|
cm->bit_depth = AOM_BITS_8;
|
|
|
|
#if CONFIG_AOM_HIGHBITDEPTH
|
2015-08-06 05:00:31 +03:00
|
|
|
cm->use_highbitdepth = 0;
|
|
|
|
#endif
|
|
|
|
}
|
2016-08-31 00:01:10 +03:00
|
|
|
cm->color_space = aom_rb_read_literal(rb, 3);
|
|
|
|
if (cm->color_space != AOM_CS_SRGB) {
|
2015-09-16 04:56:51 +03:00
|
|
|
// [16,235] (including xvycc) vs [0,255] range
|
2016-08-31 00:01:10 +03:00
|
|
|
cm->color_range = aom_rb_read_bit(rb);
|
2015-08-06 05:00:31 +03:00
|
|
|
if (cm->profile == PROFILE_1 || cm->profile == PROFILE_3) {
|
2016-08-31 00:01:10 +03:00
|
|
|
cm->subsampling_x = aom_rb_read_bit(rb);
|
|
|
|
cm->subsampling_y = aom_rb_read_bit(rb);
|
2015-08-06 05:00:31 +03:00
|
|
|
if (cm->subsampling_x == 1 && cm->subsampling_y == 1)
|
2016-08-31 00:01:10 +03:00
|
|
|
aom_internal_error(&cm->error, AOM_CODEC_UNSUP_BITSTREAM,
|
2015-08-06 05:00:31 +03:00
|
|
|
"4:2:0 color not supported in profile 1 or 3");
|
2016-08-31 00:01:10 +03:00
|
|
|
if (aom_rb_read_bit(rb))
|
|
|
|
aom_internal_error(&cm->error, AOM_CODEC_UNSUP_BITSTREAM,
|
2015-08-06 05:00:31 +03:00
|
|
|
"Reserved bit set");
|
|
|
|
} else {
|
|
|
|
cm->subsampling_y = cm->subsampling_x = 1;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
if (cm->profile == PROFILE_1 || cm->profile == PROFILE_3) {
|
|
|
|
// Note if colorspace is SRGB then 4:4:4 chroma sampling is assumed.
|
|
|
|
// 4:2:2 or 4:4:0 chroma sampling is not allowed.
|
|
|
|
cm->subsampling_y = cm->subsampling_x = 0;
|
2016-08-31 00:01:10 +03:00
|
|
|
if (aom_rb_read_bit(rb))
|
|
|
|
aom_internal_error(&cm->error, AOM_CODEC_UNSUP_BITSTREAM,
|
2015-08-06 05:00:31 +03:00
|
|
|
"Reserved bit set");
|
|
|
|
} else {
|
2016-08-31 00:01:10 +03:00
|
|
|
aom_internal_error(&cm->error, AOM_CODEC_UNSUP_BITSTREAM,
|
2015-08-06 05:00:31 +03:00
|
|
|
"4:4:4 color not supported in profile 0 or 2");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-08-31 00:01:10 +03:00
|
|
|
static size_t read_uncompressed_header(AV1Decoder *pbi,
|
|
|
|
struct aom_read_bit_buffer *rb) {
|
|
|
|
AV1_COMMON *const cm = &pbi->common;
|
2015-09-08 21:33:17 +03:00
|
|
|
MACROBLOCKD *const xd = &pbi->mb;
|
2015-08-06 05:00:31 +03:00
|
|
|
BufferPool *const pool = cm->buffer_pool;
|
|
|
|
RefCntBuffer *const frame_bufs = pool->frame_bufs;
|
|
|
|
int i, mask, ref_index = 0;
|
|
|
|
size_t sz;
|
2015-11-12 13:12:17 +03:00
|
|
|
#if CONFIG_EXT_REFS
|
|
|
|
cm->last3_frame_type = cm->last2_frame_type;
|
|
|
|
cm->last2_frame_type = cm->last_frame_type;
|
|
|
|
#endif // CONFIG_EXT_REFS
|
2015-08-06 05:00:31 +03:00
|
|
|
cm->last_frame_type = cm->frame_type;
|
|
|
|
cm->last_intra_only = cm->intra_only;
|
|
|
|
|
Merge bi-predictive frames to EXT_REFS
This patch removed the experiment of BIDIR_PRED and merged the feature
into the experiment of EXT_REFS:
(1) Each frame now has up to 6 reference frames, namely
LAST_FRAME, LAST2_FRAME, LAST3_FRAME, GOLDEN_FRAME, (forward) and
BWDREF_FRAME, ALTREF_FRAME (backward);
LAST4_FRAME has been removed;
(2) First pass still keeps the 8 updates:
KF_UPDATE, LF_UPDATE, GF_UPDATE, ARF_UPDATE, OVERLAY_UPDATE, and
BRF_UPDATE, LAST_BIPRED_UPDATE, BI_PRED_UPDATE;
(3) show_existing_frame==1 is supported in the experiment of EXT_REFS;
(4) New encoding modes are added for both single-ref and compound cases,
through the use of the 2 extra forward references (LAST2 & LAST3)
and the 1 extra backward reference (BWDREF).
RD performance wise, using Overall PSNR: Avg/BDRate
Bipred only Prev EXT_REFS Current EXT_REFS with bipred
lowres: -3.474/-3.324 -1.748/-1.586 -4.613/-4.387
derflr: -2.097/-1.353 -1.439/-1.215 -3.120/-2.252
midres: -2.129/-1.901 -1.345/-1.185 -2.898/-2.636
If in vp10/encoder/firstpass.h, change BFG_INTERVAL from 2 to 3, i.e. to
use 2 bi-predictive frames than 1, a further improvement may be
obtained:
Current EXT_REFS with bipred
1 bi-predictive frame 2 bi-predictive frames
lowres: -4.613/-4.387 -4.675/-4.465
derflr: -3.120/-2.252 -3.333/-2.516
midres: -2.898/-2.636 -3.406/-3.095
Change-Id: Ib06fe9ea0a5cfd7418a1d79b978ee9d80bf191cb
2016-06-09 00:27:56 +03:00
|
|
|
#if CONFIG_EXT_REFS
|
2016-02-04 20:47:46 +03:00
|
|
|
// NOTE: By default all coded frames to be used as a reference
|
|
|
|
cm->is_reference_frame = 1;
|
Merge bi-predictive frames to EXT_REFS
This patch removed the experiment of BIDIR_PRED and merged the feature
into the experiment of EXT_REFS:
(1) Each frame now has up to 6 reference frames, namely
LAST_FRAME, LAST2_FRAME, LAST3_FRAME, GOLDEN_FRAME, (forward) and
BWDREF_FRAME, ALTREF_FRAME (backward);
LAST4_FRAME has been removed;
(2) First pass still keeps the 8 updates:
KF_UPDATE, LF_UPDATE, GF_UPDATE, ARF_UPDATE, OVERLAY_UPDATE, and
BRF_UPDATE, LAST_BIPRED_UPDATE, BI_PRED_UPDATE;
(3) show_existing_frame==1 is supported in the experiment of EXT_REFS;
(4) New encoding modes are added for both single-ref and compound cases,
through the use of the 2 extra forward references (LAST2 & LAST3)
and the 1 extra backward reference (BWDREF).
RD performance wise, using Overall PSNR: Avg/BDRate
Bipred only Prev EXT_REFS Current EXT_REFS with bipred
lowres: -3.474/-3.324 -1.748/-1.586 -4.613/-4.387
derflr: -2.097/-1.353 -1.439/-1.215 -3.120/-2.252
midres: -2.129/-1.901 -1.345/-1.185 -2.898/-2.636
If in vp10/encoder/firstpass.h, change BFG_INTERVAL from 2 to 3, i.e. to
use 2 bi-predictive frames than 1, a further improvement may be
obtained:
Current EXT_REFS with bipred
1 bi-predictive frame 2 bi-predictive frames
lowres: -4.613/-4.387 -4.675/-4.465
derflr: -3.120/-2.252 -3.333/-2.516
midres: -2.898/-2.636 -3.406/-3.095
Change-Id: Ib06fe9ea0a5cfd7418a1d79b978ee9d80bf191cb
2016-06-09 00:27:56 +03:00
|
|
|
#endif // CONFIG_EXT_REFS
|
2016-02-04 20:47:46 +03:00
|
|
|
|
2016-08-31 00:01:10 +03:00
|
|
|
if (aom_rb_read_literal(rb, 2) != AOM_FRAME_MARKER)
|
|
|
|
aom_internal_error(&cm->error, AOM_CODEC_UNSUP_BITSTREAM,
|
2016-08-12 04:53:26 +03:00
|
|
|
"Invalid frame marker");
|
2015-08-06 05:00:31 +03:00
|
|
|
|
2016-08-31 00:01:10 +03:00
|
|
|
cm->profile = av1_read_profile(rb);
|
|
|
|
#if CONFIG_AOM_HIGHBITDEPTH
|
2015-08-06 05:00:31 +03:00
|
|
|
if (cm->profile >= MAX_PROFILES)
|
2016-08-31 00:01:10 +03:00
|
|
|
aom_internal_error(&cm->error, AOM_CODEC_UNSUP_BITSTREAM,
|
2015-08-06 05:00:31 +03:00
|
|
|
"Unsupported bitstream profile");
|
|
|
|
#else
|
|
|
|
if (cm->profile >= PROFILE_2)
|
2016-08-31 00:01:10 +03:00
|
|
|
aom_internal_error(&cm->error, AOM_CODEC_UNSUP_BITSTREAM,
|
2015-08-06 05:00:31 +03:00
|
|
|
"Unsupported bitstream profile");
|
|
|
|
#endif
|
|
|
|
|
2016-08-31 00:01:10 +03:00
|
|
|
cm->show_existing_frame = aom_rb_read_bit(rb);
|
2016-02-04 20:47:46 +03:00
|
|
|
|
2015-08-06 05:00:31 +03:00
|
|
|
if (cm->show_existing_frame) {
|
|
|
|
// Show an existing frame directly.
|
2016-08-31 00:01:10 +03:00
|
|
|
const int frame_to_show = cm->ref_frame_map[aom_rb_read_literal(rb, 3)];
|
2016-02-04 20:47:46 +03:00
|
|
|
|
2015-08-06 05:00:31 +03:00
|
|
|
lock_buffer_pool(pool);
|
|
|
|
if (frame_to_show < 0 || frame_bufs[frame_to_show].ref_count < 1) {
|
|
|
|
unlock_buffer_pool(pool);
|
2016-08-31 00:01:10 +03:00
|
|
|
aom_internal_error(&cm->error, AOM_CODEC_UNSUP_BITSTREAM,
|
2015-08-06 05:00:31 +03:00
|
|
|
"Buffer %d does not contain a decoded frame",
|
|
|
|
frame_to_show);
|
|
|
|
}
|
|
|
|
ref_cnt_fb(frame_bufs, &cm->new_fb_idx, frame_to_show);
|
|
|
|
unlock_buffer_pool(pool);
|
2016-02-04 20:47:46 +03:00
|
|
|
|
2015-08-06 05:00:31 +03:00
|
|
|
cm->lf.filter_level = 0;
|
|
|
|
cm->show_frame = 1;
|
2016-02-04 20:47:46 +03:00
|
|
|
pbi->refresh_frame_flags = 0;
|
2016-06-30 23:33:55 +03:00
|
|
|
|
2015-09-07 17:14:18 +03:00
|
|
|
if (cm->frame_parallel_decode) {
|
2015-08-06 05:00:31 +03:00
|
|
|
for (i = 0; i < REF_FRAMES; ++i)
|
|
|
|
cm->next_ref_frame_map[i] = cm->ref_frame_map[i];
|
|
|
|
}
|
2016-02-04 20:47:46 +03:00
|
|
|
|
2015-08-06 05:00:31 +03:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2016-08-31 00:01:10 +03:00
|
|
|
cm->frame_type = (FRAME_TYPE)aom_rb_read_bit(rb);
|
|
|
|
cm->show_frame = aom_rb_read_bit(rb);
|
|
|
|
cm->error_resilient_mode = aom_rb_read_bit(rb);
|
2015-08-06 05:00:31 +03:00
|
|
|
|
|
|
|
if (cm->frame_type == KEY_FRAME) {
|
2016-08-31 00:01:10 +03:00
|
|
|
if (!av1_read_sync_code(rb))
|
|
|
|
aom_internal_error(&cm->error, AOM_CODEC_UNSUP_BITSTREAM,
|
2015-08-06 05:00:31 +03:00
|
|
|
"Invalid frame sync code");
|
|
|
|
|
|
|
|
read_bitdepth_colorspace_sampling(cm, rb);
|
|
|
|
pbi->refresh_frame_flags = (1 << REF_FRAMES) - 1;
|
|
|
|
|
Code refactoring on Macros related to ref frame numbers
We have renamed following Macros to avoid name confusion:
REFS_PER_FRAME --> INTER_REFS_PER_FRAME
(= ALTREF_FRAME - LAST_FRAME + 1)
MAX_REF_FRAMES --> TOTAL_REFS_PER_FRAME
(= ALTREF_FRAME - INTRA_FRAME + 1)
INTER_REFS_PER_FRAME specifies the maximum number of reference frames
that each Inter frame may use.
TOTAL_REFS_PER_FRAME is equal to INTER_REFS_PER_FRAME + 1, which
counts the INTRA_FRAME.
Further, at the encoder side, since REF_FRAMES specifies the maximum
number of the reference frames that the encoder may store, REF_FRAMES
is usually larger than INTER_REFS_PER_FRAME. For example, in the
ext-refs experiment, REF_FRAMES == 8, which allows the encoder to
store maximum 8 reference frames in the buffer, but
INTER_REFS_PER_FRAME equals to 6, which allows each Inter frame may
use up to 6 frames out of the 8 buffered frames as its references.
Hence, in order to explore the possibility to store more reference
frames in future patches, we modified a couple of array sizes to
accomodate the case that the number of buffered reference frames is
not always equal to the number of the references that are being used
by each Inter frame.
Change-Id: I19e42ef608946cc76ebfd3e965a05f4b9b93a0b3
2016-08-04 00:46:43 +03:00
|
|
|
for (i = 0; i < INTER_REFS_PER_FRAME; ++i) {
|
2015-08-06 05:00:31 +03:00
|
|
|
cm->frame_refs[i].idx = INVALID_IDX;
|
|
|
|
cm->frame_refs[i].buf = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
setup_frame_size(cm, rb);
|
|
|
|
if (pbi->need_resync) {
|
|
|
|
memset(&cm->ref_frame_map, -1, sizeof(cm->ref_frame_map));
|
|
|
|
pbi->need_resync = 0;
|
|
|
|
}
|
2015-12-08 05:18:57 +03:00
|
|
|
if (frame_is_intra_only(cm))
|
2016-08-31 00:01:10 +03:00
|
|
|
cm->allow_screen_content_tools = aom_rb_read_bit(rb);
|
2015-08-06 05:00:31 +03:00
|
|
|
} else {
|
2016-08-31 00:01:10 +03:00
|
|
|
cm->intra_only = cm->show_frame ? 0 : aom_rb_read_bit(rb);
|
2015-08-06 05:00:31 +03:00
|
|
|
|
2015-09-08 21:14:28 +03:00
|
|
|
if (cm->error_resilient_mode) {
|
2016-08-12 04:53:26 +03:00
|
|
|
cm->reset_frame_context = RESET_FRAME_CONTEXT_ALL;
|
2015-09-08 21:14:28 +03:00
|
|
|
} else {
|
|
|
|
if (cm->intra_only) {
|
2016-08-31 00:01:10 +03:00
|
|
|
cm->reset_frame_context = aom_rb_read_bit(rb)
|
2016-08-12 04:53:26 +03:00
|
|
|
? RESET_FRAME_CONTEXT_ALL
|
2015-09-08 21:14:28 +03:00
|
|
|
: RESET_FRAME_CONTEXT_CURRENT;
|
2016-08-12 04:53:26 +03:00
|
|
|
} else {
|
2016-08-31 00:01:10 +03:00
|
|
|
cm->reset_frame_context = aom_rb_read_bit(rb)
|
2016-08-12 04:53:26 +03:00
|
|
|
? RESET_FRAME_CONTEXT_CURRENT
|
|
|
|
: RESET_FRAME_CONTEXT_NONE;
|
|
|
|
if (cm->reset_frame_context == RESET_FRAME_CONTEXT_CURRENT)
|
2016-08-31 00:01:10 +03:00
|
|
|
cm->reset_frame_context = aom_rb_read_bit(rb)
|
2016-08-12 04:53:26 +03:00
|
|
|
? RESET_FRAME_CONTEXT_ALL
|
|
|
|
: RESET_FRAME_CONTEXT_CURRENT;
|
2015-09-08 21:14:28 +03:00
|
|
|
}
|
|
|
|
}
|
2015-08-06 05:00:31 +03:00
|
|
|
|
|
|
|
if (cm->intra_only) {
|
2016-08-31 00:01:10 +03:00
|
|
|
if (!av1_read_sync_code(rb))
|
|
|
|
aom_internal_error(&cm->error, AOM_CODEC_UNSUP_BITSTREAM,
|
2015-08-06 05:00:31 +03:00
|
|
|
"Invalid frame sync code");
|
2015-11-17 03:58:15 +03:00
|
|
|
|
2015-10-19 19:18:57 +03:00
|
|
|
read_bitdepth_colorspace_sampling(cm, rb);
|
2015-08-06 05:00:31 +03:00
|
|
|
|
2016-08-31 00:01:10 +03:00
|
|
|
pbi->refresh_frame_flags = aom_rb_read_literal(rb, REF_FRAMES);
|
2015-08-06 05:00:31 +03:00
|
|
|
setup_frame_size(cm, rb);
|
|
|
|
if (pbi->need_resync) {
|
|
|
|
memset(&cm->ref_frame_map, -1, sizeof(cm->ref_frame_map));
|
|
|
|
pbi->need_resync = 0;
|
|
|
|
}
|
2016-08-12 04:53:26 +03:00
|
|
|
} else if (pbi->need_resync != 1) { /* Skip if need resync */
|
2016-08-31 00:01:10 +03:00
|
|
|
pbi->refresh_frame_flags = aom_rb_read_literal(rb, REF_FRAMES);
|
2016-02-04 20:47:46 +03:00
|
|
|
|
Merge bi-predictive frames to EXT_REFS
This patch removed the experiment of BIDIR_PRED and merged the feature
into the experiment of EXT_REFS:
(1) Each frame now has up to 6 reference frames, namely
LAST_FRAME, LAST2_FRAME, LAST3_FRAME, GOLDEN_FRAME, (forward) and
BWDREF_FRAME, ALTREF_FRAME (backward);
LAST4_FRAME has been removed;
(2) First pass still keeps the 8 updates:
KF_UPDATE, LF_UPDATE, GF_UPDATE, ARF_UPDATE, OVERLAY_UPDATE, and
BRF_UPDATE, LAST_BIPRED_UPDATE, BI_PRED_UPDATE;
(3) show_existing_frame==1 is supported in the experiment of EXT_REFS;
(4) New encoding modes are added for both single-ref and compound cases,
through the use of the 2 extra forward references (LAST2 & LAST3)
and the 1 extra backward reference (BWDREF).
RD performance wise, using Overall PSNR: Avg/BDRate
Bipred only Prev EXT_REFS Current EXT_REFS with bipred
lowres: -3.474/-3.324 -1.748/-1.586 -4.613/-4.387
derflr: -2.097/-1.353 -1.439/-1.215 -3.120/-2.252
midres: -2.129/-1.901 -1.345/-1.185 -2.898/-2.636
If in vp10/encoder/firstpass.h, change BFG_INTERVAL from 2 to 3, i.e. to
use 2 bi-predictive frames than 1, a further improvement may be
obtained:
Current EXT_REFS with bipred
1 bi-predictive frame 2 bi-predictive frames
lowres: -4.613/-4.387 -4.675/-4.465
derflr: -3.120/-2.252 -3.333/-2.516
midres: -2.898/-2.636 -3.406/-3.095
Change-Id: Ib06fe9ea0a5cfd7418a1d79b978ee9d80bf191cb
2016-06-09 00:27:56 +03:00
|
|
|
#if CONFIG_EXT_REFS
|
2016-02-04 20:47:46 +03:00
|
|
|
if (!pbi->refresh_frame_flags) {
|
|
|
|
// NOTE: "pbi->refresh_frame_flags == 0" indicates that the coded frame
|
|
|
|
// will not be used as a reference
|
|
|
|
cm->is_reference_frame = 0;
|
|
|
|
}
|
Merge bi-predictive frames to EXT_REFS
This patch removed the experiment of BIDIR_PRED and merged the feature
into the experiment of EXT_REFS:
(1) Each frame now has up to 6 reference frames, namely
LAST_FRAME, LAST2_FRAME, LAST3_FRAME, GOLDEN_FRAME, (forward) and
BWDREF_FRAME, ALTREF_FRAME (backward);
LAST4_FRAME has been removed;
(2) First pass still keeps the 8 updates:
KF_UPDATE, LF_UPDATE, GF_UPDATE, ARF_UPDATE, OVERLAY_UPDATE, and
BRF_UPDATE, LAST_BIPRED_UPDATE, BI_PRED_UPDATE;
(3) show_existing_frame==1 is supported in the experiment of EXT_REFS;
(4) New encoding modes are added for both single-ref and compound cases,
through the use of the 2 extra forward references (LAST2 & LAST3)
and the 1 extra backward reference (BWDREF).
RD performance wise, using Overall PSNR: Avg/BDRate
Bipred only Prev EXT_REFS Current EXT_REFS with bipred
lowres: -3.474/-3.324 -1.748/-1.586 -4.613/-4.387
derflr: -2.097/-1.353 -1.439/-1.215 -3.120/-2.252
midres: -2.129/-1.901 -1.345/-1.185 -2.898/-2.636
If in vp10/encoder/firstpass.h, change BFG_INTERVAL from 2 to 3, i.e. to
use 2 bi-predictive frames than 1, a further improvement may be
obtained:
Current EXT_REFS with bipred
1 bi-predictive frame 2 bi-predictive frames
lowres: -4.613/-4.387 -4.675/-4.465
derflr: -3.120/-2.252 -3.333/-2.516
midres: -2.898/-2.636 -3.406/-3.095
Change-Id: Ib06fe9ea0a5cfd7418a1d79b978ee9d80bf191cb
2016-06-09 00:27:56 +03:00
|
|
|
#endif // CONFIG_EXT_REFS
|
2016-02-04 20:47:46 +03:00
|
|
|
|
Code refactoring on Macros related to ref frame numbers
We have renamed following Macros to avoid name confusion:
REFS_PER_FRAME --> INTER_REFS_PER_FRAME
(= ALTREF_FRAME - LAST_FRAME + 1)
MAX_REF_FRAMES --> TOTAL_REFS_PER_FRAME
(= ALTREF_FRAME - INTRA_FRAME + 1)
INTER_REFS_PER_FRAME specifies the maximum number of reference frames
that each Inter frame may use.
TOTAL_REFS_PER_FRAME is equal to INTER_REFS_PER_FRAME + 1, which
counts the INTRA_FRAME.
Further, at the encoder side, since REF_FRAMES specifies the maximum
number of the reference frames that the encoder may store, REF_FRAMES
is usually larger than INTER_REFS_PER_FRAME. For example, in the
ext-refs experiment, REF_FRAMES == 8, which allows the encoder to
store maximum 8 reference frames in the buffer, but
INTER_REFS_PER_FRAME equals to 6, which allows each Inter frame may
use up to 6 frames out of the 8 buffered frames as its references.
Hence, in order to explore the possibility to store more reference
frames in future patches, we modified a couple of array sizes to
accomodate the case that the number of buffered reference frames is
not always equal to the number of the references that are being used
by each Inter frame.
Change-Id: I19e42ef608946cc76ebfd3e965a05f4b9b93a0b3
2016-08-04 00:46:43 +03:00
|
|
|
for (i = 0; i < INTER_REFS_PER_FRAME; ++i) {
|
2016-08-31 00:01:10 +03:00
|
|
|
const int ref = aom_rb_read_literal(rb, REF_FRAMES_LOG2);
|
2015-08-06 05:00:31 +03:00
|
|
|
const int idx = cm->ref_frame_map[ref];
|
|
|
|
RefBuffer *const ref_frame = &cm->frame_refs[i];
|
|
|
|
ref_frame->idx = idx;
|
|
|
|
ref_frame->buf = &frame_bufs[idx].buf;
|
2016-08-31 00:01:10 +03:00
|
|
|
cm->ref_frame_sign_bias[LAST_FRAME + i] = aom_rb_read_bit(rb);
|
2015-08-06 05:00:31 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
setup_frame_size_with_refs(cm, rb);
|
|
|
|
|
2016-08-31 00:01:10 +03:00
|
|
|
cm->allow_high_precision_mv = aom_rb_read_bit(rb);
|
2015-08-06 05:00:31 +03:00
|
|
|
cm->interp_filter = read_interp_filter(rb);
|
|
|
|
|
Code refactoring on Macros related to ref frame numbers
We have renamed following Macros to avoid name confusion:
REFS_PER_FRAME --> INTER_REFS_PER_FRAME
(= ALTREF_FRAME - LAST_FRAME + 1)
MAX_REF_FRAMES --> TOTAL_REFS_PER_FRAME
(= ALTREF_FRAME - INTRA_FRAME + 1)
INTER_REFS_PER_FRAME specifies the maximum number of reference frames
that each Inter frame may use.
TOTAL_REFS_PER_FRAME is equal to INTER_REFS_PER_FRAME + 1, which
counts the INTRA_FRAME.
Further, at the encoder side, since REF_FRAMES specifies the maximum
number of the reference frames that the encoder may store, REF_FRAMES
is usually larger than INTER_REFS_PER_FRAME. For example, in the
ext-refs experiment, REF_FRAMES == 8, which allows the encoder to
store maximum 8 reference frames in the buffer, but
INTER_REFS_PER_FRAME equals to 6, which allows each Inter frame may
use up to 6 frames out of the 8 buffered frames as its references.
Hence, in order to explore the possibility to store more reference
frames in future patches, we modified a couple of array sizes to
accomodate the case that the number of buffered reference frames is
not always equal to the number of the references that are being used
by each Inter frame.
Change-Id: I19e42ef608946cc76ebfd3e965a05f4b9b93a0b3
2016-08-04 00:46:43 +03:00
|
|
|
for (i = 0; i < INTER_REFS_PER_FRAME; ++i) {
|
2015-08-06 05:00:31 +03:00
|
|
|
RefBuffer *const ref_buf = &cm->frame_refs[i];
|
2016-08-31 00:01:10 +03:00
|
|
|
#if CONFIG_AOM_HIGHBITDEPTH
|
|
|
|
av1_setup_scale_factors_for_frame(
|
2016-08-12 04:53:26 +03:00
|
|
|
&ref_buf->sf, ref_buf->buf->y_crop_width,
|
|
|
|
ref_buf->buf->y_crop_height, cm->width, cm->height,
|
|
|
|
cm->use_highbitdepth);
|
2015-08-06 05:00:31 +03:00
|
|
|
#else
|
2016-08-31 00:01:10 +03:00
|
|
|
av1_setup_scale_factors_for_frame(
|
2016-08-12 04:53:26 +03:00
|
|
|
&ref_buf->sf, ref_buf->buf->y_crop_width,
|
|
|
|
ref_buf->buf->y_crop_height, cm->width, cm->height);
|
2015-08-06 05:00:31 +03:00
|
|
|
#endif
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2016-08-31 00:01:10 +03:00
|
|
|
#if CONFIG_AOM_HIGHBITDEPTH
|
2015-08-06 05:00:31 +03:00
|
|
|
get_frame_new_buffer(cm)->bit_depth = cm->bit_depth;
|
|
|
|
#endif
|
|
|
|
get_frame_new_buffer(cm)->color_space = cm->color_space;
|
2015-09-16 04:56:51 +03:00
|
|
|
get_frame_new_buffer(cm)->color_range = cm->color_range;
|
2016-08-12 04:53:26 +03:00
|
|
|
get_frame_new_buffer(cm)->render_width = cm->render_width;
|
2015-09-29 01:55:46 +03:00
|
|
|
get_frame_new_buffer(cm)->render_height = cm->render_height;
|
2015-08-06 05:00:31 +03:00
|
|
|
|
|
|
|
if (pbi->need_resync) {
|
2016-08-31 00:01:10 +03:00
|
|
|
aom_internal_error(&cm->error, AOM_CODEC_CORRUPT_FRAME,
|
2015-08-06 05:00:31 +03:00
|
|
|
"Keyframe / intra-only frame required to reset decoder"
|
|
|
|
" state");
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!cm->error_resilient_mode) {
|
2016-08-31 00:01:10 +03:00
|
|
|
cm->refresh_frame_context = aom_rb_read_bit(rb)
|
2016-08-12 04:53:26 +03:00
|
|
|
? REFRESH_FRAME_CONTEXT_FORWARD
|
|
|
|
: REFRESH_FRAME_CONTEXT_BACKWARD;
|
2015-08-06 05:00:31 +03:00
|
|
|
} else {
|
2016-05-10 00:20:50 +03:00
|
|
|
cm->refresh_frame_context = REFRESH_FRAME_CONTEXT_FORWARD;
|
2015-08-06 05:00:31 +03:00
|
|
|
}
|
|
|
|
|
2016-08-31 00:01:10 +03:00
|
|
|
// This flag will be overridden by the call to av1_setup_past_independence
|
2015-08-06 05:00:31 +03:00
|
|
|
// below, forcing the use of context 0 for those frame types.
|
2016-08-31 00:01:10 +03:00
|
|
|
cm->frame_context_idx = aom_rb_read_literal(rb, FRAME_CONTEXTS_LOG2);
|
2015-08-06 05:00:31 +03:00
|
|
|
|
|
|
|
// Generate next_ref_frame_map.
|
|
|
|
lock_buffer_pool(pool);
|
|
|
|
for (mask = pbi->refresh_frame_flags; mask; mask >>= 1) {
|
|
|
|
if (mask & 1) {
|
|
|
|
cm->next_ref_frame_map[ref_index] = cm->new_fb_idx;
|
|
|
|
++frame_bufs[cm->new_fb_idx].ref_count;
|
|
|
|
} else {
|
|
|
|
cm->next_ref_frame_map[ref_index] = cm->ref_frame_map[ref_index];
|
|
|
|
}
|
|
|
|
// Current thread holds the reference frame.
|
|
|
|
if (cm->ref_frame_map[ref_index] >= 0)
|
|
|
|
++frame_bufs[cm->ref_frame_map[ref_index]].ref_count;
|
|
|
|
++ref_index;
|
|
|
|
}
|
|
|
|
|
|
|
|
for (; ref_index < REF_FRAMES; ++ref_index) {
|
|
|
|
cm->next_ref_frame_map[ref_index] = cm->ref_frame_map[ref_index];
|
2015-11-12 13:12:17 +03:00
|
|
|
|
2015-08-06 05:00:31 +03:00
|
|
|
// Current thread holds the reference frame.
|
|
|
|
if (cm->ref_frame_map[ref_index] >= 0)
|
|
|
|
++frame_bufs[cm->ref_frame_map[ref_index]].ref_count;
|
|
|
|
}
|
|
|
|
unlock_buffer_pool(pool);
|
|
|
|
pbi->hold_ref_buf = 1;
|
|
|
|
|
|
|
|
if (frame_is_intra_only(cm) || cm->error_resilient_mode)
|
2016-08-31 00:01:10 +03:00
|
|
|
av1_setup_past_independence(cm);
|
2015-08-06 05:00:31 +03:00
|
|
|
|
Make superblock size variable at the frame level.
The uncompressed frame header contains a bit to signal whether the
frame is encoded using 64x64 or 128x128 superblocks. This can vary
between any 2 frames.
vpxenc gained the --sb-size={64,128,dynamic} option, which allows the
configuration of the superblock size used (default is dynamic). 64/128
will force the encoder to always use the specified superblock size.
Dynamic would enable the encoder to choose the sb size for each
frame, but this is not implemented yet (dynamic does the same as 128
for now).
Constraints on tile sizes depend on the superblock size, the following
is a summary of the current bitstream syntax and semantics:
If both --enable-ext-tile is OFF and --enable-ext-partition is OFF:
The tile coding in this case is the same as VP9. In particular,
tiles have a minimum width of 256 pixels and a maximum width of
4096 pixels. The tile width must be multiples of 64 pixels
(except for the rightmost tile column). There can be a maximum
of 64 tile columns and 4 tile rows.
If --enable-ext-tile is OFF and --enable-ext-partition is ON:
Same constraints as above, except that tile width must be
multiples of 128 pixels (except for the rightmost tile column).
There is no change in the bitstream syntax used for coding the tile
configuration if --enable-ext-tile is OFF.
If --enable-ext-tile is ON and --enable-ext-partition is ON:
This is the new large scale tile coding configuration. The
minimum/maximum tile width and height are 64/4096 pixels. Tile
width and height must be multiples of 64 pixels. The uncompressed
header contains two 6 bit fields that hold the tile width/heigh
in units of 64 pixels. The maximum number of tile rows/columns
is only limited by the maximum frame size of 65536x65536 pixels
that can be coded in the bitstream. This yields a maximum of
1024x1024 tile rows and columns (of 64x64 tiles in a 65536x65536
frame).
If both --enable-ext-tile is ON and --enable-ext-partition is ON:
Same applies as above, except that in the bitstream the 2 fields
containing the tile width/height are in units of the superblock
size, and the superblock size itself is also coded in the bitstream.
If the uncompressed header signals the use of 64x64 superblocks,
then the tile width/height fields are 6 bits wide and are in units
of 64 pixels. If the uncompressed header signals the use of 128x128
superblocks, then the tile width/height fields are 5 bits wide and
are in units of 128 pixels.
The above is a summary of the bitstream. The user interface to vpxenc
(and the equivalent encoder API) behaves a follows:
If --enable-ext-tile is OFF:
No change in the user interface. --tile-columns and --tile-rows
specify the base 2 logarithm of the desired number of tile columns
and tile rows. The actual number of tile rows and tile columns,
and the particular tile width and tile height are computed by the
codec ensuring all of the above constraints are respected.
If --enable-ext-tile is ON, but --enable-ext-partition is OFF:
No change in the user interface. --tile-columns and --tile-rows
specify the WIDTH and HEIGHT of the tiles in unit of 64 pixels.
The valid values are in the range [1, 64] (which corresponds to
[64, 4096] pixels in increments of 64.
If both --enable-ext-tile is ON and --enable-ext-partition is ON:
If --sb-size=64 (default):
The user interface is the same as in the previous point.
--tile-columns and --tile-rows specify tile WIDTH and HEIGHT,
in units of 64 pixels, in the range [1, 64] (which corresponds
to [64, 4096] pixels in increments of 64).
If --sb-size=128 or --sb-size=dynamic:
--tile-columns and --tile-rows specify tile WIDTH and HEIGHT,
in units of 128 pixels in the range [1, 32] (which corresponds
to [128, 4096] pixels in increments of 128).
Change-Id: Idc9beee1ad12ff1634e83671985d14c680f9179a
2016-03-24 16:56:05 +03:00
|
|
|
#if CONFIG_EXT_PARTITION
|
2016-08-31 00:01:10 +03:00
|
|
|
set_sb_size(cm, aom_rb_read_bit(rb) ? BLOCK_128X128 : BLOCK_64X64);
|
Make superblock size variable at the frame level.
The uncompressed frame header contains a bit to signal whether the
frame is encoded using 64x64 or 128x128 superblocks. This can vary
between any 2 frames.
vpxenc gained the --sb-size={64,128,dynamic} option, which allows the
configuration of the superblock size used (default is dynamic). 64/128
will force the encoder to always use the specified superblock size.
Dynamic would enable the encoder to choose the sb size for each
frame, but this is not implemented yet (dynamic does the same as 128
for now).
Constraints on tile sizes depend on the superblock size, the following
is a summary of the current bitstream syntax and semantics:
If both --enable-ext-tile is OFF and --enable-ext-partition is OFF:
The tile coding in this case is the same as VP9. In particular,
tiles have a minimum width of 256 pixels and a maximum width of
4096 pixels. The tile width must be multiples of 64 pixels
(except for the rightmost tile column). There can be a maximum
of 64 tile columns and 4 tile rows.
If --enable-ext-tile is OFF and --enable-ext-partition is ON:
Same constraints as above, except that tile width must be
multiples of 128 pixels (except for the rightmost tile column).
There is no change in the bitstream syntax used for coding the tile
configuration if --enable-ext-tile is OFF.
If --enable-ext-tile is ON and --enable-ext-partition is ON:
This is the new large scale tile coding configuration. The
minimum/maximum tile width and height are 64/4096 pixels. Tile
width and height must be multiples of 64 pixels. The uncompressed
header contains two 6 bit fields that hold the tile width/heigh
in units of 64 pixels. The maximum number of tile rows/columns
is only limited by the maximum frame size of 65536x65536 pixels
that can be coded in the bitstream. This yields a maximum of
1024x1024 tile rows and columns (of 64x64 tiles in a 65536x65536
frame).
If both --enable-ext-tile is ON and --enable-ext-partition is ON:
Same applies as above, except that in the bitstream the 2 fields
containing the tile width/height are in units of the superblock
size, and the superblock size itself is also coded in the bitstream.
If the uncompressed header signals the use of 64x64 superblocks,
then the tile width/height fields are 6 bits wide and are in units
of 64 pixels. If the uncompressed header signals the use of 128x128
superblocks, then the tile width/height fields are 5 bits wide and
are in units of 128 pixels.
The above is a summary of the bitstream. The user interface to vpxenc
(and the equivalent encoder API) behaves a follows:
If --enable-ext-tile is OFF:
No change in the user interface. --tile-columns and --tile-rows
specify the base 2 logarithm of the desired number of tile columns
and tile rows. The actual number of tile rows and tile columns,
and the particular tile width and tile height are computed by the
codec ensuring all of the above constraints are respected.
If --enable-ext-tile is ON, but --enable-ext-partition is OFF:
No change in the user interface. --tile-columns and --tile-rows
specify the WIDTH and HEIGHT of the tiles in unit of 64 pixels.
The valid values are in the range [1, 64] (which corresponds to
[64, 4096] pixels in increments of 64.
If both --enable-ext-tile is ON and --enable-ext-partition is ON:
If --sb-size=64 (default):
The user interface is the same as in the previous point.
--tile-columns and --tile-rows specify tile WIDTH and HEIGHT,
in units of 64 pixels, in the range [1, 64] (which corresponds
to [64, 4096] pixels in increments of 64).
If --sb-size=128 or --sb-size=dynamic:
--tile-columns and --tile-rows specify tile WIDTH and HEIGHT,
in units of 128 pixels in the range [1, 32] (which corresponds
to [128, 4096] pixels in increments of 128).
Change-Id: Idc9beee1ad12ff1634e83671985d14c680f9179a
2016-03-24 16:56:05 +03:00
|
|
|
#else
|
|
|
|
set_sb_size(cm, BLOCK_64X64);
|
|
|
|
#endif // CONFIG_EXT_PARTITION
|
|
|
|
|
2016-01-20 00:01:01 +03:00
|
|
|
setup_loopfilter(cm, rb);
|
2016-08-11 19:39:47 +03:00
|
|
|
#if CONFIG_CLPF
|
|
|
|
setup_clpf(cm, rb);
|
|
|
|
#endif
|
2016-08-15 20:27:19 +03:00
|
|
|
#if CONFIG_DERING
|
|
|
|
setup_dering(cm, rb);
|
|
|
|
#endif
|
2016-02-09 23:24:33 +03:00
|
|
|
#if CONFIG_LOOP_RESTORATION
|
2016-09-09 01:15:17 +03:00
|
|
|
decode_restoration_mode(cm, rb);
|
2016-02-09 23:24:33 +03:00
|
|
|
#endif // CONFIG_LOOP_RESTORATION
|
2015-12-15 05:49:59 +03:00
|
|
|
setup_quantization(cm, rb);
|
2016-08-31 00:01:10 +03:00
|
|
|
#if CONFIG_AOM_HIGHBITDEPTH
|
2015-12-16 22:43:11 +03:00
|
|
|
xd->bd = (int)cm->bit_depth;
|
|
|
|
#endif
|
|
|
|
|
2016-01-08 01:29:26 +03:00
|
|
|
#if CONFIG_ENTROPY
|
2016-08-31 00:01:10 +03:00
|
|
|
av1_default_coef_probs(cm);
|
2016-01-08 01:29:26 +03:00
|
|
|
if (cm->frame_type == KEY_FRAME || cm->error_resilient_mode ||
|
|
|
|
cm->reset_frame_context == RESET_FRAME_CONTEXT_ALL) {
|
2016-08-12 04:53:26 +03:00
|
|
|
for (i = 0; i < FRAME_CONTEXTS; ++i) cm->frame_contexts[i] = *cm->fc;
|
2016-01-08 01:29:26 +03:00
|
|
|
} else if (cm->reset_frame_context == RESET_FRAME_CONTEXT_CURRENT) {
|
|
|
|
cm->frame_contexts[cm->frame_context_idx] = *cm->fc;
|
|
|
|
}
|
|
|
|
#endif // CONFIG_ENTROPY
|
|
|
|
|
2015-09-03 23:08:29 +03:00
|
|
|
setup_segmentation(cm, rb);
|
2015-12-15 05:49:59 +03:00
|
|
|
|
|
|
|
{
|
|
|
|
int i;
|
|
|
|
for (i = 0; i < MAX_SEGMENTS; ++i) {
|
2016-08-12 04:53:26 +03:00
|
|
|
const int qindex = cm->seg.enabled
|
2016-08-31 00:01:10 +03:00
|
|
|
? av1_get_qindex(&cm->seg, i, cm->base_qindex)
|
2016-08-12 04:53:26 +03:00
|
|
|
: cm->base_qindex;
|
|
|
|
xd->lossless[i] = qindex == 0 && cm->y_dc_delta_q == 0 &&
|
|
|
|
cm->uv_dc_delta_q == 0 && cm->uv_ac_delta_q == 0;
|
2015-12-15 05:49:59 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-08-06 05:00:31 +03:00
|
|
|
setup_segmentation_dequant(cm);
|
2016-08-12 04:53:26 +03:00
|
|
|
cm->tx_mode =
|
|
|
|
(!cm->seg.enabled && xd->lossless[0]) ? ONLY_4X4 : read_tx_mode(rb);
|
2015-09-29 01:55:46 +03:00
|
|
|
cm->reference_mode = read_frame_reference_mode(cm, rb);
|
2015-08-06 05:00:31 +03:00
|
|
|
|
Make superblock size variable at the frame level.
The uncompressed frame header contains a bit to signal whether the
frame is encoded using 64x64 or 128x128 superblocks. This can vary
between any 2 frames.
vpxenc gained the --sb-size={64,128,dynamic} option, which allows the
configuration of the superblock size used (default is dynamic). 64/128
will force the encoder to always use the specified superblock size.
Dynamic would enable the encoder to choose the sb size for each
frame, but this is not implemented yet (dynamic does the same as 128
for now).
Constraints on tile sizes depend on the superblock size, the following
is a summary of the current bitstream syntax and semantics:
If both --enable-ext-tile is OFF and --enable-ext-partition is OFF:
The tile coding in this case is the same as VP9. In particular,
tiles have a minimum width of 256 pixels and a maximum width of
4096 pixels. The tile width must be multiples of 64 pixels
(except for the rightmost tile column). There can be a maximum
of 64 tile columns and 4 tile rows.
If --enable-ext-tile is OFF and --enable-ext-partition is ON:
Same constraints as above, except that tile width must be
multiples of 128 pixels (except for the rightmost tile column).
There is no change in the bitstream syntax used for coding the tile
configuration if --enable-ext-tile is OFF.
If --enable-ext-tile is ON and --enable-ext-partition is ON:
This is the new large scale tile coding configuration. The
minimum/maximum tile width and height are 64/4096 pixels. Tile
width and height must be multiples of 64 pixels. The uncompressed
header contains two 6 bit fields that hold the tile width/heigh
in units of 64 pixels. The maximum number of tile rows/columns
is only limited by the maximum frame size of 65536x65536 pixels
that can be coded in the bitstream. This yields a maximum of
1024x1024 tile rows and columns (of 64x64 tiles in a 65536x65536
frame).
If both --enable-ext-tile is ON and --enable-ext-partition is ON:
Same applies as above, except that in the bitstream the 2 fields
containing the tile width/height are in units of the superblock
size, and the superblock size itself is also coded in the bitstream.
If the uncompressed header signals the use of 64x64 superblocks,
then the tile width/height fields are 6 bits wide and are in units
of 64 pixels. If the uncompressed header signals the use of 128x128
superblocks, then the tile width/height fields are 5 bits wide and
are in units of 128 pixels.
The above is a summary of the bitstream. The user interface to vpxenc
(and the equivalent encoder API) behaves a follows:
If --enable-ext-tile is OFF:
No change in the user interface. --tile-columns and --tile-rows
specify the base 2 logarithm of the desired number of tile columns
and tile rows. The actual number of tile rows and tile columns,
and the particular tile width and tile height are computed by the
codec ensuring all of the above constraints are respected.
If --enable-ext-tile is ON, but --enable-ext-partition is OFF:
No change in the user interface. --tile-columns and --tile-rows
specify the WIDTH and HEIGHT of the tiles in unit of 64 pixels.
The valid values are in the range [1, 64] (which corresponds to
[64, 4096] pixels in increments of 64.
If both --enable-ext-tile is ON and --enable-ext-partition is ON:
If --sb-size=64 (default):
The user interface is the same as in the previous point.
--tile-columns and --tile-rows specify tile WIDTH and HEIGHT,
in units of 64 pixels, in the range [1, 64] (which corresponds
to [64, 4096] pixels in increments of 64).
If --sb-size=128 or --sb-size=dynamic:
--tile-columns and --tile-rows specify tile WIDTH and HEIGHT,
in units of 128 pixels in the range [1, 32] (which corresponds
to [128, 4096] pixels in increments of 128).
Change-Id: Idc9beee1ad12ff1634e83671985d14c680f9179a
2016-03-24 16:56:05 +03:00
|
|
|
read_tile_info(pbi, rb);
|
2016-08-31 00:01:10 +03:00
|
|
|
sz = aom_rb_read_literal(rb, 16);
|
2015-08-06 05:00:31 +03:00
|
|
|
|
|
|
|
if (sz == 0)
|
2016-08-31 00:01:10 +03:00
|
|
|
aom_internal_error(&cm->error, AOM_CODEC_CORRUPT_FRAME,
|
2015-08-06 05:00:31 +03:00
|
|
|
"Invalid header size");
|
|
|
|
|
|
|
|
return sz;
|
|
|
|
}
|
|
|
|
|
2015-09-03 12:58:12 +03:00
|
|
|
#if CONFIG_EXT_TX
|
2016-08-31 00:01:10 +03:00
|
|
|
static void read_ext_tx_probs(FRAME_CONTEXT *fc, aom_reader *r) {
|
2015-09-29 04:38:00 +03:00
|
|
|
int i, j, k;
|
2015-10-12 22:30:55 +03:00
|
|
|
int s;
|
|
|
|
for (s = 1; s < EXT_TX_SETS_INTER; ++s) {
|
2016-08-31 00:01:10 +03:00
|
|
|
if (aom_read(r, GROUP_DIFF_UPDATE_PROB)) {
|
2015-10-12 22:30:55 +03:00
|
|
|
for (i = TX_4X4; i < EXT_TX_SIZES; ++i) {
|
2015-11-18 22:56:50 +03:00
|
|
|
if (!use_inter_ext_tx_for_txsize[s][i]) continue;
|
2015-10-12 22:30:55 +03:00
|
|
|
for (j = 0; j < num_ext_tx_set_inter[s] - 1; ++j)
|
2016-08-31 00:01:10 +03:00
|
|
|
av1_diff_update_prob(r, &fc->inter_ext_tx_prob[s][i][j]);
|
2015-10-12 22:30:55 +03:00
|
|
|
}
|
|
|
|
}
|
2015-09-29 04:38:00 +03:00
|
|
|
}
|
|
|
|
|
2015-10-12 22:30:55 +03:00
|
|
|
for (s = 1; s < EXT_TX_SETS_INTRA; ++s) {
|
2016-08-31 00:01:10 +03:00
|
|
|
if (aom_read(r, GROUP_DIFF_UPDATE_PROB)) {
|
2015-10-12 22:30:55 +03:00
|
|
|
for (i = TX_4X4; i < EXT_TX_SIZES; ++i) {
|
2015-11-18 22:56:50 +03:00
|
|
|
if (!use_intra_ext_tx_for_txsize[s][i]) continue;
|
2015-10-12 22:30:55 +03:00
|
|
|
for (j = 0; j < INTRA_MODES; ++j)
|
|
|
|
for (k = 0; k < num_ext_tx_set_intra[s] - 1; ++k)
|
2016-08-31 00:01:10 +03:00
|
|
|
av1_diff_update_prob(r, &fc->intra_ext_tx_prob[s][i][j][k]);
|
2015-10-12 22:30:55 +03:00
|
|
|
}
|
|
|
|
}
|
2015-09-03 12:58:12 +03:00
|
|
|
}
|
|
|
|
}
|
2016-01-23 01:52:38 +03:00
|
|
|
|
2016-01-11 21:27:35 +03:00
|
|
|
#else
|
2016-01-23 01:52:38 +03:00
|
|
|
|
2016-08-31 00:01:10 +03:00
|
|
|
static void read_ext_tx_probs(FRAME_CONTEXT *fc, aom_reader *r) {
|
2016-01-06 22:24:57 +03:00
|
|
|
int i, j, k;
|
2016-08-31 00:01:10 +03:00
|
|
|
if (aom_read(r, GROUP_DIFF_UPDATE_PROB)) {
|
2016-01-06 22:24:57 +03:00
|
|
|
for (i = TX_4X4; i < EXT_TX_SIZES; ++i) {
|
|
|
|
for (j = 0; j < TX_TYPES; ++j)
|
|
|
|
for (k = 0; k < TX_TYPES - 1; ++k)
|
2016-08-31 00:01:10 +03:00
|
|
|
av1_diff_update_prob(r, &fc->intra_ext_tx_prob[i][j][k]);
|
2016-01-06 22:24:57 +03:00
|
|
|
}
|
|
|
|
}
|
2016-08-31 00:01:10 +03:00
|
|
|
if (aom_read(r, GROUP_DIFF_UPDATE_PROB)) {
|
2016-01-06 22:24:57 +03:00
|
|
|
for (i = TX_4X4; i < EXT_TX_SIZES; ++i) {
|
|
|
|
for (k = 0; k < TX_TYPES - 1; ++k)
|
2016-08-31 00:01:10 +03:00
|
|
|
av1_diff_update_prob(r, &fc->inter_ext_tx_prob[i][k]);
|
2016-01-06 22:24:57 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2015-09-03 12:58:12 +03:00
|
|
|
#endif // CONFIG_EXT_TX
|
|
|
|
|
2015-11-20 03:51:16 +03:00
|
|
|
#if CONFIG_SUPERTX
|
2016-08-31 00:01:10 +03:00
|
|
|
static void read_supertx_probs(FRAME_CONTEXT *fc, aom_reader *r) {
|
2015-11-20 03:51:16 +03:00
|
|
|
int i, j;
|
2016-08-31 00:01:10 +03:00
|
|
|
if (aom_read(r, GROUP_DIFF_UPDATE_PROB)) {
|
2015-11-20 03:51:16 +03:00
|
|
|
for (i = 0; i < PARTITION_SUPERTX_CONTEXTS; ++i) {
|
|
|
|
for (j = 1; j < TX_SIZES; ++j) {
|
2016-08-31 00:01:10 +03:00
|
|
|
av1_diff_update_prob(r, &fc->supertx_prob[i][j]);
|
2015-11-20 03:51:16 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
#endif // CONFIG_SUPERTX
|
|
|
|
|
2016-07-11 21:47:55 +03:00
|
|
|
#if CONFIG_GLOBAL_MOTION
|
|
|
|
static void read_global_motion_params(Global_Motion_Params *params,
|
2016-08-31 00:01:10 +03:00
|
|
|
aom_prob *probs, aom_reader *r) {
|
2016-08-12 04:53:26 +03:00
|
|
|
GLOBAL_MOTION_TYPE gmtype =
|
2016-08-31 00:01:10 +03:00
|
|
|
aom_read_tree(r, av1_global_motion_types_tree, probs);
|
2016-07-11 21:47:55 +03:00
|
|
|
params->gmtype = gmtype;
|
2016-07-21 03:11:39 +03:00
|
|
|
params->motion_params.wmtype = gm_to_trans_type(gmtype);
|
2016-07-11 21:47:55 +03:00
|
|
|
switch (gmtype) {
|
2016-08-12 04:53:26 +03:00
|
|
|
case GLOBAL_ZERO: break;
|
2016-07-21 03:11:39 +03:00
|
|
|
case GLOBAL_AFFINE:
|
2016-08-17 00:57:37 +03:00
|
|
|
params->motion_params.wmmat[2].as_mv.row =
|
2016-09-07 23:24:53 +03:00
|
|
|
(aom_read_primitive_symmetric(r, GM_ABS_ALPHA_BITS) *
|
|
|
|
GM_ALPHA_DECODE_FACTOR);
|
|
|
|
params->motion_params.wmmat[2].as_mv.col =
|
2016-08-31 00:01:10 +03:00
|
|
|
aom_read_primitive_symmetric(r, GM_ABS_ALPHA_BITS) *
|
2016-08-19 01:10:22 +03:00
|
|
|
GM_ALPHA_DECODE_FACTOR +
|
2016-08-16 05:11:19 +03:00
|
|
|
(1 << WARPEDMODEL_PREC_BITS);
|
2016-08-12 04:53:26 +03:00
|
|
|
// fallthrough intended
|
2016-07-11 21:47:55 +03:00
|
|
|
case GLOBAL_ROTZOOM:
|
2016-08-17 00:57:37 +03:00
|
|
|
params->motion_params.wmmat[1].as_mv.row =
|
|
|
|
aom_read_primitive_symmetric(r, GM_ABS_ALPHA_BITS) *
|
|
|
|
GM_ALPHA_DECODE_FACTOR;
|
|
|
|
params->motion_params.wmmat[1].as_mv.col =
|
2016-08-31 00:01:10 +03:00
|
|
|
(aom_read_primitive_symmetric(r, GM_ABS_ALPHA_BITS) *
|
2016-08-12 04:53:26 +03:00
|
|
|
GM_ALPHA_DECODE_FACTOR) +
|
|
|
|
(1 << WARPEDMODEL_PREC_BITS);
|
|
|
|
// fallthrough intended
|
2016-07-21 03:11:39 +03:00
|
|
|
case GLOBAL_TRANSLATION:
|
2016-08-17 00:57:37 +03:00
|
|
|
params->motion_params.wmmat[0].as_mv.row =
|
2016-08-31 00:01:10 +03:00
|
|
|
aom_read_primitive_symmetric(r, GM_ABS_TRANS_BITS) *
|
2016-07-21 03:11:39 +03:00
|
|
|
GM_TRANS_DECODE_FACTOR;
|
2016-08-17 00:57:37 +03:00
|
|
|
params->motion_params.wmmat[0].as_mv.col =
|
2016-08-31 00:01:10 +03:00
|
|
|
aom_read_primitive_symmetric(r, GM_ABS_TRANS_BITS) *
|
2016-07-21 03:11:39 +03:00
|
|
|
GM_TRANS_DECODE_FACTOR;
|
2016-07-11 21:47:55 +03:00
|
|
|
break;
|
2016-08-12 04:53:26 +03:00
|
|
|
default: assert(0);
|
2016-07-11 21:47:55 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-08-31 00:01:10 +03:00
|
|
|
static void read_global_motion(AV1_COMMON *cm, aom_reader *r) {
|
2016-07-11 21:47:55 +03:00
|
|
|
int frame;
|
|
|
|
memset(cm->global_motion, 0, sizeof(cm->global_motion));
|
|
|
|
for (frame = LAST_FRAME; frame <= ALTREF_FRAME; ++frame) {
|
2016-08-12 04:53:26 +03:00
|
|
|
read_global_motion_params(&cm->global_motion[frame],
|
|
|
|
cm->fc->global_motion_types_prob, r);
|
2016-08-17 00:57:37 +03:00
|
|
|
/*
|
|
|
|
printf("Dec Ref %d [%d]: %d %d %d %d\n",
|
|
|
|
frame, cm->current_video_frame,
|
|
|
|
cm->global_motion[frame].motion_params.wmmat[0].as_mv.row,
|
|
|
|
cm->global_motion[frame].motion_params.wmmat[0].as_mv.col,
|
|
|
|
cm->global_motion[frame].motion_params.wmmat[1].as_mv.row,
|
|
|
|
cm->global_motion[frame].motion_params.wmmat[1].as_mv.col);
|
|
|
|
*/
|
2016-07-11 21:47:55 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
#endif // CONFIG_GLOBAL_MOTION
|
|
|
|
|
2016-08-31 00:01:10 +03:00
|
|
|
static int read_compressed_header(AV1Decoder *pbi, const uint8_t *data,
|
2015-08-06 05:00:31 +03:00
|
|
|
size_t partition_size) {
|
2016-08-31 00:01:10 +03:00
|
|
|
AV1_COMMON *const cm = &pbi->common;
|
2015-11-20 03:51:16 +03:00
|
|
|
#if CONFIG_SUPERTX
|
|
|
|
MACROBLOCKD *const xd = &pbi->mb;
|
|
|
|
#endif
|
2015-08-06 05:00:31 +03:00
|
|
|
FRAME_CONTEXT *const fc = cm->fc;
|
2016-08-31 00:01:10 +03:00
|
|
|
aom_reader r;
|
2015-10-13 21:07:47 +03:00
|
|
|
int k, i, j;
|
2015-08-06 05:00:31 +03:00
|
|
|
|
2016-03-22 20:33:34 +03:00
|
|
|
#if !CONFIG_ANS
|
2016-08-31 00:01:10 +03:00
|
|
|
if (aom_reader_init(&r, data, partition_size, pbi->decrypt_cb,
|
2015-08-06 05:00:31 +03:00
|
|
|
pbi->decrypt_state))
|
2016-08-31 00:01:10 +03:00
|
|
|
aom_internal_error(&cm->error, AOM_CODEC_MEM_ERROR,
|
2015-08-06 05:00:31 +03:00
|
|
|
"Failed to allocate bool decoder 0");
|
2016-03-22 20:33:34 +03:00
|
|
|
#else
|
2016-09-01 18:59:46 +03:00
|
|
|
if (ans_read_init(&r, data, (int)partition_size))
|
2016-08-31 00:01:10 +03:00
|
|
|
aom_internal_error(&cm->error, AOM_CODEC_MEM_ERROR,
|
2016-03-22 20:33:34 +03:00
|
|
|
"Failed to allocate compressed header ANS decoder");
|
|
|
|
#endif // !CONFIG_ANS
|
2015-08-06 05:00:31 +03:00
|
|
|
|
2016-09-09 01:15:17 +03:00
|
|
|
#if CONFIG_LOOP_RESTORATION
|
|
|
|
decode_restoration(cm, &r);
|
|
|
|
#endif
|
|
|
|
|
2016-03-08 02:25:50 +03:00
|
|
|
if (cm->tx_mode == TX_MODE_SELECT) {
|
|
|
|
for (i = 0; i < TX_SIZES - 1; ++i)
|
|
|
|
for (j = 0; j < TX_SIZE_CONTEXTS; ++j)
|
|
|
|
for (k = 0; k < i + 1; ++k)
|
2016-08-31 00:01:10 +03:00
|
|
|
av1_diff_update_prob(&r, &fc->tx_size_probs[i][j][k]);
|
2016-03-08 02:25:50 +03:00
|
|
|
}
|
|
|
|
|
2015-08-06 05:00:31 +03:00
|
|
|
read_coef_probs(fc, cm->tx_mode, &r);
|
|
|
|
|
2015-10-14 19:38:17 +03:00
|
|
|
#if CONFIG_VAR_TX
|
|
|
|
for (k = 0; k < TXFM_PARTITION_CONTEXTS; ++k)
|
2016-08-31 00:01:10 +03:00
|
|
|
av1_diff_update_prob(&r, &fc->txfm_partition_prob[k]);
|
2016-08-30 03:29:33 +03:00
|
|
|
#if CONFIG_EXT_TX && CONFIG_RECT_TX
|
|
|
|
if (cm->tx_mode == TX_MODE_SELECT) {
|
|
|
|
for (i = 1; i < TX_SIZES - 1; ++i)
|
|
|
|
av1_diff_update_prob(&r, &fc->rect_tx_prob[i]);
|
|
|
|
}
|
|
|
|
#endif // CONFIG_EXT_TX && CONFIG_RECT_TX
|
2015-10-14 19:38:17 +03:00
|
|
|
#endif
|
|
|
|
|
2015-08-06 05:00:31 +03:00
|
|
|
for (k = 0; k < SKIP_CONTEXTS; ++k)
|
2016-08-31 00:01:10 +03:00
|
|
|
av1_diff_update_prob(&r, &fc->skip_probs[k]);
|
2015-08-06 05:00:31 +03:00
|
|
|
|
2016-08-18 00:20:34 +03:00
|
|
|
if (cm->seg.enabled && cm->seg.update_map) {
|
2015-10-13 21:06:28 +03:00
|
|
|
if (cm->seg.temporal_update) {
|
|
|
|
for (k = 0; k < PREDICTION_PROBS; k++)
|
2016-08-31 00:01:10 +03:00
|
|
|
av1_diff_update_prob(&r, &cm->fc->seg.pred_probs[k]);
|
2015-10-13 21:06:28 +03:00
|
|
|
}
|
|
|
|
for (k = 0; k < MAX_SEGMENTS - 1; k++)
|
2016-08-31 00:01:10 +03:00
|
|
|
av1_diff_update_prob(&r, &cm->fc->seg.tree_probs[k]);
|
2015-10-13 21:06:28 +03:00
|
|
|
}
|
2015-10-13 21:07:47 +03:00
|
|
|
|
|
|
|
for (j = 0; j < INTRA_MODES; j++)
|
|
|
|
for (i = 0; i < INTRA_MODES - 1; ++i)
|
2016-08-31 00:01:10 +03:00
|
|
|
av1_diff_update_prob(&r, &fc->uv_mode_prob[j][i]);
|
2015-10-13 21:07:47 +03:00
|
|
|
|
2016-03-17 19:50:28 +03:00
|
|
|
#if CONFIG_EXT_PARTITION_TYPES
|
2016-08-12 04:53:26 +03:00
|
|
|
for (i = 0; i < PARTITION_TYPES - 1; ++i)
|
2016-08-31 00:01:10 +03:00
|
|
|
av1_diff_update_prob(&r, &fc->partition_prob[0][i]);
|
2016-08-12 04:53:26 +03:00
|
|
|
for (j = 1; j < PARTITION_CONTEXTS; ++j)
|
|
|
|
for (i = 0; i < EXT_PARTITION_TYPES - 1; ++i)
|
2016-08-31 00:01:10 +03:00
|
|
|
av1_diff_update_prob(&r, &fc->partition_prob[j][i]);
|
2016-03-17 19:50:28 +03:00
|
|
|
#else
|
2015-10-13 21:07:47 +03:00
|
|
|
for (j = 0; j < PARTITION_CONTEXTS; ++j)
|
|
|
|
for (i = 0; i < PARTITION_TYPES - 1; ++i)
|
2016-08-31 00:01:10 +03:00
|
|
|
av1_diff_update_prob(&r, &fc->partition_prob[j][i]);
|
2016-03-17 19:50:28 +03:00
|
|
|
#endif // CONFIG_EXT_PARTITION_TYPES
|
2015-10-13 21:06:28 +03:00
|
|
|
|
2016-01-13 03:38:58 +03:00
|
|
|
#if CONFIG_EXT_INTRA
|
|
|
|
for (i = 0; i < INTRA_FILTERS + 1; ++i)
|
|
|
|
for (j = 0; j < INTRA_FILTERS - 1; ++j)
|
2016-08-31 00:01:10 +03:00
|
|
|
av1_diff_update_prob(&r, &fc->intra_filter_probs[i][j]);
|
2016-01-13 03:38:58 +03:00
|
|
|
#endif // CONFIG_EXT_INTRA
|
|
|
|
|
2015-10-13 21:08:24 +03:00
|
|
|
if (frame_is_intra_only(cm)) {
|
2016-08-31 00:01:10 +03:00
|
|
|
av1_copy(cm->kf_y_prob, av1_kf_y_mode_prob);
|
2015-10-13 21:08:24 +03:00
|
|
|
for (k = 0; k < INTRA_MODES; k++)
|
|
|
|
for (j = 0; j < INTRA_MODES; j++)
|
|
|
|
for (i = 0; i < INTRA_MODES - 1; ++i)
|
2016-08-31 00:01:10 +03:00
|
|
|
av1_diff_update_prob(&r, &cm->kf_y_prob[k][j][i]);
|
2015-10-13 21:08:24 +03:00
|
|
|
} else {
|
2016-02-18 22:57:44 +03:00
|
|
|
#if !CONFIG_REF_MV
|
2015-08-06 05:00:31 +03:00
|
|
|
nmv_context *const nmvc = &fc->nmvc;
|
2016-02-18 22:57:44 +03:00
|
|
|
#endif
|
2015-08-06 05:00:31 +03:00
|
|
|
|
|
|
|
read_inter_mode_probs(fc, &r);
|
|
|
|
|
2016-01-20 03:45:45 +03:00
|
|
|
#if CONFIG_EXT_INTER
|
|
|
|
read_inter_compound_mode_probs(fc, &r);
|
2016-02-22 13:55:32 +03:00
|
|
|
if (cm->reference_mode != COMPOUND_REFERENCE) {
|
2016-03-31 03:33:15 +03:00
|
|
|
for (i = 0; i < BLOCK_SIZE_GROUPS; i++) {
|
|
|
|
if (is_interintra_allowed_bsize_group(i)) {
|
2016-08-31 00:01:10 +03:00
|
|
|
av1_diff_update_prob(&r, &fc->interintra_prob[i]);
|
2016-02-22 13:55:32 +03:00
|
|
|
}
|
|
|
|
}
|
2016-03-31 03:33:15 +03:00
|
|
|
for (i = 0; i < BLOCK_SIZE_GROUPS; i++) {
|
|
|
|
for (j = 0; j < INTERINTRA_MODES - 1; j++)
|
2016-08-31 00:01:10 +03:00
|
|
|
av1_diff_update_prob(&r, &fc->interintra_mode_prob[i][j]);
|
2016-03-31 03:33:15 +03:00
|
|
|
}
|
2016-03-01 03:08:07 +03:00
|
|
|
for (i = 0; i < BLOCK_SIZES; i++) {
|
2016-03-31 03:33:15 +03:00
|
|
|
if (is_interintra_allowed_bsize(i) && is_interintra_wedge_used(i)) {
|
2016-08-31 00:01:10 +03:00
|
|
|
av1_diff_update_prob(&r, &fc->wedge_interintra_prob[i]);
|
2016-03-01 03:08:07 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (cm->reference_mode != SINGLE_REFERENCE) {
|
|
|
|
for (i = 0; i < BLOCK_SIZES; i++) {
|
2016-03-31 03:33:15 +03:00
|
|
|
if (is_interinter_wedge_used(i)) {
|
2016-08-31 00:01:10 +03:00
|
|
|
av1_diff_update_prob(&r, &fc->wedge_interinter_prob[i]);
|
2016-03-01 03:08:07 +03:00
|
|
|
}
|
|
|
|
}
|
2016-02-22 13:55:32 +03:00
|
|
|
}
|
2016-01-20 03:45:45 +03:00
|
|
|
#endif // CONFIG_EXT_INTER
|
|
|
|
|
2016-06-09 10:57:09 +03:00
|
|
|
#if CONFIG_OBMC || CONFIG_WARPED_MOTION
|
|
|
|
for (i = BLOCK_8X8; i < BLOCK_SIZES; ++i) {
|
|
|
|
for (j = 0; j < MOTION_VARIATIONS - 1; ++j)
|
2016-08-31 00:01:10 +03:00
|
|
|
av1_diff_update_prob(&r, &fc->motvar_prob[i][j]);
|
2016-06-09 10:57:09 +03:00
|
|
|
}
|
|
|
|
#endif // CONFIG_OBMC || CONFIG_WARPED_MOTION
|
2016-01-28 01:18:53 +03:00
|
|
|
|
2016-08-12 04:53:26 +03:00
|
|
|
if (cm->interp_filter == SWITCHABLE) read_switchable_interp_probs(fc, &r);
|
2015-08-06 05:00:31 +03:00
|
|
|
|
|
|
|
for (i = 0; i < INTRA_INTER_CONTEXTS; i++)
|
2016-08-31 00:01:10 +03:00
|
|
|
av1_diff_update_prob(&r, &fc->intra_inter_prob[i]);
|
2015-08-06 05:00:31 +03:00
|
|
|
|
|
|
|
if (cm->reference_mode != SINGLE_REFERENCE)
|
|
|
|
setup_compound_reference_mode(cm);
|
2016-02-04 20:47:46 +03:00
|
|
|
|
2015-08-06 05:00:31 +03:00
|
|
|
read_frame_reference_mode_probs(cm, &r);
|
|
|
|
|
|
|
|
for (j = 0; j < BLOCK_SIZE_GROUPS; j++)
|
|
|
|
for (i = 0; i < INTRA_MODES - 1; ++i)
|
2016-08-31 00:01:10 +03:00
|
|
|
av1_diff_update_prob(&r, &fc->y_mode_prob[j][i]);
|
2015-08-06 05:00:31 +03:00
|
|
|
|
2016-02-18 22:57:44 +03:00
|
|
|
#if CONFIG_REF_MV
|
|
|
|
for (i = 0; i < NMV_CONTEXTS; ++i)
|
|
|
|
read_mv_probs(&fc->nmvc[i], cm->allow_high_precision_mv, &r);
|
|
|
|
#else
|
2015-08-06 05:00:31 +03:00
|
|
|
read_mv_probs(nmvc, cm->allow_high_precision_mv, &r);
|
2016-02-18 22:57:44 +03:00
|
|
|
#endif
|
2015-09-03 12:58:12 +03:00
|
|
|
read_ext_tx_probs(fc, &r);
|
2015-11-20 03:51:16 +03:00
|
|
|
#if CONFIG_SUPERTX
|
2016-08-12 04:53:26 +03:00
|
|
|
if (!xd->lossless[0]) read_supertx_probs(fc, &r);
|
2015-09-03 12:58:12 +03:00
|
|
|
#endif
|
2016-07-11 21:47:55 +03:00
|
|
|
#if CONFIG_GLOBAL_MOTION
|
|
|
|
read_global_motion(cm, &r);
|
|
|
|
#endif // CONFIG_GLOBAL_MOTION
|
2015-08-06 05:00:31 +03:00
|
|
|
}
|
|
|
|
|
2016-08-31 00:01:10 +03:00
|
|
|
return aom_reader_has_error(&r);
|
2015-08-06 05:00:31 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
#ifdef NDEBUG
|
|
|
|
#define debug_check_frame_counts(cm) (void)0
|
|
|
|
#else // !NDEBUG
|
|
|
|
// Counts should only be incremented when frame_parallel_decoding_mode and
|
|
|
|
// error_resilient_mode are disabled.
|
2016-08-31 00:01:10 +03:00
|
|
|
static void debug_check_frame_counts(const AV1_COMMON *const cm) {
|
2015-08-06 05:00:31 +03:00
|
|
|
FRAME_COUNTS zero_counts;
|
2016-08-31 00:01:10 +03:00
|
|
|
av1_zero(zero_counts);
|
2015-09-15 04:06:28 +03:00
|
|
|
assert(cm->refresh_frame_context != REFRESH_FRAME_CONTEXT_BACKWARD ||
|
|
|
|
cm->error_resilient_mode);
|
2015-08-06 05:00:31 +03:00
|
|
|
assert(!memcmp(cm->counts.y_mode, zero_counts.y_mode,
|
|
|
|
sizeof(cm->counts.y_mode)));
|
|
|
|
assert(!memcmp(cm->counts.uv_mode, zero_counts.uv_mode,
|
|
|
|
sizeof(cm->counts.uv_mode)));
|
|
|
|
assert(!memcmp(cm->counts.partition, zero_counts.partition,
|
|
|
|
sizeof(cm->counts.partition)));
|
2016-08-12 04:53:26 +03:00
|
|
|
assert(!memcmp(cm->counts.coef, zero_counts.coef, sizeof(cm->counts.coef)));
|
2015-08-06 05:00:31 +03:00
|
|
|
assert(!memcmp(cm->counts.eob_branch, zero_counts.eob_branch,
|
|
|
|
sizeof(cm->counts.eob_branch)));
|
|
|
|
assert(!memcmp(cm->counts.switchable_interp, zero_counts.switchable_interp,
|
|
|
|
sizeof(cm->counts.switchable_interp)));
|
|
|
|
assert(!memcmp(cm->counts.inter_mode, zero_counts.inter_mode,
|
|
|
|
sizeof(cm->counts.inter_mode)));
|
2016-01-20 03:45:45 +03:00
|
|
|
#if CONFIG_EXT_INTER
|
|
|
|
assert(!memcmp(cm->counts.inter_compound_mode,
|
|
|
|
zero_counts.inter_compound_mode,
|
|
|
|
sizeof(cm->counts.inter_compound_mode)));
|
2016-02-22 13:55:32 +03:00
|
|
|
assert(!memcmp(cm->counts.interintra, zero_counts.interintra,
|
|
|
|
sizeof(cm->counts.interintra)));
|
2016-03-01 03:08:07 +03:00
|
|
|
assert(!memcmp(cm->counts.wedge_interintra, zero_counts.wedge_interintra,
|
|
|
|
sizeof(cm->counts.wedge_interintra)));
|
|
|
|
assert(!memcmp(cm->counts.wedge_interinter, zero_counts.wedge_interinter,
|
|
|
|
sizeof(cm->counts.wedge_interinter)));
|
2016-01-20 03:45:45 +03:00
|
|
|
#endif // CONFIG_EXT_INTER
|
2016-06-09 10:57:09 +03:00
|
|
|
#if CONFIG_OBMC || CONFIG_WARPED_MOTION
|
|
|
|
assert(!memcmp(cm->counts.motvar, zero_counts.motvar,
|
|
|
|
sizeof(cm->counts.motvar)));
|
|
|
|
#endif // CONFIG_OBMC || CONFIG_WARPED_MOTION
|
2015-08-06 05:00:31 +03:00
|
|
|
assert(!memcmp(cm->counts.intra_inter, zero_counts.intra_inter,
|
|
|
|
sizeof(cm->counts.intra_inter)));
|
|
|
|
assert(!memcmp(cm->counts.comp_inter, zero_counts.comp_inter,
|
|
|
|
sizeof(cm->counts.comp_inter)));
|
|
|
|
assert(!memcmp(cm->counts.single_ref, zero_counts.single_ref,
|
|
|
|
sizeof(cm->counts.single_ref)));
|
|
|
|
assert(!memcmp(cm->counts.comp_ref, zero_counts.comp_ref,
|
|
|
|
sizeof(cm->counts.comp_ref)));
|
Merge bi-predictive frames to EXT_REFS
This patch removed the experiment of BIDIR_PRED and merged the feature
into the experiment of EXT_REFS:
(1) Each frame now has up to 6 reference frames, namely
LAST_FRAME, LAST2_FRAME, LAST3_FRAME, GOLDEN_FRAME, (forward) and
BWDREF_FRAME, ALTREF_FRAME (backward);
LAST4_FRAME has been removed;
(2) First pass still keeps the 8 updates:
KF_UPDATE, LF_UPDATE, GF_UPDATE, ARF_UPDATE, OVERLAY_UPDATE, and
BRF_UPDATE, LAST_BIPRED_UPDATE, BI_PRED_UPDATE;
(3) show_existing_frame==1 is supported in the experiment of EXT_REFS;
(4) New encoding modes are added for both single-ref and compound cases,
through the use of the 2 extra forward references (LAST2 & LAST3)
and the 1 extra backward reference (BWDREF).
RD performance wise, using Overall PSNR: Avg/BDRate
Bipred only Prev EXT_REFS Current EXT_REFS with bipred
lowres: -3.474/-3.324 -1.748/-1.586 -4.613/-4.387
derflr: -2.097/-1.353 -1.439/-1.215 -3.120/-2.252
midres: -2.129/-1.901 -1.345/-1.185 -2.898/-2.636
If in vp10/encoder/firstpass.h, change BFG_INTERVAL from 2 to 3, i.e. to
use 2 bi-predictive frames than 1, a further improvement may be
obtained:
Current EXT_REFS with bipred
1 bi-predictive frame 2 bi-predictive frames
lowres: -4.613/-4.387 -4.675/-4.465
derflr: -3.120/-2.252 -3.333/-2.516
midres: -2.898/-2.636 -3.406/-3.095
Change-Id: Ib06fe9ea0a5cfd7418a1d79b978ee9d80bf191cb
2016-06-09 00:27:56 +03:00
|
|
|
#if CONFIG_EXT_REFS
|
2016-02-04 20:47:46 +03:00
|
|
|
assert(!memcmp(cm->counts.comp_bwdref, zero_counts.comp_bwdref,
|
|
|
|
sizeof(cm->counts.comp_bwdref)));
|
Merge bi-predictive frames to EXT_REFS
This patch removed the experiment of BIDIR_PRED and merged the feature
into the experiment of EXT_REFS:
(1) Each frame now has up to 6 reference frames, namely
LAST_FRAME, LAST2_FRAME, LAST3_FRAME, GOLDEN_FRAME, (forward) and
BWDREF_FRAME, ALTREF_FRAME (backward);
LAST4_FRAME has been removed;
(2) First pass still keeps the 8 updates:
KF_UPDATE, LF_UPDATE, GF_UPDATE, ARF_UPDATE, OVERLAY_UPDATE, and
BRF_UPDATE, LAST_BIPRED_UPDATE, BI_PRED_UPDATE;
(3) show_existing_frame==1 is supported in the experiment of EXT_REFS;
(4) New encoding modes are added for both single-ref and compound cases,
through the use of the 2 extra forward references (LAST2 & LAST3)
and the 1 extra backward reference (BWDREF).
RD performance wise, using Overall PSNR: Avg/BDRate
Bipred only Prev EXT_REFS Current EXT_REFS with bipred
lowres: -3.474/-3.324 -1.748/-1.586 -4.613/-4.387
derflr: -2.097/-1.353 -1.439/-1.215 -3.120/-2.252
midres: -2.129/-1.901 -1.345/-1.185 -2.898/-2.636
If in vp10/encoder/firstpass.h, change BFG_INTERVAL from 2 to 3, i.e. to
use 2 bi-predictive frames than 1, a further improvement may be
obtained:
Current EXT_REFS with bipred
1 bi-predictive frame 2 bi-predictive frames
lowres: -4.613/-4.387 -4.675/-4.465
derflr: -3.120/-2.252 -3.333/-2.516
midres: -2.898/-2.636 -3.406/-3.095
Change-Id: Ib06fe9ea0a5cfd7418a1d79b978ee9d80bf191cb
2016-06-09 00:27:56 +03:00
|
|
|
#endif // CONFIG_EXT_REFS
|
|
|
|
assert(!memcmp(&cm->counts.tx_size, &zero_counts.tx_size,
|
|
|
|
sizeof(cm->counts.tx_size)));
|
2015-08-06 05:00:31 +03:00
|
|
|
assert(!memcmp(cm->counts.skip, zero_counts.skip, sizeof(cm->counts.skip)));
|
2016-02-18 22:57:44 +03:00
|
|
|
#if CONFIG_REF_MV
|
2016-08-12 04:53:26 +03:00
|
|
|
assert(
|
|
|
|
!memcmp(&cm->counts.mv[0], &zero_counts.mv[0], sizeof(cm->counts.mv[0])));
|
|
|
|
assert(
|
|
|
|
!memcmp(&cm->counts.mv[1], &zero_counts.mv[1], sizeof(cm->counts.mv[0])));
|
2016-02-18 22:57:44 +03:00
|
|
|
#else
|
2015-08-06 05:00:31 +03:00
|
|
|
assert(!memcmp(&cm->counts.mv, &zero_counts.mv, sizeof(cm->counts.mv)));
|
2016-02-18 22:57:44 +03:00
|
|
|
#endif
|
2015-10-12 22:30:55 +03:00
|
|
|
assert(!memcmp(cm->counts.inter_ext_tx, zero_counts.inter_ext_tx,
|
|
|
|
sizeof(cm->counts.inter_ext_tx)));
|
|
|
|
assert(!memcmp(cm->counts.intra_ext_tx, zero_counts.intra_ext_tx,
|
|
|
|
sizeof(cm->counts.intra_ext_tx)));
|
2015-08-06 05:00:31 +03:00
|
|
|
}
|
|
|
|
#endif // NDEBUG
|
|
|
|
|
2016-08-31 00:01:10 +03:00
|
|
|
static struct aom_read_bit_buffer *init_read_bit_buffer(
|
|
|
|
AV1Decoder *pbi, struct aom_read_bit_buffer *rb, const uint8_t *data,
|
|
|
|
const uint8_t *data_end, uint8_t clear_data[MAX_AV1_HEADER_SIZE]) {
|
2015-08-06 05:00:31 +03:00
|
|
|
rb->bit_offset = 0;
|
|
|
|
rb->error_handler = error_handler;
|
|
|
|
rb->error_handler_data = &pbi->common;
|
|
|
|
if (pbi->decrypt_cb) {
|
2016-08-31 00:01:10 +03:00
|
|
|
const int n = (int)AOMMIN(MAX_AV1_HEADER_SIZE, data_end - data);
|
2015-08-06 05:00:31 +03:00
|
|
|
pbi->decrypt_cb(pbi->decrypt_state, data, clear_data, n);
|
|
|
|
rb->bit_buffer = clear_data;
|
|
|
|
rb->bit_buffer_end = clear_data + n;
|
|
|
|
} else {
|
|
|
|
rb->bit_buffer = data;
|
|
|
|
rb->bit_buffer_end = data_end;
|
|
|
|
}
|
|
|
|
return rb;
|
|
|
|
}
|
|
|
|
|
|
|
|
//------------------------------------------------------------------------------
|
|
|
|
|
2016-08-31 00:01:10 +03:00
|
|
|
int av1_read_sync_code(struct aom_read_bit_buffer *const rb) {
|
|
|
|
return aom_rb_read_literal(rb, 8) == AV1_SYNC_CODE_0 &&
|
|
|
|
aom_rb_read_literal(rb, 8) == AV1_SYNC_CODE_1 &&
|
|
|
|
aom_rb_read_literal(rb, 8) == AV1_SYNC_CODE_2;
|
2015-08-06 05:00:31 +03:00
|
|
|
}
|
|
|
|
|
2016-08-31 00:01:10 +03:00
|
|
|
void av1_read_frame_size(struct aom_read_bit_buffer *rb, int *width,
|
|
|
|
int *height) {
|
|
|
|
*width = aom_rb_read_literal(rb, 16) + 1;
|
|
|
|
*height = aom_rb_read_literal(rb, 16) + 1;
|
2015-08-06 05:00:31 +03:00
|
|
|
}
|
|
|
|
|
2016-08-31 00:01:10 +03:00
|
|
|
BITSTREAM_PROFILE av1_read_profile(struct aom_read_bit_buffer *rb) {
|
|
|
|
int profile = aom_rb_read_bit(rb);
|
|
|
|
profile |= aom_rb_read_bit(rb) << 1;
|
|
|
|
if (profile > 2) profile += aom_rb_read_bit(rb);
|
2016-08-12 04:53:26 +03:00
|
|
|
return (BITSTREAM_PROFILE)profile;
|
2015-08-06 05:00:31 +03:00
|
|
|
}
|
|
|
|
|
2016-08-31 00:01:10 +03:00
|
|
|
void av1_decode_frame(AV1Decoder *pbi, const uint8_t *data,
|
|
|
|
const uint8_t *data_end, const uint8_t **p_data_end) {
|
|
|
|
AV1_COMMON *const cm = &pbi->common;
|
2015-08-06 05:00:31 +03:00
|
|
|
MACROBLOCKD *const xd = &pbi->mb;
|
2016-08-31 00:01:10 +03:00
|
|
|
struct aom_read_bit_buffer rb;
|
2015-08-06 05:00:31 +03:00
|
|
|
int context_updated = 0;
|
2016-08-31 00:01:10 +03:00
|
|
|
uint8_t clear_data[MAX_AV1_HEADER_SIZE];
|
2016-09-02 02:10:50 +03:00
|
|
|
size_t first_partition_size;
|
|
|
|
YV12_BUFFER_CONFIG *new_fb;
|
|
|
|
|
|
|
|
#if CONFIG_BITSTREAM_DEBUG
|
|
|
|
bitstream_queue_set_frame_read(cm->current_video_frame * 2 + cm->show_frame);
|
|
|
|
#endif
|
|
|
|
|
|
|
|
first_partition_size = read_uncompressed_header(
|
2016-08-12 04:53:26 +03:00
|
|
|
pbi, init_read_bit_buffer(pbi, &rb, data, data_end, clear_data));
|
2016-09-02 02:10:50 +03:00
|
|
|
new_fb = get_frame_new_buffer(cm);
|
2015-08-06 05:00:31 +03:00
|
|
|
xd->cur_buf = new_fb;
|
2016-07-11 21:47:55 +03:00
|
|
|
#if CONFIG_GLOBAL_MOTION
|
|
|
|
xd->global_motion = cm->global_motion;
|
|
|
|
#endif // CONFIG_GLOBAL_MOTION
|
2015-08-06 05:00:31 +03:00
|
|
|
|
|
|
|
if (!first_partition_size) {
|
2016-08-12 04:53:26 +03:00
|
|
|
// showing a frame directly
|
Merge bi-predictive frames to EXT_REFS
This patch removed the experiment of BIDIR_PRED and merged the feature
into the experiment of EXT_REFS:
(1) Each frame now has up to 6 reference frames, namely
LAST_FRAME, LAST2_FRAME, LAST3_FRAME, GOLDEN_FRAME, (forward) and
BWDREF_FRAME, ALTREF_FRAME (backward);
LAST4_FRAME has been removed;
(2) First pass still keeps the 8 updates:
KF_UPDATE, LF_UPDATE, GF_UPDATE, ARF_UPDATE, OVERLAY_UPDATE, and
BRF_UPDATE, LAST_BIPRED_UPDATE, BI_PRED_UPDATE;
(3) show_existing_frame==1 is supported in the experiment of EXT_REFS;
(4) New encoding modes are added for both single-ref and compound cases,
through the use of the 2 extra forward references (LAST2 & LAST3)
and the 1 extra backward reference (BWDREF).
RD performance wise, using Overall PSNR: Avg/BDRate
Bipred only Prev EXT_REFS Current EXT_REFS with bipred
lowres: -3.474/-3.324 -1.748/-1.586 -4.613/-4.387
derflr: -2.097/-1.353 -1.439/-1.215 -3.120/-2.252
midres: -2.129/-1.901 -1.345/-1.185 -2.898/-2.636
If in vp10/encoder/firstpass.h, change BFG_INTERVAL from 2 to 3, i.e. to
use 2 bi-predictive frames than 1, a further improvement may be
obtained:
Current EXT_REFS with bipred
1 bi-predictive frame 2 bi-predictive frames
lowres: -4.613/-4.387 -4.675/-4.465
derflr: -3.120/-2.252 -3.333/-2.516
midres: -2.898/-2.636 -3.406/-3.095
Change-Id: Ib06fe9ea0a5cfd7418a1d79b978ee9d80bf191cb
2016-06-09 00:27:56 +03:00
|
|
|
#if CONFIG_EXT_REFS
|
2016-02-04 20:47:46 +03:00
|
|
|
if (cm->show_existing_frame)
|
2016-08-31 00:01:10 +03:00
|
|
|
*p_data_end = data + aom_rb_bytes_read(&rb);
|
2016-02-04 20:47:46 +03:00
|
|
|
else
|
Merge bi-predictive frames to EXT_REFS
This patch removed the experiment of BIDIR_PRED and merged the feature
into the experiment of EXT_REFS:
(1) Each frame now has up to 6 reference frames, namely
LAST_FRAME, LAST2_FRAME, LAST3_FRAME, GOLDEN_FRAME, (forward) and
BWDREF_FRAME, ALTREF_FRAME (backward);
LAST4_FRAME has been removed;
(2) First pass still keeps the 8 updates:
KF_UPDATE, LF_UPDATE, GF_UPDATE, ARF_UPDATE, OVERLAY_UPDATE, and
BRF_UPDATE, LAST_BIPRED_UPDATE, BI_PRED_UPDATE;
(3) show_existing_frame==1 is supported in the experiment of EXT_REFS;
(4) New encoding modes are added for both single-ref and compound cases,
through the use of the 2 extra forward references (LAST2 & LAST3)
and the 1 extra backward reference (BWDREF).
RD performance wise, using Overall PSNR: Avg/BDRate
Bipred only Prev EXT_REFS Current EXT_REFS with bipred
lowres: -3.474/-3.324 -1.748/-1.586 -4.613/-4.387
derflr: -2.097/-1.353 -1.439/-1.215 -3.120/-2.252
midres: -2.129/-1.901 -1.345/-1.185 -2.898/-2.636
If in vp10/encoder/firstpass.h, change BFG_INTERVAL from 2 to 3, i.e. to
use 2 bi-predictive frames than 1, a further improvement may be
obtained:
Current EXT_REFS with bipred
1 bi-predictive frame 2 bi-predictive frames
lowres: -4.613/-4.387 -4.675/-4.465
derflr: -3.120/-2.252 -3.333/-2.516
midres: -2.898/-2.636 -3.406/-3.095
Change-Id: Ib06fe9ea0a5cfd7418a1d79b978ee9d80bf191cb
2016-06-09 00:27:56 +03:00
|
|
|
#endif // CONFIG_EXT_REFS
|
2016-02-04 20:47:46 +03:00
|
|
|
*p_data_end = data + (cm->profile <= PROFILE_2 ? 1 : 2);
|
|
|
|
|
2015-08-06 05:00:31 +03:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2016-08-31 00:01:10 +03:00
|
|
|
data += aom_rb_bytes_read(&rb);
|
2015-08-06 05:00:31 +03:00
|
|
|
if (!read_is_valid(data, first_partition_size, data_end))
|
2016-08-31 00:01:10 +03:00
|
|
|
aom_internal_error(&cm->error, AOM_CODEC_CORRUPT_FRAME,
|
2015-08-06 05:00:31 +03:00
|
|
|
"Truncated packet or corrupt header length");
|
|
|
|
|
2016-08-12 04:53:26 +03:00
|
|
|
cm->use_prev_frame_mvs =
|
|
|
|
!cm->error_resilient_mode && cm->width == cm->last_width &&
|
|
|
|
cm->height == cm->last_height && !cm->last_intra_only &&
|
|
|
|
cm->last_show_frame && (cm->last_frame_type != KEY_FRAME);
|
Merge bi-predictive frames to EXT_REFS
This patch removed the experiment of BIDIR_PRED and merged the feature
into the experiment of EXT_REFS:
(1) Each frame now has up to 6 reference frames, namely
LAST_FRAME, LAST2_FRAME, LAST3_FRAME, GOLDEN_FRAME, (forward) and
BWDREF_FRAME, ALTREF_FRAME (backward);
LAST4_FRAME has been removed;
(2) First pass still keeps the 8 updates:
KF_UPDATE, LF_UPDATE, GF_UPDATE, ARF_UPDATE, OVERLAY_UPDATE, and
BRF_UPDATE, LAST_BIPRED_UPDATE, BI_PRED_UPDATE;
(3) show_existing_frame==1 is supported in the experiment of EXT_REFS;
(4) New encoding modes are added for both single-ref and compound cases,
through the use of the 2 extra forward references (LAST2 & LAST3)
and the 1 extra backward reference (BWDREF).
RD performance wise, using Overall PSNR: Avg/BDRate
Bipred only Prev EXT_REFS Current EXT_REFS with bipred
lowres: -3.474/-3.324 -1.748/-1.586 -4.613/-4.387
derflr: -2.097/-1.353 -1.439/-1.215 -3.120/-2.252
midres: -2.129/-1.901 -1.345/-1.185 -2.898/-2.636
If in vp10/encoder/firstpass.h, change BFG_INTERVAL from 2 to 3, i.e. to
use 2 bi-predictive frames than 1, a further improvement may be
obtained:
Current EXT_REFS with bipred
1 bi-predictive frame 2 bi-predictive frames
lowres: -4.613/-4.387 -4.675/-4.465
derflr: -3.120/-2.252 -3.333/-2.516
midres: -2.898/-2.636 -3.406/-3.095
Change-Id: Ib06fe9ea0a5cfd7418a1d79b978ee9d80bf191cb
2016-06-09 00:27:56 +03:00
|
|
|
#if CONFIG_EXT_REFS
|
2016-05-25 21:57:15 +03:00
|
|
|
// NOTE(zoeliu): As cm->prev_frame can take neither a frame of
|
|
|
|
// show_exisiting_frame=1, nor can it take a frame not used as
|
|
|
|
// a reference, it is probable that by the time it is being
|
|
|
|
// referred to, the frame buffer it originally points to may
|
|
|
|
// already get expired and have been reassigned to the current
|
|
|
|
// newly coded frame. Hence, we need to check whether this is
|
|
|
|
// the case, and if yes, we have 2 choices:
|
|
|
|
// (1) Simply disable the use of previous frame mvs; or
|
|
|
|
// (2) Have cm->prev_frame point to one reference frame buffer,
|
|
|
|
// e.g. LAST_FRAME.
|
|
|
|
if (cm->use_prev_frame_mvs && !dec_is_ref_frame_buf(pbi, cm->prev_frame)) {
|
|
|
|
// Reassign the LAST_FRAME buffer to cm->prev_frame.
|
|
|
|
RefBuffer *last_fb_ref_buf = &cm->frame_refs[LAST_FRAME - LAST_FRAME];
|
|
|
|
cm->prev_frame = &cm->buffer_pool->frame_bufs[last_fb_ref_buf->idx];
|
|
|
|
}
|
Merge bi-predictive frames to EXT_REFS
This patch removed the experiment of BIDIR_PRED and merged the feature
into the experiment of EXT_REFS:
(1) Each frame now has up to 6 reference frames, namely
LAST_FRAME, LAST2_FRAME, LAST3_FRAME, GOLDEN_FRAME, (forward) and
BWDREF_FRAME, ALTREF_FRAME (backward);
LAST4_FRAME has been removed;
(2) First pass still keeps the 8 updates:
KF_UPDATE, LF_UPDATE, GF_UPDATE, ARF_UPDATE, OVERLAY_UPDATE, and
BRF_UPDATE, LAST_BIPRED_UPDATE, BI_PRED_UPDATE;
(3) show_existing_frame==1 is supported in the experiment of EXT_REFS;
(4) New encoding modes are added for both single-ref and compound cases,
through the use of the 2 extra forward references (LAST2 & LAST3)
and the 1 extra backward reference (BWDREF).
RD performance wise, using Overall PSNR: Avg/BDRate
Bipred only Prev EXT_REFS Current EXT_REFS with bipred
lowres: -3.474/-3.324 -1.748/-1.586 -4.613/-4.387
derflr: -2.097/-1.353 -1.439/-1.215 -3.120/-2.252
midres: -2.129/-1.901 -1.345/-1.185 -2.898/-2.636
If in vp10/encoder/firstpass.h, change BFG_INTERVAL from 2 to 3, i.e. to
use 2 bi-predictive frames than 1, a further improvement may be
obtained:
Current EXT_REFS with bipred
1 bi-predictive frame 2 bi-predictive frames
lowres: -4.613/-4.387 -4.675/-4.465
derflr: -3.120/-2.252 -3.333/-2.516
midres: -2.898/-2.636 -3.406/-3.095
Change-Id: Ib06fe9ea0a5cfd7418a1d79b978ee9d80bf191cb
2016-06-09 00:27:56 +03:00
|
|
|
#endif // CONFIG_EXT_REFS
|
2015-08-06 05:00:31 +03:00
|
|
|
|
2016-08-31 00:01:10 +03:00
|
|
|
av1_setup_block_planes(xd, cm->subsampling_x, cm->subsampling_y);
|
2015-08-06 05:00:31 +03:00
|
|
|
|
|
|
|
*cm->fc = cm->frame_contexts[cm->frame_context_idx];
|
|
|
|
if (!cm->fc->initialized)
|
2016-08-31 00:01:10 +03:00
|
|
|
aom_internal_error(&cm->error, AOM_CODEC_CORRUPT_FRAME,
|
2015-08-06 05:00:31 +03:00
|
|
|
"Uninitialized entropy context.");
|
|
|
|
|
2016-08-31 00:01:10 +03:00
|
|
|
av1_zero(cm->counts);
|
2015-08-06 05:00:31 +03:00
|
|
|
|
|
|
|
xd->corrupted = 0;
|
|
|
|
new_fb->corrupted = read_compressed_header(pbi, data, first_partition_size);
|
|
|
|
if (new_fb->corrupted)
|
2016-08-31 00:01:10 +03:00
|
|
|
aom_internal_error(&cm->error, AOM_CODEC_CORRUPT_FRAME,
|
2015-08-06 05:00:31 +03:00
|
|
|
"Decode failed. Frame data header is corrupted.");
|
|
|
|
|
|
|
|
if (cm->lf.filter_level && !cm->skip_loop_filter) {
|
2016-08-31 00:01:10 +03:00
|
|
|
av1_loop_filter_frame_init(cm, cm->lf.filter_level);
|
2015-08-06 05:00:31 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
// If encoded in frame parallel mode, frame context is ready after decoding
|
|
|
|
// the frame header.
|
2015-09-08 21:20:48 +03:00
|
|
|
if (cm->frame_parallel_decode &&
|
|
|
|
cm->refresh_frame_context != REFRESH_FRAME_CONTEXT_BACKWARD) {
|
2016-08-31 00:01:10 +03:00
|
|
|
AVxWorker *const worker = pbi->frame_worker_owner;
|
2015-08-06 05:00:31 +03:00
|
|
|
FrameWorkerData *const frame_worker_data = worker->data1;
|
2015-09-08 21:20:48 +03:00
|
|
|
if (cm->refresh_frame_context == REFRESH_FRAME_CONTEXT_FORWARD) {
|
2015-08-06 05:00:31 +03:00
|
|
|
context_updated = 1;
|
|
|
|
cm->frame_contexts[cm->frame_context_idx] = *cm->fc;
|
|
|
|
}
|
2016-08-31 00:01:10 +03:00
|
|
|
av1_frameworker_lock_stats(worker);
|
2015-08-06 05:00:31 +03:00
|
|
|
pbi->cur_buf->row = -1;
|
|
|
|
pbi->cur_buf->col = -1;
|
|
|
|
frame_worker_data->frame_context_ready = 1;
|
|
|
|
// Signal the main thread that context is ready.
|
2016-08-31 00:01:10 +03:00
|
|
|
av1_frameworker_signal_stats(worker);
|
|
|
|
av1_frameworker_unlock_stats(worker);
|
2015-08-06 05:00:31 +03:00
|
|
|
}
|
|
|
|
|
2016-01-08 01:29:26 +03:00
|
|
|
#if CONFIG_ENTROPY
|
2016-08-31 00:01:10 +03:00
|
|
|
av1_copy(cm->starting_coef_probs, cm->fc->coef_probs);
|
2016-01-08 01:29:26 +03:00
|
|
|
cm->coef_probs_update_idx = 0;
|
|
|
|
#endif // CONFIG_ENTROPY
|
|
|
|
|
2016-03-11 20:42:49 +03:00
|
|
|
if (pbi->max_threads > 1
|
|
|
|
#if CONFIG_EXT_TILE
|
|
|
|
&& pbi->dec_tile_col < 0 // Decoding all columns
|
2016-08-12 04:53:26 +03:00
|
|
|
#endif // CONFIG_EXT_TILE
|
2016-03-11 20:42:49 +03:00
|
|
|
&& cm->tile_cols > 1) {
|
2015-08-06 05:00:31 +03:00
|
|
|
// Multi-threaded tile decoder
|
|
|
|
*p_data_end = decode_tiles_mt(pbi, data + first_partition_size, data_end);
|
|
|
|
if (!xd->corrupted) {
|
|
|
|
if (!cm->skip_loop_filter) {
|
|
|
|
// If multiple threads are used to decode tiles, then we use those
|
|
|
|
// threads to do parallel loopfiltering.
|
2016-08-31 00:01:10 +03:00
|
|
|
av1_loop_filter_frame_mt(new_fb, cm, pbi->mb.plane, cm->lf.filter_level,
|
|
|
|
0, 0, pbi->tile_workers, pbi->num_tile_workers,
|
|
|
|
&pbi->lf_row_sync);
|
2015-08-06 05:00:31 +03:00
|
|
|
}
|
|
|
|
} else {
|
2016-08-31 00:01:10 +03:00
|
|
|
aom_internal_error(&cm->error, AOM_CODEC_CORRUPT_FRAME,
|
2015-08-06 05:00:31 +03:00
|
|
|
"Decode failed. Frame data is corrupted.");
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
*p_data_end = decode_tiles(pbi, data + first_partition_size, data_end);
|
|
|
|
}
|
2016-01-20 00:01:01 +03:00
|
|
|
#if CONFIG_LOOP_RESTORATION
|
2016-02-09 23:24:33 +03:00
|
|
|
if (cm->rst_info.restoration_type != RESTORE_NONE) {
|
2016-08-31 00:01:10 +03:00
|
|
|
av1_loop_restoration_init(&cm->rst_internal, &cm->rst_info,
|
|
|
|
cm->frame_type == KEY_FRAME, cm->width,
|
|
|
|
cm->height);
|
|
|
|
av1_loop_restoration_rows(new_fb, cm, 0, cm->mi_rows, 0);
|
2016-01-20 00:01:01 +03:00
|
|
|
}
|
|
|
|
#endif // CONFIG_LOOP_RESTORATION
|
2015-08-06 05:00:31 +03:00
|
|
|
|
2016-04-20 02:57:24 +03:00
|
|
|
#if CONFIG_CLPF
|
|
|
|
if (cm->clpf && !cm->skip_loop_filter)
|
|
|
|
av1_clpf_frame(&pbi->cur_buf->buf, cm, &pbi->mb);
|
|
|
|
#endif
|
|
|
|
#if CONFIG_DERING
|
|
|
|
if (cm->dering_level && !cm->skip_loop_filter) {
|
|
|
|
av1_dering_frame(&pbi->cur_buf->buf, cm, &pbi->mb, cm->dering_level);
|
|
|
|
}
|
|
|
|
#endif // CONFIG_DERING
|
|
|
|
|
2015-08-06 05:00:31 +03:00
|
|
|
if (!xd->corrupted) {
|
2015-09-08 21:20:48 +03:00
|
|
|
if (cm->refresh_frame_context == REFRESH_FRAME_CONTEXT_BACKWARD) {
|
2016-01-08 01:29:26 +03:00
|
|
|
#if CONFIG_ENTROPY
|
|
|
|
cm->partial_prob_update = 0;
|
|
|
|
#endif // CONFIG_ENTROPY
|
2016-08-31 00:01:10 +03:00
|
|
|
av1_adapt_coef_probs(cm);
|
|
|
|
av1_adapt_intra_frame_probs(cm);
|
2015-08-06 05:00:31 +03:00
|
|
|
|
|
|
|
if (!frame_is_intra_only(cm)) {
|
2016-08-31 00:01:10 +03:00
|
|
|
av1_adapt_inter_frame_probs(cm);
|
|
|
|
av1_adapt_mv_probs(cm, cm->allow_high_precision_mv);
|
2015-08-06 05:00:31 +03:00
|
|
|
}
|
|
|
|
} else {
|
|
|
|
debug_check_frame_counts(cm);
|
|
|
|
}
|
|
|
|
} else {
|
2016-08-31 00:01:10 +03:00
|
|
|
aom_internal_error(&cm->error, AOM_CODEC_CORRUPT_FRAME,
|
2015-08-06 05:00:31 +03:00
|
|
|
"Decode failed. Frame data is corrupted.");
|
|
|
|
}
|
|
|
|
|
|
|
|
// Non frame parallel update frame context here.
|
2016-05-10 00:20:50 +03:00
|
|
|
if (!cm->error_resilient_mode && !context_updated)
|
2015-08-06 05:00:31 +03:00
|
|
|
cm->frame_contexts[cm->frame_context_idx] = *cm->fc;
|
|
|
|
}
|