static int encode_slices(VC2EncContext *s) { uint8_t *buf; int i, slice_x, slice_y, skip = 0; int bytes_left = 0; SliceArgs *enc_args = s->slice_args; int bytes_top[SLICE_REDIST_TOTAL] = {0}; SliceArgs *top_loc[SLICE_REDIST_TOTAL] = {NULL}; avpriv_align_put_bits(&s->pb); flush_put_bits(&s->pb); buf = put_bits_ptr(&s->pb); for (slice_y = 0; slice_y < s->num_y; slice_y++) { for (slice_x = 0; slice_x < s->num_x; slice_x++) { SliceArgs *args = &enc_args[s->num_x*slice_y + slice_x]; bytes_left += args->bytes_left; for (i = 0; i < FFMIN(SLICE_REDIST_TOTAL, s->num_x*s->num_y); i++) { if (args->bytes > bytes_top[i]) { bytes_top[i] = args->bytes; top_loc[i] = args; break; } } } } while (1) { int distributed = 0; for (i = 0; i < FFMIN(SLICE_REDIST_TOTAL, s->num_x*s->num_y); i++) { SliceArgs *args; int bits, bytes, diff, prev_bytes, new_idx; if (bytes_left <= 0) break; if (!top_loc[i] || !top_loc[i]->quant_idx) break; args = top_loc[i]; prev_bytes = args->bytes; new_idx = av_clip(args->quant_idx - 1, 0, s->q_ceil); bits = count_hq_slice(s, args->cache, args->x, args->y, new_idx); bytes = FFALIGN((bits >> 3), s->size_scaler) + 4 + s->prefix_bytes; diff = bytes - prev_bytes; if ((bytes_left - diff) >= 0) { args->quant_idx = new_idx; args->bytes = bytes; bytes_left -= diff; distributed++; } } if (!distributed) break; } for (slice_y = 0; slice_y < s->num_y; slice_y++) { for (slice_x = 0; slice_x < s->num_x; slice_x++) { SliceArgs *args = &enc_args[s->num_x*slice_y + slice_x]; init_put_bits(&args->pb, buf + skip, args->bytes); s->q_avg = (s->q_avg + args->quant_idx)/2; skip += args->bytes; } } s->avctx->execute(s->avctx, encode_hq_slice, enc_args, NULL, s->num_x*s->num_y, sizeof(SliceArgs)); skip_put_bytes(&s->pb, skip); return 0; }