static av_always_inline void decode_line(FFV1Context *s, int w, int16_t *sample[2], int plane_index, int bits) { PlaneContext *const p = &s->plane[plane_index]; RangeCoder *const c = &s->c; int x; int run_count = 0; int run_mode = 0; int run_index = s->run_index; if (s->slice_coding_mode == 1) { int i; for (x = 0; x < w; x++) { int v = 0; for (i=0; i<bits; i++) { uint8_t state = 128; v += v + get_rac(c, &state); } sample[1][x] = v; } return; } for (x = 0; x < w; x++) { int diff, context, sign; context = get_context(p, sample[1] + x, sample[0] + x, sample[1] + x); if (context < 0) { context = -context; sign = 1; } else sign = 0; av_assert2(context < p->context_count); if (s->ac) { diff = get_symbol_inline(c, p->state[context], 1); } else { if (context == 0 && run_mode == 0) run_mode = 1; if (run_mode) { if (run_count == 0 && run_mode == 1) { if (get_bits1(&s->gb)) { run_count = 1 << ff_log2_run[run_index]; if (x + run_count <= w) run_index++; } else { if (ff_log2_run[run_index]) run_count = get_bits(&s->gb, ff_log2_run[run_index]); else run_count = 0; if (run_index) run_index--; run_mode = 2; } } run_count--; if (run_count < 0) { run_mode = 0; run_count = 0; diff = get_vlc_symbol(&s->gb, &p->vlc_state[context], bits); if (diff >= 0) diff++; } else diff = 0; } else diff = get_vlc_symbol(&s->gb, &p->vlc_state[context], bits); ff_dlog(s->avctx, "count:%d index:%d, mode:%d, x:%d pos:%d\n", run_count, run_index, run_mode, x, get_bits_count(&s->gb)); } if (sign) diff = -diff; sample[1][x] = av_mod_uintp2(predict(sample[1] + x, sample[0] + x) + diff, bits); } s->run_index = run_index; }
static av_always_inline int RENAME(decode_line)(FFV1Context *s, int w, TYPE *sample[2], int plane_index, int bits) { PlaneContext *const p = &s->plane[plane_index]; RangeCoder *const c = &s->c; int x; int run_count = 0; int run_mode = 0; int run_index = s->run_index; if (is_input_end(s)) return AVERROR_INVALIDDATA; if (s->slice_coding_mode == 1) { int i; for (x = 0; x < w; x++) { int v = 0; for (i=0; i<bits; i++) { uint8_t state = 128; v += v + get_rac(c, &state); } sample[1][x] = v; } return 0; } for (x = 0; x < w; x++) { int diff, context, sign; if (!(x & 1023)) { if (is_input_end(s)) return AVERROR_INVALIDDATA; } context = RENAME(get_context)(p, sample[1] + x, sample[0] + x, sample[1] + x); if (context < 0) { context = -context; sign = 1; } else sign = 0; av_assert2(context < p->context_count); if (s->ac != AC_GOLOMB_RICE) { diff = get_symbol_inline(c, p->state[context], 1); } else { if (context == 0 && run_mode == 0) run_mode = 1; if (run_mode) { if (run_count == 0 && run_mode == 1) { if (get_bits1(&s->gb)) { run_count = 1 << ff_log2_run[run_index]; if (x + run_count <= w) run_index++; } else { if (ff_log2_run[run_index]) run_count = get_bits(&s->gb, ff_log2_run[run_index]); else run_count = 0; if (run_index) run_index--; run_mode = 2; } } while (run_count > 1 && w-x > 1) { sample[1][x] = RENAME(predict)(sample[1] + x, sample[0] + x); x++; run_count--; } run_count--; if (run_count < 0) { run_mode = 0; run_count = 0; diff = get_vlc_symbol(&s->gb, &p->vlc_state[context], bits); if (diff >= 0) diff++; } else diff = 0; } else diff = get_vlc_symbol(&s->gb, &p->vlc_state[context], bits); ff_dlog(s->avctx, "count:%d index:%d, mode:%d, x:%d pos:%d\n", run_count, run_index, run_mode, x, get_bits_count(&s->gb)); } if (sign) diff = -(unsigned)diff; sample[1][x] = av_mod_uintp2(RENAME(predict)(sample[1] + x, sample[0] + x) + (SUINT)diff, bits); } s->run_index = run_index; return 0; }
int ff_h264_execute_ref_pic_marking(H264Context *h, MMCO *mmco, int mmco_count) { int i, av_uninit(j); int pps_count; int pps_ref_count[2] = {0}; int current_ref_assigned = 0, err = 0; H264Picture *av_uninit(pic); if ((h->avctx->debug & FF_DEBUG_MMCO) && mmco_count == 0) av_log(h->avctx, AV_LOG_DEBUG, "no mmco here\n"); for (i = 0; i < mmco_count; i++) { int av_uninit(structure), av_uninit(frame_num); if (h->avctx->debug & FF_DEBUG_MMCO) av_log(h->avctx, AV_LOG_DEBUG, "mmco:%d %d %d\n", h->mmco[i].opcode, h->mmco[i].short_pic_num, h->mmco[i].long_arg); if (mmco[i].opcode == MMCO_SHORT2UNUSED || mmco[i].opcode == MMCO_SHORT2LONG) { frame_num = pic_num_extract(h, mmco[i].short_pic_num, &structure); pic = find_short(h, frame_num, &j); if (!pic) { if (mmco[i].opcode != MMCO_SHORT2LONG || !h->long_ref[mmco[i].long_arg] || h->long_ref[mmco[i].long_arg]->frame_num != frame_num) { av_log(h->avctx, h->short_ref_count ? AV_LOG_ERROR : AV_LOG_DEBUG, "mmco: unref short failure\n"); err = AVERROR_INVALIDDATA; } continue; } } switch (mmco[i].opcode) { case MMCO_SHORT2UNUSED: if (h->avctx->debug & FF_DEBUG_MMCO) av_log(h->avctx, AV_LOG_DEBUG, "mmco: unref short %d count %d\n", h->mmco[i].short_pic_num, h->short_ref_count); remove_short(h, frame_num, structure ^ PICT_FRAME); break; case MMCO_SHORT2LONG: if (h->long_ref[mmco[i].long_arg] != pic) remove_long(h, mmco[i].long_arg, 0); remove_short_at_index(h, j); h->long_ref[ mmco[i].long_arg ] = pic; if (h->long_ref[mmco[i].long_arg]) { h->long_ref[mmco[i].long_arg]->long_ref = 1; h->long_ref_count++; } break; case MMCO_LONG2UNUSED: j = pic_num_extract(h, mmco[i].long_arg, &structure); pic = h->long_ref[j]; if (pic) { remove_long(h, j, structure ^ PICT_FRAME); } else if (h->avctx->debug & FF_DEBUG_MMCO) av_log(h->avctx, AV_LOG_DEBUG, "mmco: unref long failure\n"); break; case MMCO_LONG: // Comment below left from previous code as it is an interresting note. /* First field in pair is in short term list or * at a different long term index. * This is not allowed; see 7.4.3.3, notes 2 and 3. * Report the problem and keep the pair where it is, * and mark this field valid. */ if (h->short_ref[0] == h->cur_pic_ptr) { av_log(h->avctx, AV_LOG_ERROR, "mmco: cannot assign current picture to short and long at the same time\n"); remove_short_at_index(h, 0); } /* make sure the current picture is not already assigned as a long ref */ if (h->cur_pic_ptr->long_ref) { for (j = 0; j < FF_ARRAY_ELEMS(h->long_ref); j++) { if (h->long_ref[j] == h->cur_pic_ptr) { if (j != mmco[i].long_arg) av_log(h->avctx, AV_LOG_ERROR, "mmco: cannot assign current picture to 2 long term references\n"); remove_long(h, j, 0); } } } if (h->long_ref[mmco[i].long_arg] != h->cur_pic_ptr) { av_assert0(!h->cur_pic_ptr->long_ref); remove_long(h, mmco[i].long_arg, 0); h->long_ref[mmco[i].long_arg] = h->cur_pic_ptr; h->long_ref[mmco[i].long_arg]->long_ref = 1; h->long_ref_count++; } h->cur_pic_ptr->reference |= h->picture_structure; current_ref_assigned = 1; break; case MMCO_SET_MAX_LONG: assert(mmco[i].long_arg <= 16); // just remove the long term which index is greater than new max for (j = mmco[i].long_arg; j < 16; j++) { remove_long(h, j, 0); } break; case MMCO_RESET: while (h->short_ref_count) { remove_short(h, h->short_ref[0]->frame_num, 0); } for (j = 0; j < 16; j++) { remove_long(h, j, 0); } h->frame_num = h->cur_pic_ptr->frame_num = 0; h->mmco_reset = 1; h->cur_pic_ptr->mmco_reset = 1; for (j = 0; j < MAX_DELAYED_PIC_COUNT; j++) h->last_pocs[j] = INT_MIN; break; default: assert(0); } } if (!current_ref_assigned) { /* Second field of complementary field pair; the first field of * which is already referenced. If short referenced, it * should be first entry in short_ref. If not, it must exist * in long_ref; trying to put it on the short list here is an * error in the encoded bit stream (ref: 7.4.3.3, NOTE 2 and 3). */ if (h->short_ref_count && h->short_ref[0] == h->cur_pic_ptr) { /* Just mark the second field valid */ h->cur_pic_ptr->reference |= h->picture_structure; } else if (h->cur_pic_ptr->long_ref) { av_log(h->avctx, AV_LOG_ERROR, "illegal short term reference " "assignment for second field " "in complementary field pair " "(first field is long term)\n"); err = AVERROR_INVALIDDATA; } else { pic = remove_short(h, h->cur_pic_ptr->frame_num, 0); if (pic) { av_log(h->avctx, AV_LOG_ERROR, "illegal short term buffer state detected\n"); err = AVERROR_INVALIDDATA; } if (h->short_ref_count) memmove(&h->short_ref[1], &h->short_ref[0], h->short_ref_count * sizeof(H264Picture*)); h->short_ref[0] = h->cur_pic_ptr; h->short_ref_count++; h->cur_pic_ptr->reference |= h->picture_structure; } } if (h->long_ref_count + h->short_ref_count > FFMAX(h->sps.ref_frame_count, 1)) { /* We have too many reference frames, probably due to corrupted * stream. Need to discard one frame. Prevents overrun of the * short_ref and long_ref buffers. */ av_log(h->avctx, AV_LOG_ERROR, "number of reference frames (%d+%d) exceeds max (%d; probably " "corrupt input), discarding one\n", h->long_ref_count, h->short_ref_count, h->sps.ref_frame_count); err = AVERROR_INVALIDDATA; if (h->long_ref_count && !h->short_ref_count) { for (i = 0; i < 16; ++i) if (h->long_ref[i]) break; assert(i < 16); remove_long(h, i, 0); } else { pic = h->short_ref[h->short_ref_count - 1]; remove_short(h, pic->frame_num, 0); } } for (i = 0; i<h->short_ref_count; i++) { pic = h->short_ref[i]; if (pic->invalid_gap) { int d = av_mod_uintp2(h->cur_pic_ptr->frame_num - pic->frame_num, h->sps.log2_max_frame_num); if (d > h->sps.ref_frame_count) remove_short(h, pic->frame_num, 0); } } print_short_term(h); print_long_term(h); pps_count = 0; for (i = 0; i < FF_ARRAY_ELEMS(h->pps_buffers); i++) { pps_count += !!h->pps_buffers[i]; pps_ref_count[0] = FFMAX(pps_ref_count[0], h->pps.ref_count[0]); pps_ref_count[1] = FFMAX(pps_ref_count[1], h->pps.ref_count[1]); } if ( err >= 0 && h->long_ref_count==0 && ( h->short_ref_count<=2 || pps_ref_count[0] <= 1 + (h->picture_structure != PICT_FRAME) && pps_ref_count[1] <= 1) && pps_ref_count[0]<=2 + (h->picture_structure != PICT_FRAME) + (2*!h->has_recovery_point) && h->cur_pic_ptr->f->pict_type == AV_PICTURE_TYPE_I){ h->cur_pic_ptr->recovered |= 1; if(!h->avctx->has_b_frames) h->frame_recovered |= FRAME_RECOVERED_SEI; } return (h->avctx->err_recognition & AV_EF_EXPLODE) ? err : 0; }
static av_always_inline void FUNC(intra_pred)(HEVCContext *s, int x0, int y0, int log2_size, int c_idx) { #define PU(x) \ ((x) >> s->ps.sps->log2_min_pu_size) #define MVF(x, y) \ (s->ref->tab_mvf[(x) + (y) * min_pu_width]) #define MVF_PU(x, y) \ MVF(PU(x0 + ((x) << hshift)), PU(y0 + ((y) << vshift))) #define IS_INTRA(x, y) \ (MVF_PU(x, y).pred_flag == PF_INTRA) #define MIN_TB_ADDR_ZS(x, y) \ s->ps.pps->min_tb_addr_zs[(y) * (s->ps.sps->tb_mask+2) + (x)] #define EXTEND(ptr, val, len) \ do { \ pixel4 pix = PIXEL_SPLAT_X4(val); \ for (i = 0; i < (len); i += 4) \ AV_WN4P(ptr + i, pix); \ } while (0) #define EXTEND_RIGHT_CIP(ptr, start, length) \ for (i = start; i < (start) + (length); i += 4) \ if (!IS_INTRA(i, -1)) \ AV_WN4P(&ptr[i], a); \ else \ a = PIXEL_SPLAT_X4(ptr[i+3]) #define EXTEND_LEFT_CIP(ptr, start, length) \ for (i = start; i > (start) - (length); i--) \ if (!IS_INTRA(i - 1, -1)) \ ptr[i - 1] = ptr[i] #define EXTEND_UP_CIP(ptr, start, length) \ for (i = (start); i > (start) - (length); i -= 4) \ if (!IS_INTRA(-1, i - 3)) \ AV_WN4P(&ptr[i - 3], a); \ else \ a = PIXEL_SPLAT_X4(ptr[i - 3]) #define EXTEND_DOWN_CIP(ptr, start, length) \ for (i = start; i < (start) + (length); i += 4) \ if (!IS_INTRA(-1, i)) \ AV_WN4P(&ptr[i], a); \ else \ a = PIXEL_SPLAT_X4(ptr[i + 3]) HEVCLocalContext *lc = s->HEVClc; int i; int hshift = s->ps.sps->hshift[c_idx]; int vshift = s->ps.sps->vshift[c_idx]; int size = (1 << log2_size); int size_in_luma_h = size << hshift; int size_in_tbs_h = size_in_luma_h >> s->ps.sps->log2_min_tb_size; int size_in_luma_v = size << vshift; int size_in_tbs_v = size_in_luma_v >> s->ps.sps->log2_min_tb_size; int x = x0 >> hshift; int y = y0 >> vshift; int x_tb = (x0 >> s->ps.sps->log2_min_tb_size) & s->ps.sps->tb_mask; int y_tb = (y0 >> s->ps.sps->log2_min_tb_size) & s->ps.sps->tb_mask; int cur_tb_addr = MIN_TB_ADDR_ZS(x_tb, y_tb); ptrdiff_t stride = s->frame->linesize[c_idx] / sizeof(pixel); pixel *src = (pixel*)s->frame->data[c_idx] + x + y * stride; int min_pu_width = s->ps.sps->min_pu_width; enum IntraPredMode mode = c_idx ? lc->tu.intra_pred_mode_c : lc->tu.intra_pred_mode; pixel4 a; pixel left_array[2 * MAX_TB_SIZE + 1]; pixel filtered_left_array[2 * MAX_TB_SIZE + 1]; pixel top_array[2 * MAX_TB_SIZE + 1]; pixel filtered_top_array[2 * MAX_TB_SIZE + 1]; pixel *left = left_array + 1; pixel *top = top_array + 1; pixel *filtered_left = filtered_left_array + 1; pixel *filtered_top = filtered_top_array + 1; int cand_bottom_left = lc->na.cand_bottom_left && cur_tb_addr > MIN_TB_ADDR_ZS( x_tb - 1, (y_tb + size_in_tbs_v) & s->ps.sps->tb_mask); int cand_left = lc->na.cand_left; int cand_up_left = lc->na.cand_up_left; int cand_up = lc->na.cand_up; int cand_up_right = lc->na.cand_up_right && cur_tb_addr > MIN_TB_ADDR_ZS((x_tb + size_in_tbs_h) & s->ps.sps->tb_mask, y_tb - 1); int bottom_left_size = (FFMIN(y0 + 2 * size_in_luma_v, s->ps.sps->height) - (y0 + size_in_luma_v)) >> vshift; int top_right_size = (FFMIN(x0 + 2 * size_in_luma_h, s->ps.sps->width) - (x0 + size_in_luma_h)) >> hshift; if (s->ps.pps->constrained_intra_pred_flag == 1) { int size_in_luma_pu_v = PU(size_in_luma_v); int size_in_luma_pu_h = PU(size_in_luma_h); int on_pu_edge_x = !av_mod_uintp2(x0, s->ps.sps->log2_min_pu_size); int on_pu_edge_y = !av_mod_uintp2(y0, s->ps.sps->log2_min_pu_size); if (!size_in_luma_pu_h) size_in_luma_pu_h++; if (cand_bottom_left == 1 && on_pu_edge_x) { int x_left_pu = PU(x0 - 1); int y_bottom_pu = PU(y0 + size_in_luma_v); int max = FFMIN(size_in_luma_pu_v, s->ps.sps->min_pu_height - y_bottom_pu); cand_bottom_left = 0; for (i = 0; i < max; i += 2) cand_bottom_left |= (MVF(x_left_pu, y_bottom_pu + i).pred_flag == PF_INTRA); } if (cand_left == 1 && on_pu_edge_x) { int x_left_pu = PU(x0 - 1); int y_left_pu = PU(y0); int max = FFMIN(size_in_luma_pu_v, s->ps.sps->min_pu_height - y_left_pu); cand_left = 0; for (i = 0; i < max; i += 2) cand_left |= (MVF(x_left_pu, y_left_pu + i).pred_flag == PF_INTRA); } if (cand_up_left == 1) { int x_left_pu = PU(x0 - 1); int y_top_pu = PU(y0 - 1); cand_up_left = MVF(x_left_pu, y_top_pu).pred_flag == PF_INTRA; } if (cand_up == 1 && on_pu_edge_y) { int x_top_pu = PU(x0); int y_top_pu = PU(y0 - 1); int max = FFMIN(size_in_luma_pu_h, s->ps.sps->min_pu_width - x_top_pu); cand_up = 0; for (i = 0; i < max; i += 2) cand_up |= (MVF(x_top_pu + i, y_top_pu).pred_flag == PF_INTRA); } if (cand_up_right == 1 && on_pu_edge_y) { int y_top_pu = PU(y0 - 1); int x_right_pu = PU(x0 + size_in_luma_h); int max = FFMIN(size_in_luma_pu_h, s->ps.sps->min_pu_width - x_right_pu); cand_up_right = 0; for (i = 0; i < max; i += 2) cand_up_right |= (MVF(x_right_pu + i, y_top_pu).pred_flag == PF_INTRA); } memset(left, 128, 2 * MAX_TB_SIZE*sizeof(pixel)); memset(top , 128, 2 * MAX_TB_SIZE*sizeof(pixel)); top[-1] = 128; } if (cand_up_left) { left[-1] = POS(-1, -1); top[-1] = left[-1]; } if (cand_up) memcpy(top, src - stride, size * sizeof(pixel)); if (cand_up_right) { memcpy(top + size, src - stride + size, size * sizeof(pixel)); EXTEND(top + size + top_right_size, POS(size + top_right_size - 1, -1), size - top_right_size); } if (cand_left) for (i = 0; i < size; i++) left[i] = POS(-1, i); if (cand_bottom_left) { for (i = size; i < size + bottom_left_size; i++) left[i] = POS(-1, i); EXTEND(left + size + bottom_left_size, POS(-1, size + bottom_left_size - 1), size - bottom_left_size); } if (s->ps.pps->constrained_intra_pred_flag == 1) { if (cand_bottom_left || cand_left || cand_up_left || cand_up || cand_up_right) { int size_max_x = x0 + ((2 * size) << hshift) < s->ps.sps->width ? 2 * size : (s->ps.sps->width - x0) >> hshift; int size_max_y = y0 + ((2 * size) << vshift) < s->ps.sps->height ? 2 * size : (s->ps.sps->height - y0) >> vshift; int j = size + (cand_bottom_left? bottom_left_size: 0) -1; if (!cand_up_right) { size_max_x = x0 + ((size) << hshift) < s->ps.sps->width ? size : (s->ps.sps->width - x0) >> hshift; } if (!cand_bottom_left) { size_max_y = y0 + (( size) << vshift) < s->ps.sps->height ? size : (s->ps.sps->height - y0) >> vshift; }