int ff_generate_sliding_window_mmcos(H264Context *h, int first_slice) { MMCO mmco_temp[MAX_MMCO_COUNT], *mmco = first_slice ? h->mmco : mmco_temp; int mmco_index = 0, i; if (h->short_ref_count && h->long_ref_count + h->short_ref_count >= h->sps.ref_frame_count && !(FIELD_PICTURE(h) && !h->first_field && h->cur_pic_ptr->reference)) { mmco[0].opcode = MMCO_SHORT2UNUSED; mmco[0].short_pic_num = h->short_ref[h->short_ref_count - 1]->frame_num; mmco_index = 1; if (FIELD_PICTURE(h)) { mmco[0].short_pic_num *= 2; mmco[1].opcode = MMCO_SHORT2UNUSED; mmco[1].short_pic_num = mmco[0].short_pic_num + 1; mmco_index = 2; } } if (first_slice) { h->mmco_index = mmco_index; } else if (!first_slice && mmco_index >= 0 && (mmco_index != h->mmco_index || (i = check_opcodes(h->mmco, mmco_temp, mmco_index)))) { av_log(h->avctx, AV_LOG_ERROR, "Inconsistent MMCO state between slices [%d, %d]\n", mmco_index, h->mmco_index); return AVERROR_INVALIDDATA; } return 0; }
static void write_opcodes (void) { struct d10v_opcode *opcode; int i, j; /* write out opcode table */ printf ("#include \"d10v_sim.h\"\n"); printf ("#include \"simops.h\"\n\n"); printf ("struct simops Simops[] = {\n"); for (opcode = (struct d10v_opcode *)d10v_opcodes; opcode->name; opcode++) { if (opcode->format != OPCODE_FAKE) { printf (" { %ld,%d,%ld,%d,%d,%d,%d,OP_%lX,", opcode->opcode, (opcode->format & LONG_OPCODE) ? 1 : 0, opcode->mask, opcode->format, opcode->cycles, opcode->unit, opcode->exec_type, opcode->opcode); /* REMOVE ME */ check_opcodes (opcode->opcode); Opcodes[curop++] = opcode->opcode; j = 0; for (i=0;i<6;i++) { int flags = d10v_operands[opcode->operands[i]].flags; if ((flags & OPERAND_REG) || (flags & OPERAND_NUM) || (flags & OPERAND_ADDR)) j++; } printf ("%d,",j); j = 0; for (i=0;i<6;i++) { int flags = d10v_operands[opcode->operands[i]].flags; int shift = d10v_operands[opcode->operands[i]].shift; if ((flags & OPERAND_REG) || (flags & OPERAND_NUM)|| (flags & OPERAND_ADDR)) { if (j == 0) printf ("{"); else printf (", "); if ((flags & OPERAND_REG) && (opcode->format == LONG_L)) shift += 15; printf ("%d,%d,%d",shift,d10v_operands[opcode->operands[i]].bits,flags); j = 1; } } if (j) printf ("}"); printf ("},\n"); } } printf ("{ 0,0,0,0,0,0,0,(void (*)(void))0,0,{0,0,0}},\n};\n"); }
int ff_h264_decode_ref_pic_marking(H264Context *h, GetBitContext *gb, int first_slice) { int i, ret; MMCO mmco_temp[MAX_MMCO_COUNT], *mmco = mmco_temp; int mmco_index = 0; if (h->nal_unit_type == NAL_IDR_SLICE) { // FIXME fields skip_bits1(gb); // broken_link if (get_bits1(gb)) { mmco[0].opcode = MMCO_LONG; mmco[0].long_arg = 0; mmco_index = 1; } } else { if (get_bits1(gb)) { // adaptive_ref_pic_marking_mode_flag for (i = 0; i < MAX_MMCO_COUNT; i++) { MMCOOpcode opcode = get_ue_golomb_31(gb); mmco[i].opcode = opcode; if (opcode == MMCO_SHORT2UNUSED || opcode == MMCO_SHORT2LONG) { mmco[i].short_pic_num = (h->curr_pic_num - get_ue_golomb(gb) - 1) & (h->max_pic_num - 1); #if 0 if (mmco[i].short_pic_num >= h->short_ref_count || h->short_ref[ mmco[i].short_pic_num ] == NULL){ av_log(s->avctx, AV_LOG_ERROR, "illegal short ref in memory management control " "operation %d\n", mmco); return -1; } #endif } if (opcode == MMCO_SHORT2LONG || opcode == MMCO_LONG2UNUSED || opcode == MMCO_LONG || opcode == MMCO_SET_MAX_LONG) { unsigned int long_arg = get_ue_golomb_31(gb); if (long_arg >= 32 || (long_arg >= 16 && !(opcode == MMCO_SET_MAX_LONG && long_arg == 16) && !(opcode == MMCO_LONG2UNUSED && FIELD_PICTURE(h)))) { av_log(h->avctx, AV_LOG_ERROR, "illegal long ref in memory management control " "operation %d\n", opcode); return -1; } mmco[i].long_arg = long_arg; } if (opcode > (unsigned) MMCO_LONG) { av_log(h->avctx, AV_LOG_ERROR, "illegal memory management control operation %d\n", opcode); return -1; } if (opcode == MMCO_END) break; } mmco_index = i; } else { if (first_slice) { ret = ff_generate_sliding_window_mmcos(h, first_slice); if (ret < 0 && h->avctx->err_recognition & AV_EF_EXPLODE) return ret; } mmco_index = -1; } } if (first_slice && mmco_index != -1) { memcpy(h->mmco, mmco_temp, sizeof(h->mmco)); h->mmco_index = mmco_index; } else if (!first_slice && mmco_index >= 0 && (mmco_index != h->mmco_index || check_opcodes(h->mmco, mmco_temp, mmco_index))) { av_log(h->avctx, AV_LOG_ERROR, "Inconsistent MMCO state between slices [%d, %d]\n", mmco_index, h->mmco_index); return AVERROR_INVALIDDATA; } return 0; }