summaryrefslogtreecommitdiff
path: root/vstream
diff options
context:
space:
mode:
authorMarcin Koƛcielnicki <koriakin@0x04.net>2011-12-23 20:26:01 +0100
committerMarcin Koƛcielnicki <koriakin@0x04.net>2011-12-23 20:26:01 +0100
commitc3a912b4724e7ba198441161a51294e8e2f19e70 (patch)
treeefb9a44cede437c089b7fc389a66e71108917e63 /vstream
parent83d4e4dfd8161c4e496610f8b75e4fe4f9d95cac (diff)
h264: ref_idx and mvd SEs.
Diffstat (limited to 'vstream')
-rw-r--r--vstream/h264_se.c66
1 files changed, 66 insertions, 0 deletions
diff --git a/vstream/h264_se.c b/vstream/h264_se.c
index 0a5993a1..3b1df490 100644
--- a/vstream/h264_se.c
+++ b/vstream/h264_se.c
@@ -554,6 +554,72 @@ int h264_intra_chroma_pred_mode(struct bitstream *str, struct h264_cabac_context
return h264_cabac_tu(str, cabac, ctxIdx, 2, 3, val);
}
+int h264_ref_idx(struct bitstream *str, struct h264_cabac_context *cabac, int idx, int which, int max, uint32_t *val) {
+ if (!max)
+ return vs_infer(str, val, 0);
+ if (!cabac) {
+ if (max == 1) {
+ uint32_t tmp = 1 - *val;
+ if (vs_u(str, val, 1)) return 1;
+ *val = 1 - tmp;
+ return 0;
+ } else {
+ return vs_ue(str, val);
+ }
+ }
+ int idxA, idxB;
+ const struct h264_macroblock *mbT = h264_mb_nb(cabac->slice, H264_MB_THIS, 0);
+ const struct h264_macroblock *mbA = h264_mb_nb_b(cabac->slice, H264_MB_A, H264_BLOCK_8X8, 0, idx, &idxA);
+ const struct h264_macroblock *mbB = h264_mb_nb_b(cabac->slice, H264_MB_B, H264_BLOCK_8X8, 0, idx, &idxB);
+ int thrA, thrB;
+ thrA = (!mbT->mb_field_decoding_flag && mbA->mb_field_decoding_flag);
+ thrB = (!mbT->mb_field_decoding_flag && mbB->mb_field_decoding_flag);
+ int condTermFlagA = mbA->ref_idx[which][idxA] > thrA;
+ int condTermFlagB = mbB->ref_idx[which][idxB] > thrB;
+ int ctxIdx[3];
+ ctxIdx[0] = H264_CABAC_CTXIDX_REF_IDX + condTermFlagA + 2 * condTermFlagB;
+ ctxIdx[1] = H264_CABAC_CTXIDX_REF_IDX + 4;
+ ctxIdx[2] = H264_CABAC_CTXIDX_REF_IDX + 5;
+ return h264_cabac_tu(str, cabac, ctxIdx, 3, -1, val);
+}
+
+int h264_mvd(struct bitstream *str, struct h264_cabac_context *cabac, int idx, int comp, int which, int32_t *val) {
+ if (!cabac)
+ return vs_se(str, val);
+ int baseidx = (comp ? H264_CABAC_CTXIDX_MVD_Y : H264_CABAC_CTXIDX_MVD_X);
+ int idxA, idxB;
+ const struct h264_macroblock *mbT = h264_mb_nb(cabac->slice, H264_MB_THIS, 0);
+ const struct h264_macroblock *mbA = h264_mb_nb_b(cabac->slice, H264_MB_A, H264_BLOCK_4X4, 0, idx, &idxA);
+ const struct h264_macroblock *mbB = h264_mb_nb_b(cabac->slice, H264_MB_B, H264_BLOCK_4X4, 0, idx, &idxB);
+ int absMvdCompA = abs(mbA->mvd[which][idxA][comp]);
+ int absMvdCompB = abs(mbB->mvd[which][idxB][comp]);
+ if (comp) {
+ if (mbT->mb_field_decoding_flag && !mbA->mb_field_decoding_flag)
+ absMvdCompA /= 2;
+ if (!mbT->mb_field_decoding_flag && mbA->mb_field_decoding_flag)
+ absMvdCompA *= 2;
+ if (mbT->mb_field_decoding_flag && !mbB->mb_field_decoding_flag)
+ absMvdCompB /= 2;
+ if (!mbT->mb_field_decoding_flag && mbB->mb_field_decoding_flag)
+ absMvdCompB *= 2;
+ }
+ int sum = absMvdCompA + absMvdCompB;
+ int inc;
+ if (sum < 3)
+ inc = 0;
+ else if (sum <= 32)
+ inc = 1;
+ else
+ inc = 2;
+ int ctxIdx[5];
+ ctxIdx[0] = baseidx + inc;
+ ctxIdx[1] = baseidx + 3;
+ ctxIdx[2] = baseidx + 4;
+ ctxIdx[3] = baseidx + 5;
+ ctxIdx[4] = baseidx + 6;
+ return h264_cabac_ueg(str, cabac, ctxIdx, 5, 3, 1, 9, val);
+}
+
static const struct h264_macroblock *inter_filter(struct h264_slice *slice, const struct h264_macroblock *mb, int inter) {
if (!inter
&& slice->picparm->constrained_intra_pred_flag