]> git.sesse.net Git - ffmpeg/blobdiff - libavcodec/flacenc.c
cosmetics: rename find_subblock_rice_params() to find_subframe_rice_params()
[ffmpeg] / libavcodec / flacenc.c
index b23d3a6c9797c5abe02a974fe5c5b70a669ea6ee..ea3dbe8dc2f7e85780e3c27da44bb8852aae5db7 100644 (file)
@@ -77,6 +77,7 @@ typedef struct FlacFrame {
     int bs_code[2];
     uint8_t crc8;
     int ch_mode;
+    int verbatim_only;
 } FlacFrame;
 
 typedef struct FlacEncodeContext {
@@ -472,6 +473,8 @@ static void init_frame(FlacEncodeContext *s)
 
     for (ch = 0; ch < s->channels; ch++)
         frame->subframes[ch].obits = 16;
+
+    frame->verbatim_only = 0;
 }
 
 
@@ -603,39 +606,23 @@ static int get_max_p_order(int max_porder, int n, int order)
 }
 
 
-static uint32_t calc_rice_params_fixed(RiceContext *rc, int pmin, int pmax,
-                                       int32_t *data, int n, int pred_order,
-                                       int bps)
-{
-    uint32_t bits;
-    pmin  = get_max_p_order(pmin, n, pred_order);
-    pmax  = get_max_p_order(pmax, n, pred_order);
-    bits  = pred_order * bps + 6;
-    bits += calc_rice_params(rc, pmin, pmax, data, n, pred_order);
-    return bits;
-}
-
-
-static uint32_t calc_rice_params_lpc(RiceContext *rc, int pmin, int pmax,
-                                     int32_t *data, int n, int pred_order,
-                                     int bps, int precision)
+static uint32_t find_subframe_rice_params(FlacEncodeContext *s,
+                                          FlacSubframe *sub, int pred_order)
 {
-    uint32_t bits;
-    pmin  = get_max_p_order(pmin, n, pred_order);
-    pmax  = get_max_p_order(pmax, n, pred_order);
-    bits  = pred_order*bps + 4 + 5 + pred_order*precision + 6;
-    bits += calc_rice_params(rc, pmin, pmax, data, n, pred_order);
+    int pmin = get_max_p_order(s->options.min_partition_order,
+                               s->frame.blocksize, pred_order);
+    int pmax = get_max_p_order(s->options.max_partition_order,
+                               s->frame.blocksize, pred_order);
+
+    uint32_t bits = 8 + pred_order * sub->obits + 2 + 4;
+    if (sub->type == FLAC_SUBFRAME_LPC)
+        bits += 4 + 5 + pred_order * s->options.lpc_coeff_precision;
+    bits += calc_rice_params(&sub->rc, pmin, pmax, sub->residual,
+                             s->frame.blocksize, pred_order);
     return bits;
 }
 
 
-static void encode_residual_verbatim(int32_t *res, int32_t *smp, int n)
-{
-    assert(n > 0);
-    memcpy(res, smp, n * sizeof(int32_t));
-}
-
-
 static void encode_residual_fixed(int32_t *res, const int32_t *smp, int n,
                                   int order)
 {
@@ -791,18 +778,17 @@ static void encode_residual_lpc(int32_t *res, const int32_t *smp, int n,
 }
 
 
-static int encode_residual(FlacEncodeContext *ctx, int ch)
+static int encode_residual_ch(FlacEncodeContext *s, int ch)
 {
     int i, n;
-    int min_order, max_order, opt_order, precision, omethod;
-    int min_porder, max_porder;
+    int min_order, max_order, opt_order, omethod;
     FlacFrame *frame;
     FlacSubframe *sub;
     int32_t coefs[MAX_LPC_ORDER][MAX_LPC_ORDER];
     int shift[MAX_LPC_ORDER];
     int32_t *res, *smp;
 
-    frame = &ctx->frame;
+    frame = &s->frame;
     sub   = &frame->subframes[ch];
     res   = sub->residual;
     smp   = sub->samples;
@@ -819,22 +805,20 @@ static int encode_residual(FlacEncodeContext *ctx, int ch)
     }
 
     /* VERBATIM */
-    if (n < 5) {
+    if (frame->verbatim_only || n < 5) {
         sub->type = sub->type_code = FLAC_SUBFRAME_VERBATIM;
-        encode_residual_verbatim(res, smp, n);
+        memcpy(res, smp, n * sizeof(int32_t));
         return sub->obits * n;
     }
 
-    min_order  = ctx->options.min_prediction_order;
-    max_order  = ctx->options.max_prediction_order;
-    min_porder = ctx->options.min_partition_order;
-    max_porder = ctx->options.max_partition_order;
-    precision  = ctx->options.lpc_coeff_precision;
-    omethod    = ctx->options.prediction_order_method;
+    min_order  = s->options.min_prediction_order;
+    max_order  = s->options.max_prediction_order;
+    omethod    = s->options.prediction_order_method;
 
     /* FIXED */
-    if (ctx->options.lpc_type == AV_LPC_TYPE_NONE  ||
-        ctx->options.lpc_type == AV_LPC_TYPE_FIXED || n <= max_order) {
+    sub->type = FLAC_SUBFRAME_FIXED;
+    if (s->options.lpc_type == AV_LPC_TYPE_NONE  ||
+        s->options.lpc_type == AV_LPC_TYPE_FIXED || n <= max_order) {
         uint32_t bits[MAX_FIXED_ORDER+1];
         if (max_order > MAX_FIXED_ORDER)
             max_order = MAX_FIXED_ORDER;
@@ -842,26 +826,24 @@ static int encode_residual(FlacEncodeContext *ctx, int ch)
         bits[0]   = UINT32_MAX;
         for (i = min_order; i <= max_order; i++) {
             encode_residual_fixed(res, smp, n, i);
-            bits[i] = calc_rice_params_fixed(&sub->rc, min_porder, max_porder, res,
-                                             n, i, sub->obits);
+            bits[i] = find_subframe_rice_params(s, sub, i);
             if (bits[i] < bits[opt_order])
                 opt_order = i;
         }
         sub->order     = opt_order;
-        sub->type      = FLAC_SUBFRAME_FIXED;
         sub->type_code = sub->type | sub->order;
         if (sub->order != max_order) {
             encode_residual_fixed(res, smp, n, sub->order);
-            return calc_rice_params_fixed(&sub->rc, min_porder, max_porder, res, n,
-                                          sub->order, sub->obits);
+            return find_subframe_rice_params(s, sub, sub->order);
         }
         return bits[sub->order];
     }
 
     /* LPC */
-    opt_order = ff_lpc_calc_coefs(&ctx->dsp, smp, n, min_order, max_order,
-                                  precision, coefs, shift, ctx->options.lpc_type,
-                                  ctx->options.lpc_passes, omethod,
+    sub->type = FLAC_SUBFRAME_LPC;
+    opt_order = ff_lpc_calc_coefs(&s->dsp, smp, n, min_order, max_order,
+                                  s->options.lpc_coeff_precision, coefs, shift, s->options.lpc_type,
+                                  s->options.lpc_passes, omethod,
                                   MAX_LPC_SHIFT, 0);
 
     if (omethod == ORDER_METHOD_2LEVEL ||
@@ -878,8 +860,7 @@ static int encode_residual(FlacEncodeContext *ctx, int ch)
             if (order < 0)
                 order = 0;
             encode_residual_lpc(res, smp, n, order+1, coefs[order], shift[order]);
-            bits[i] = calc_rice_params_lpc(&sub->rc, min_porder, max_porder,
-                                           res, n, order+1, sub->obits, precision);
+            bits[i] = find_subframe_rice_params(s, sub, order+1);
             if (bits[i] < bits[opt_index]) {
                 opt_index = i;
                 opt_order = order;
@@ -893,8 +874,7 @@ static int encode_residual(FlacEncodeContext *ctx, int ch)
         bits[0]   = UINT32_MAX;
         for (i = min_order-1; i < max_order; i++) {
             encode_residual_lpc(res, smp, n, i+1, coefs[i], shift[i]);
-            bits[i] = calc_rice_params_lpc(&sub->rc, min_porder, max_porder,
-                                           res, n, i+1, sub->obits, precision);
+            bits[i] = find_subframe_rice_params(s, sub, i+1);
             if (bits[i] < bits[opt_order])
                 opt_order = i;
         }
@@ -912,9 +892,7 @@ static int encode_residual(FlacEncodeContext *ctx, int ch)
                 if (i < min_order-1 || i >= max_order || bits[i] < UINT32_MAX)
                     continue;
                 encode_residual_lpc(res, smp, n, i+1, coefs[i], shift[i]);
-                bits[i] = calc_rice_params_lpc(&sub->rc, min_porder, max_porder,
-                                               res, n, i+1, sub->obits,
-                                               precision);
+                bits[i] = find_subframe_rice_params(s, sub, i+1);
                 if (bits[i] < bits[opt_order])
                     opt_order = i;
             }
@@ -923,7 +901,6 @@ static int encode_residual(FlacEncodeContext *ctx, int ch)
     }
 
     sub->order     = opt_order;
-    sub->type      = FLAC_SUBFRAME_LPC;
     sub->type_code = sub->type | (sub->order-1);
     sub->shift     = shift[sub->order-1];
     for (i = 0; i < sub->order; i++)
@@ -931,38 +908,59 @@ static int encode_residual(FlacEncodeContext *ctx, int ch)
 
     encode_residual_lpc(res, smp, n, sub->order, sub->coefs, sub->shift);
 
-    return calc_rice_params_lpc(&sub->rc, min_porder, max_porder, res, n,
-                                sub->order, sub->obits, precision);
+    return find_subframe_rice_params(s, sub, sub->order);
 }
 
 
-static int encode_residual_v(FlacEncodeContext *ctx, int ch)
+static int count_frame_header(FlacEncodeContext *s)
 {
-    int i, n;
-    FlacFrame *frame;
-    FlacSubframe *sub;
-    int32_t *res, *smp;
+    uint8_t tmp;
+    int count;
+
+    /*
+    <14> Sync code
+    <1>  Reserved
+    <1>  Blocking strategy
+    <4>  Block size in inter-channel samples
+    <4>  Sample rate
+    <4>  Channel assignment
+    <3>  Sample size in bits
+    <1>  Reserved
+    */
+    count = 32;
+
+    /* coded frame number */
+    PUT_UTF8(s->frame_count, tmp, count += 8;)
+
+    /* explicit block size */
+    if (s->frame.bs_code[0] == 6)
+        count += 8;
+    else if (s->frame.bs_code[0] == 7)
+        count += 16;
+
+    /* explicit sample rate */
+    count += ((s->sr_code[0] == 12) + (s->sr_code[0] > 12)) * 8;
+
+    /* frame header CRC-8 */
+    count += 8;
+
+    return count;
+}
 
-    frame = &ctx->frame;
-    sub   = &frame->subframes[ch];
-    res   = sub->residual;
-    smp   = sub->samples;
-    n     = frame->blocksize;
 
-    /* CONSTANT */
-    for (i = 1; i < n; i++)
-        if (smp[i] != smp[0])
-            break;
-    if (i == n) {
-        sub->type = sub->type_code = FLAC_SUBFRAME_CONSTANT;
-        res[0]    = smp[0];
-        return sub->obits;
-    }
+static int encode_frame(FlacEncodeContext *s)
+{
+    int ch, count;
 
-    /* VERBATIM */
-    sub->type = sub->type_code = FLAC_SUBFRAME_VERBATIM;
-    encode_residual_verbatim(res, smp, n);
-    return sub->obits * n;
+    count = count_frame_header(s);
+
+    for (ch = 0; ch < s->channels; ch++)
+        count += encode_residual_ch(s, ch);
+
+    count += (8 - (count & 7)) & 7; // byte alignment
+    count += 16;                    // CRC-16
+
+    return count >> 3;
 }
 
 
@@ -1016,18 +1014,18 @@ static int estimate_stereo_mode(int32_t *left_ch, int32_t *right_ch, int n)
 /**
  * Perform stereo channel decorrelation.
  */
-static void channel_decorrelation(FlacEncodeContext *ctx)
+static void channel_decorrelation(FlacEncodeContext *s)
 {
     FlacFrame *frame;
     int32_t *left, *right;
     int i, n;
 
-    frame = &ctx->frame;
+    frame = &s->frame;
     n     = frame->blocksize;
     left  = frame->subframes[0].samples;
     right = frame->subframes[1].samples;
 
-    if (ctx->channels != 2) {
+    if (s->channels != 2) {
         frame->ch_mode = FLAC_CHMODE_INDEPENDENT;
         return;
     }
@@ -1101,123 +1099,16 @@ static void output_frame_header(FlacEncodeContext *s)
 }
 
 
-static void output_subframe_constant(FlacEncodeContext *s, int ch)
-{
-    FlacSubframe *sub;
-    int32_t res;
-
-    sub = &s->frame.subframes[ch];
-    res = sub->residual[0];
-    put_sbits(&s->pb, sub->obits, res);
-}
-
-
-static void output_subframe_verbatim(FlacEncodeContext *s, int ch)
-{
-    int i;
-    FlacFrame *frame;
-    FlacSubframe *sub;
-    int32_t res;
-
-    frame = &s->frame;
-    sub   = &frame->subframes[ch];
-
-    for (i = 0; i < frame->blocksize; i++) {
-        res = sub->residual[i];
-        put_sbits(&s->pb, sub->obits, res);
-    }
-}
-
-
-static void output_residual(FlacEncodeContext *ctx, int ch)
-{
-    int i, j, p, n, parts;
-    int k, porder, psize, res_cnt;
-    FlacFrame *frame;
-    FlacSubframe *sub;
-    int32_t *res;
-
-    frame = &ctx->frame;
-    sub   = &frame->subframes[ch];
-    res   = sub->residual;
-    n     = frame->blocksize;
-
-    /* rice-encoded block */
-    put_bits(&ctx->pb, 2, 0);
-
-    /* partition order */
-    porder  = sub->rc.porder;
-    psize   = n >> porder;
-    parts   = (1 << porder);
-    put_bits(&ctx->pb, 4, porder);
-    res_cnt = psize - sub->order;
-
-    /* residual */
-    j = sub->order;
-    for (p = 0; p < parts; p++) {
-        k = sub->rc.params[p];
-        put_bits(&ctx->pb, 4, k);
-        if (p == 1)
-            res_cnt = psize;
-        for (i = 0; i < res_cnt && j < n; i++, j++)
-            set_sr_golomb_flac(&ctx->pb, res[j], k, INT32_MAX, 0);
-    }
-}
-
-
-static void output_subframe_fixed(FlacEncodeContext *ctx, int ch)
-{
-    int i;
-    FlacFrame *frame;
-    FlacSubframe *sub;
-
-    frame = &ctx->frame;
-    sub   = &frame->subframes[ch];
-
-    /* warm-up samples */
-    for (i = 0; i < sub->order; i++)
-        put_sbits(&ctx->pb, sub->obits, sub->residual[i]);
-
-    /* residual */
-    output_residual(ctx, ch);
-}
-
-
-static void output_subframe_lpc(FlacEncodeContext *ctx, int ch)
-{
-    int i, cbits;
-    FlacFrame *frame;
-    FlacSubframe *sub;
-
-    frame = &ctx->frame;
-    sub = &frame->subframes[ch];
-
-    /* warm-up samples */
-    for (i = 0; i < sub->order; i++)
-        put_sbits(&ctx->pb, sub->obits, sub->residual[i]);
-
-    /* LPC coefficients */
-    cbits = ctx->options.lpc_coeff_precision;
-    put_bits( &ctx->pb, 4, cbits-1);
-    put_sbits(&ctx->pb, 5, sub->shift);
-    for (i = 0; i < sub->order; i++)
-        put_sbits(&ctx->pb, cbits, sub->coefs[i]);
-
-    /* residual */
-    output_residual(ctx, ch);
-}
-
-
 static void output_subframes(FlacEncodeContext *s)
 {
-    FlacFrame *frame;
-    FlacSubframe *sub;
     int ch;
 
-    frame = &s->frame;
-
     for (ch = 0; ch < s->channels; ch++) {
-        sub = &frame->subframes[ch];
+        FlacSubframe *sub = &s->frame.subframes[ch];
+        int i, p, porder, psize;
+        int32_t *part_end;
+        int32_t *res       =  sub->residual;
+        int32_t *frame_end = &sub->residual[s->frame.blocksize];
 
         /* subframe header */
         put_bits(&s->pb, 1, 0);
@@ -1225,14 +1116,43 @@ static void output_subframes(FlacEncodeContext *s)
         put_bits(&s->pb, 1, 0); /* no wasted bits */
 
         /* subframe */
-        if(sub->type == FLAC_SUBFRAME_CONSTANT)
-            output_subframe_constant(s, ch);
-        else if(sub->type == FLAC_SUBFRAME_VERBATIM)
-            output_subframe_verbatim(s, ch);
-        else if(sub->type == FLAC_SUBFRAME_FIXED)
-            output_subframe_fixed(s, ch);
-        else if(sub->type == FLAC_SUBFRAME_LPC)
-            output_subframe_lpc(s, ch);
+        if (sub->type == FLAC_SUBFRAME_CONSTANT) {
+            put_sbits(&s->pb, sub->obits, res[0]);
+        } else if (sub->type == FLAC_SUBFRAME_VERBATIM) {
+            while (res < frame_end)
+                put_sbits(&s->pb, sub->obits, *res++);
+        } else {
+            /* warm-up samples */
+            for (i = 0; i < sub->order; i++)
+                put_sbits(&s->pb, sub->obits, *res++);
+
+            /* LPC coefficients */
+            if (sub->type == FLAC_SUBFRAME_LPC) {
+                int cbits = s->options.lpc_coeff_precision;
+                put_bits( &s->pb, 4, cbits-1);
+                put_sbits(&s->pb, 5, sub->shift);
+                for (i = 0; i < sub->order; i++)
+                    put_sbits(&s->pb, cbits, sub->coefs[i]);
+            }
+
+            /* rice-encoded block */
+            put_bits(&s->pb, 2, 0);
+
+            /* partition order */
+            porder  = sub->rc.porder;
+            psize   = s->frame.blocksize >> porder;
+            put_bits(&s->pb, 4, porder);
+
+            /* residual */
+            part_end  = &sub->residual[psize];
+            for (p = 0; p < 1 << porder; p++) {
+                int k = sub->rc.params[p];
+                put_bits(&s->pb, 4, k);
+                while (res < part_end)
+                    set_sr_golomb_flac(&s->pb, *res++, k, INT32_MAX, 0);
+                part_end = FFMIN(frame_end, part_end + psize);
+            }
+        }
     }
 }
 
@@ -1248,6 +1168,16 @@ static void output_frame_footer(FlacEncodeContext *s)
 }
 
 
+static int write_frame(FlacEncodeContext *s, uint8_t *frame, int buf_size)
+{
+    init_put_bits(&s->pb, frame, buf_size);
+    output_frame_header(s);
+    output_subframes(s);
+    output_frame_footer(s);
+    return put_bits_count(&s->pb) >> 3;
+}
+
+
 static void update_md5_sum(FlacEncodeContext *s, const int16_t *samples)
 {
 #if HAVE_BIGENDIAN
@@ -1265,11 +1195,9 @@ static void update_md5_sum(FlacEncodeContext *s, const int16_t *samples)
 static int flac_encode_frame(AVCodecContext *avctx, uint8_t *frame,
                              int buf_size, void *data)
 {
-    int ch;
     FlacEncodeContext *s;
     const int16_t *samples = data;
     int out_bytes;
-    int reencoded=0;
 
     s = avctx->priv_data;
 
@@ -1292,31 +1220,20 @@ static int flac_encode_frame(AVCodecContext *avctx, uint8_t *frame,
 
     channel_decorrelation(s);
 
-    for (ch = 0; ch < s->channels; ch++)
-        encode_residual(s, ch);
+    encode_frame(s);
 
-write_frame:
-    init_put_bits(&s->pb, frame, buf_size);
-    output_frame_header(s);
-    output_subframes(s);
-    output_frame_footer(s);
-    out_bytes = put_bits_count(&s->pb) >> 3;
+    out_bytes = write_frame(s, frame, buf_size);
 
+    /* fallback to verbatim mode if the compressed frame is larger than it
+       would be if encoded uncompressed. */
     if (out_bytes > s->max_framesize) {
-        if (reencoded) {
-            /* still too large. must be an error. */
-            av_log(avctx, AV_LOG_ERROR, "error encoding frame\n");
-            return -1;
-        }
-
-        /* frame too large. use verbatim mode */
-        for (ch = 0; ch < s->channels; ch++)
-            encode_residual_v(s, ch);
-        reencoded = 1;
-        goto write_frame;
+        s->frame.verbatim_only = 1;
+        encode_frame(s);
+        out_bytes = write_frame(s, frame, buf_size);
     }
 
     s->frame_count++;
+    avctx->coded_frame->pts = s->sample_count;
     s->sample_count += avctx->frame_size;
     update_md5_sum(s, samples);
     if (out_bytes > s->max_encoded_framesize)