return 0;
}
-static int dnxhd_rc_cmp(const void *a, const void *b)
+#define BUCKET_BITS 8
+#define RADIX_PASSES 4
+#define NBUCKETS (1 << BUCKET_BITS)
+
+static inline int get_bucket(int value, int shift)
+{
+ value >>= shift;
+ value &= NBUCKETS - 1;
+ return NBUCKETS - 1 - value;
+}
+
+static void radix_count(const RCCMPEntry *data, int size, int buckets[RADIX_PASSES][NBUCKETS])
+{
+ int i, j;
+ memset(buckets, 0, sizeof(buckets[0][0]) * RADIX_PASSES * NBUCKETS);
+ for (i = 0; i < size; i++) {
+ int v = data[i].value;
+ for (j = 0; j < RADIX_PASSES; j++) {
+ buckets[j][get_bucket(v, 0)]++;
+ v >>= BUCKET_BITS;
+ }
+ assert(!v);
+ }
+ for (j = 0; j < RADIX_PASSES; j++) {
+ int offset = size;
+ for (i = NBUCKETS - 1; i >= 0; i--)
+ buckets[j][i] = offset -= buckets[j][i];
+ assert(!buckets[j][0]);
+ }
+}
+
+static void radix_sort_pass(RCCMPEntry *dst, const RCCMPEntry *data, int size, int buckets[NBUCKETS], int pass)
+{
+ int shift = pass * BUCKET_BITS;
+ int i;
+ for (i = 0; i < size; i++) {
+ int v = get_bucket(data[i].value, shift);
+ int pos = buckets[v]++;
+ dst[pos] = data[i];
+ }
+}
+
+static void radix_sort(RCCMPEntry *data, int size)
{
- return ((const RCCMPEntry *)b)->value - ((const RCCMPEntry *)a)->value;
+ int buckets[RADIX_PASSES][NBUCKETS];
+ RCCMPEntry *tmp = av_malloc(sizeof(*tmp) * size);
+ radix_count(data, size, buckets);
+ radix_sort_pass(tmp, data, size, buckets[0], 0);
+ radix_sort_pass(data, tmp, size, buckets[1], 1);
+ if (buckets[2][NBUCKETS - 1] || buckets[3][NBUCKETS - 1]) {
+ radix_sort_pass(tmp, data, size, buckets[2], 2);
+ radix_sort_pass(data, tmp, size, buckets[3], 3);
+ }
+ av_free(tmp);
}
static int dnxhd_encode_fast(AVCodecContext *avctx, DNXHDEncContext *ctx)
if (!ret) {
if (RC_VARIANCE)
avctx->execute(avctx, dnxhd_mb_var_thread, (void**)&ctx->thread[0], NULL, avctx->thread_count, sizeof(void*));
- qsort(ctx->mb_cmp, ctx->m.mb_num, sizeof(RCEntry), dnxhd_rc_cmp);
+ radix_sort(ctx->mb_cmp, ctx->m.mb_num);
for (x = 0; x < ctx->m.mb_num && max_bits > ctx->frame_bits; x++) {
int mb = ctx->mb_cmp[x].mb;
max_bits -= ctx->mb_rc[ctx->qscale][mb].bits - ctx->mb_rc[ctx->qscale+1][mb].bits;