67 #define MIN_TB_ADDR_ZS(x, y) \ 68 s->ps.pps->min_tb_addr_zs[(y) * (s->ps.sps->tb_mask+2) + (x)] 74 if( yN_ctb < yCurr_ctb || xN_ctb < xCurr_ctb )
90 return xN >> plevel == xP >> plevel &&
91 yN >> plevel == yP >> plevel;
94 #define MATCH_MV(x) (AV_RN32A(&A.x) == AV_RN32A(&B.x)) 95 #define MATCH(x) (A.x == B.x) 106 }
else if (a_pf ==
PF_L0) {
108 }
else if (a_pf ==
PF_L1) {
117 int tx, scale_factor;
121 tx = (0x4000 +
abs(td / 2)) / td;
124 (scale_factor * src->
x < 0)) >> 8);
126 (scale_factor * src->
y < 0)) >> 8);
132 RefPicList *refPicList_col,
int listCol,
int refidxCol)
135 int col_lt = refPicList_col[listCol].
isLongTerm[refidxCol];
136 int col_poc_diff, cur_poc_diff;
138 if (cur_lt != col_lt) {
144 col_poc_diff = colPic - refPicList_col[listCol].
list[refidxCol];
145 cur_poc_diff = poc - refPicList[
X].
list[refIdxLx];
147 if (cur_lt || col_poc_diff == cur_poc_diff || !col_poc_diff) {
148 mvLXCol->
x = mvCol->
x;
149 mvLXCol->
y = mvCol->
y;
151 mv_scale(mvLXCol, mvCol, col_poc_diff, cur_poc_diff);
156 #define CHECK_MVSET(l) \ 157 check_mvset(mvLXCol, temp_col.mv + l, \ 159 refPicList, X, refIdxLx, \ 160 refPicList_col, L ## l, temp_col.ref_idx[l]) 164 int refIdxLx,
Mv *mvLXCol,
int X,
177 int check_diffpicount = 0;
179 for (j = 0; j < 2; j++) {
180 for (i = 0; i < refPicList[j].
nb_refs; i++) {
181 if (refPicList[j].
list[i] > s->
poc) {
187 if (!check_diffpicount) {
203 #define TAB_MVF(x, y) \ 204 tab_mvf[(y) * min_pu_width + x] 206 #define TAB_MVF_PU(v) \ 207 TAB_MVF(((x ## v) >> s->ps.sps->log2_min_pu_size), \ 208 ((y ## v) >> s->ps.sps->log2_min_pu_size)) 210 #define DERIVE_TEMPORAL_COLOCATED_MVS \ 211 derive_temporal_colocated_mvs(s, temp_col, \ 212 refIdxLx, mvLXCol, X, colPic, \ 213 ff_hevc_get_ref_list(s, ref, x, y)) 219 int nPbW,
int nPbH,
int refIdxLx,
224 int x, y, x_pu, y_pu;
226 int availableFlagLXCol = 0;
232 memset(mvLXCol, 0,
sizeof(*mvLXCol));
245 y < s->ps.sps->height &&
246 x < s->ps.sps->width) {
253 temp_col =
TAB_MVF(x_pu, y_pu);
258 if (tab_mvf && !availableFlagLXCol) {
259 x = x0 + (nPbW >> 1);
260 y = y0 + (nPbH >> 1);
267 temp_col =
TAB_MVF(x_pu, y_pu);
270 return availableFlagLXCol;
273 #define AVAILABLE(cand, v) \ 274 (cand && !(TAB_MVF_PU(v).pred_flag == PF_INTRA)) 276 #define PRED_BLOCK_AVAILABLE(v) \ 277 z_scan_block_avail(s, x0, y0, x ## v, y ## v) 279 #define COMPARE_MV_REFIDX(a, b) \ 280 compare_mv_ref_idx(TAB_MVF_PU(a), TAB_MVF_PU(b)) 288 int singleMCLFlag,
int part_idx,
290 struct MvField mergecandlist[])
304 const int xA1 = x0 - 1;
305 const int yA1 = y0 + nPbH - 1;
307 const int xB1 = x0 + nPbW - 1;
308 const int yB1 = y0 - 1;
310 const int xB0 = x0 + nPbW;
311 const int yB0 = y0 - 1;
313 const int xA0 = x0 - 1;
314 const int yA0 = y0 + nPbH;
316 const int xB2 = x0 - 1;
317 const int yB2 = y0 - 1;
324 int nb_merge_cand = 0;
325 int nb_orig_merge_cand = 0;
334 if (!singleMCLFlag && part_idx == 1 &&
342 if (is_available_a1) {
350 if (!singleMCLFlag && part_idx == 1 &&
358 if (is_available_b1 &&
361 if (merge_idx == nb_merge_cand)
373 if (is_available_b0 &&
376 if (merge_idx == nb_merge_cand)
382 is_available_a0 =
AVAILABLE(cand_bottom_left, A0) &&
387 if (is_available_a0 &&
389 mergecandlist[nb_merge_cand] =
TAB_MVF_PU(A0);
390 if (merge_idx == nb_merge_cand)
399 if (is_available_b2 &&
402 nb_merge_cand != 4) {
404 if (merge_idx == nb_merge_cand)
411 nb_merge_cand < s->sh.max_num_merge_cand) {
412 Mv mv_l0_col = { 0 }, mv_l1_col = { 0 };
417 0, &mv_l1_col, 1) : 0;
419 if (available_l0 || available_l1) {
420 mergecandlist[nb_merge_cand].
pred_flag = available_l0 + (available_l1 << 1);
421 AV_ZERO16(mergecandlist[nb_merge_cand].ref_idx);
422 mergecandlist[nb_merge_cand].
mv[0] = mv_l0_col;
423 mergecandlist[nb_merge_cand].
mv[1] = mv_l1_col;
425 if (merge_idx == nb_merge_cand)
431 nb_orig_merge_cand = nb_merge_cand;
435 nb_orig_merge_cand < s->sh.max_num_merge_cand) {
439 comb_idx < nb_orig_merge_cand * (nb_orig_merge_cand - 1); comb_idx++) {
442 MvField l0_cand = mergecandlist[l0_cand_idx];
443 MvField l1_cand = mergecandlist[l1_cand_idx];
452 AV_COPY32(&mergecandlist[nb_merge_cand].
mv[0], &l0_cand.
mv[0]);
453 AV_COPY32(&mergecandlist[nb_merge_cand].mv[1], &l1_cand.
mv[1]);
454 if (merge_idx == nb_merge_cand)
462 while (nb_merge_cand < s->sh.max_num_merge_cand) {
466 mergecandlist[nb_merge_cand].
ref_idx[0] = zero_idx < nb_refs ? zero_idx : 0;
467 mergecandlist[nb_merge_cand].
ref_idx[1] = zero_idx < nb_refs ? zero_idx : 0;
469 if (merge_idx == nb_merge_cand)
480 int nPbH,
int log2_cb_size,
int part_idx,
483 int singleMCLFlag = 0;
484 int nCS = 1 << log2_cb_size;
501 singleMCLFlag, part_idx,
502 merge_idx, mergecand_list);
504 if (mergecand_list[merge_idx].pred_flag ==
PF_BI &&
505 (nPbW2 + nPbH2) == 12) {
509 *mv = mergecand_list[merge_idx];
513 int min_pu_width,
int x,
int y,
514 int elist,
int ref_idx_curr,
int ref_idx)
518 int ref_pic_elist = refPicList[elist].
list[
TAB_MVF(x, y).ref_idx[elist]];
519 int ref_pic_curr = refPicList[ref_idx_curr].
list[ref_idx];
521 if (ref_pic_elist != ref_pic_curr) {
522 int poc_diff = s->
poc - ref_pic_elist;
530 Mv *
mv,
int ref_idx_curr,
int ref_idx)
537 if (((
TAB_MVF(x, y).pred_flag) & (1 << pred_flag_index)) &&
538 refPicList[pred_flag_index].
list[
TAB_MVF(x, y).ref_idx[pred_flag_index]] == refPicList[ref_idx_curr].
list[ref_idx]) {
539 *mv =
TAB_MVF(x, y).mv[pred_flag_index];
546 Mv *
mv,
int ref_idx_curr,
int ref_idx)
553 if ((
TAB_MVF(x, y).pred_flag) & (1 << pred_flag_index)) {
554 int currIsLongTerm = refPicList[ref_idx_curr].
isLongTerm[ref_idx];
557 refPicList[pred_flag_index].
isLongTerm[(
TAB_MVF(x, y).ref_idx[pred_flag_index])];
559 if (colIsLongTerm == currIsLongTerm) {
560 *mv =
TAB_MVF(x, y).mv[pred_flag_index];
563 pred_flag_index, ref_idx_curr, ref_idx);
570 #define MP_MX(v, pred, mx) \ 572 (x ## v) >> s->ps.sps->log2_min_pu_size, \ 573 (y ## v) >> s->ps.sps->log2_min_pu_size, \ 574 pred, &mx, ref_idx_curr, ref_idx) 576 #define MP_MX_LT(v, pred, mx) \ 577 mv_mp_mode_mx_lt(s, \ 578 (x ## v) >> s->ps.sps->log2_min_pu_size, \ 579 (y ## v) >> s->ps.sps->log2_min_pu_size, \ 580 pred, &mx, ref_idx_curr, ref_idx) 583 int nPbH,
int log2_cb_size,
int part_idx,
585 int mvp_lx_flag,
int LX)
589 int isScaledFlag_L0 = 0;
590 int availableFlagLXA0 = 1;
591 int availableFlagLXB0 = 1;
592 int numMVPCandLX = 0;
606 Mv mvpcand_list[2] = { { 0 } };
611 int pred_flag_index_l0;
612 int pred_flag_index_l1;
621 pred_flag_index_l0 = LX;
622 pred_flag_index_l1 = !LX;
628 is_available_a0 =
AVAILABLE(cand_bottom_left, A0) &&
637 if (is_available_a0 || is_available_a1)
640 if (is_available_a0) {
641 if (
MP_MX(A0, pred_flag_index_l0, mxA)) {
644 if (
MP_MX(A0, pred_flag_index_l1, mxA)) {
649 if (is_available_a1) {
650 if (
MP_MX(
A1, pred_flag_index_l0, mxA)) {
653 if (
MP_MX(
A1, pred_flag_index_l1, mxA)) {
658 if (is_available_a0) {
659 if (
MP_MX_LT(A0, pred_flag_index_l0, mxA)) {
662 if (
MP_MX_LT(A0, pred_flag_index_l1, mxA)) {
667 if (is_available_a1) {
675 availableFlagLXA0 = 0;
698 if (is_available_b0) {
699 if (
MP_MX(
B0, pred_flag_index_l0, mxB)) {
702 if (
MP_MX(
B0, pred_flag_index_l1, mxB)) {
708 if (is_available_b1) {
709 if (
MP_MX(
B1, pred_flag_index_l0, mxB)) {
712 if (
MP_MX(
B1, pred_flag_index_l1, mxB)) {
718 if (is_available_b2) {
719 if (
MP_MX(
B2, pred_flag_index_l0, mxB)) {
722 if (
MP_MX(
B2, pred_flag_index_l1, mxB)) {
726 availableFlagLXB0 = 0;
729 if (!isScaledFlag_L0) {
730 if (availableFlagLXB0) {
731 availableFlagLXA0 = 1;
734 availableFlagLXB0 = 0;
737 if (is_available_b0) {
738 availableFlagLXB0 =
MP_MX_LT(
B0, pred_flag_index_l0, mxB);
739 if (!availableFlagLXB0)
740 availableFlagLXB0 =
MP_MX_LT(
B0, pred_flag_index_l1, mxB);
743 if (is_available_b1 && !availableFlagLXB0) {
744 availableFlagLXB0 =
MP_MX_LT(
B1, pred_flag_index_l0, mxB);
745 if (!availableFlagLXB0)
746 availableFlagLXB0 =
MP_MX_LT(
B1, pred_flag_index_l1, mxB);
749 if (is_available_b2 && !availableFlagLXB0) {
750 availableFlagLXB0 =
MP_MX_LT(
B2, pred_flag_index_l0, mxB);
751 if (!availableFlagLXB0)
752 availableFlagLXB0 =
MP_MX_LT(
B2, pred_flag_index_l1, mxB);
756 if (availableFlagLXA0)
757 mvpcand_list[numMVPCandLX++] = mxA;
759 if (availableFlagLXB0 && (!availableFlagLXA0 || mxA.
x != mxB.
x || mxA.
y != mxB.
y))
760 mvpcand_list[numMVPCandLX++] = mxB;
763 if (numMVPCandLX < 2 && s->sh.slice_temporal_mvp_enabled_flag &&
764 mvp_lx_flag == numMVPCandLX) {
770 mvpcand_list[numMVPCandLX++] = mv_col;
773 mv->
mv[LX] = mvpcand_list[mvp_lx_flag];
static av_always_inline void mv_scale(Mv *dst, Mv *src, int td, int tb)
#define MP_MX(v, pred, mx)
int16_t x
horizontal component of motion vector
static int temporal_luma_motion_vector(HEVCContext *s, int x0, int y0, int nPbW, int nPbH, int refIdxLx, Mv *mvLXCol, int X)
static int mv_mp_mode_mx(HEVCContext *s, int x, int y, int pred_flag_index, Mv *mv, int ref_idx_curr, int ref_idx)
static void derive_spatial_merge_candidates(HEVCContext *s, int x0, int y0, int nPbW, int nPbH, int log2_cb_size, int singleMCLFlag, int part_idx, int merge_idx, struct MvField mergecandlist[])
static int derive_temporal_colocated_mvs(HEVCContext *s, MvField temp_col, int refIdxLx, Mv *mvLXCol, int X, int colPic, RefPicList *refPicList_col)
the pkt_dts and pkt_pts fields in AVFrame will work as usual Restrictions on codec whose streams don t reset across will not work because their bitstreams cannot be decoded in parallel *The contents of buffers must not be read before ff_thread_await_progress() has been called on them.reget_buffer() and buffer age optimizations no longer work.*The contents of buffers must not be written to after ff_thread_report_progress() has been called on them.This includes draw_edges().Porting codecs to frame threading
int log2_parallel_merge_level
log2_parallel_merge_level_minus2 + 2
static int mv_mp_mode_mx_lt(HEVCContext *s, int x, int y, int pred_flag_index, Mv *mv, int ref_idx_curr, int ref_idx)
#define MRG_MAX_NUM_CANDS
uint8_t ctb_up_right_flag
#define DERIVE_TEMPORAL_COLOCATED_MVS
static av_always_inline int is_diff_mer(HEVCContext *s, int xN, int yN, int xP, int yP)
#define AVAILABLE(cand, v)
#define MIN_TB_ADDR_ZS(x, y)
unsigned int log2_ctb_size
#define MP_MX_LT(v, pred, mx)
static int check_mvset(Mv *mvLXCol, Mv *mvCol, int colPic, int poc, RefPicList *refPicList, int X, int refIdxLx, RefPicList *refPicList_col, int listCol, int refidxCol)
#define COMPARE_MV_REFIDX(a, b)
#define FF_THREAD_FRAME
Decode more than one frame at once.
static const uint8_t l0_l1_cand_idx[12][2]
struct HEVCFrame * collocated_ref
static const int8_t mv[256][2]
static av_always_inline void dist_scale(HEVCContext *s, Mv *mv, int min_pu_width, int x, int y, int elist, int ref_idx_curr, int ref_idx)
unsigned int log2_min_pu_size
Filter the word “frame” indicates either a video frame or a group of audio as stored in an AVFrame structure Format for each input and each output the list of supported formats For video that means pixel format For audio that means channel sample they are references to shared objects When the negotiation mechanism computes the intersection of the formats supported at each end of a all references to both lists are replaced with a reference to the intersection And when a single format is eventually chosen for a link amongst the remaining list
int16_t y
vertical component of motion vector
unsigned int log2_min_tb_size
void ff_hevc_luma_mv_merge_mode(HEVCContext *s, int x0, int y0, int nPbW, int nPbH, int log2_cb_size, int part_idx, int merge_idx, MvField *mv)
enum PartMode part_mode
PartMode.
static av_always_inline int z_scan_block_avail(HEVCContext *s, int xCurr, int yCurr, int xN, int yN)
HEVCLocalContext * HEVClc
F H1 F F H1 F F F F H1<-F-------F-------F v v v H2 H3 H2^^^F-------F-------F-> H1<-F-------F-------F|||||||||F H1 F|||||||||F H1 Funavailable fullpel samples(outside the picture for example) shall be equalto the closest available fullpel sampleSmaller pel interpolation:--------------------------if diag_mc is set then points which lie on a line between 2 vertically, horizontally or diagonally adjacent halfpel points shall be interpolatedlinearly with rounding to nearest and halfway values rounded up.points which lie on 2 diagonals at the same time should only use the onediagonal not containing the fullpel point F--> O q O<--h1-> O q O<--F v\/v\/v O O O O O O O|/|\|q q q q q|/|\|O O O O O O O^/\^/\^h2--> O q O<--h3-> O q O<--h2 v\/v\/v O O O O O O O|\|/|q q q q q|\|/|O O O O O O O^/\^/\^F--> O q O<--h1-> O q O<--Fthe remaining points shall be bilinearly interpolated from theup to 4 surrounding halfpel and fullpel points, again rounding should be tonearest and halfway values rounded upcompliant Snow decoders MUST support 1-1/8 pel luma and 1/2-1/16 pel chromainterpolation at leastOverlapped block motion compensation:-------------------------------------FIXMELL band prediction:===================Each sample in the LL0 subband is predicted by the median of the left, top andleft+top-topleft samples, samples outside the subband shall be considered tobe 0.To reverse this prediction in the decoder apply the following.for(y=0;y< height;y++){for(x=0;x< width;x++){sample[y][x]+=median(sample[y-1][x], sample[y][x-1], sample[y-1][x]+sample[y][x-1]-sample[y-1][x-1]);}}sample[-1][*]=sample[*][-1]=0;width, height here are the width and height of the LL0 subband not of the finalvideoDequantization:===============FIXMEWavelet Transform:==================Snow supports 2 wavelet transforms, the symmetric biorthogonal 5/3 integertransform and an integer approximation of the symmetric biorthogonal 9/7daubechies wavelet.2D IDWT(inverse discrete wavelet transform)--------------------------------------------The 2D IDWT applies a 2D filter recursively, each time combining the4 lowest frequency subbands into a single subband until only 1 subbandremains.The 2D filter is done by first applying a 1D filter in the vertical directionand then applying it in the horizontal one.------------------------------------------------------------|LL0|HL0|||||||||||||---+---|HL1||L0|H0|HL1||LL1|HL1|||||LH0|HH0|||||||||||||-------+-------|-> L1 H1 LH1 HH1 LH1 HH1 LH1 HH1 L1
void ff_hevc_luma_mv_mvp_mode(HEVCContext *s, int x0, int y0, int nPbW, int nPbH, int log2_cb_size, int part_idx, int merge_idx, MvField *mv, int mvp_lx_flag, int LX)
static av_always_inline int compare_mv_ref_idx(struct MvField A, struct MvField B)
static int ref[MAX_W *MAX_W]
void ff_hevc_set_neighbour_available(HEVCContext *s, int x0, int y0, int nPbW, int nPbH)
#define PRED_BLOCK_AVAILABLE(v)
int isLongTerm[HEVC_MAX_REFS]