summaryrefslogtreecommitdiff
path: root/libavcodec/flacenc.c
diff options
context:
space:
mode:
authorJustin Ruggles <justin.ruggles@gmail.com>2012-10-25 15:07:59 -0400
committerJustin Ruggles <justin.ruggles@gmail.com>2012-11-05 15:32:30 -0500
commite78331632208a23b285a70b3cdd487dd54617c46 (patch)
treea476f3c59f5f35b9c36b179fd4ba14725ba6eb59 /libavcodec/flacenc.c
parentdfde8a34e5419ac99265e3ecc2e82f378674128a (diff)
flacenc: remove wasted trailing 0 bits
Diffstat (limited to 'libavcodec/flacenc.c')
-rw-r--r--libavcodec/flacenc.c39
1 files changed, 37 insertions, 2 deletions
diff --git a/libavcodec/flacenc.c b/libavcodec/flacenc.c
index d32127081b..a96fa3ba49 100644
--- a/libavcodec/flacenc.c
+++ b/libavcodec/flacenc.c
@@ -20,6 +20,7 @@
*/
#include "libavutil/crc.h"
+#include "libavutil/intmath.h"
#include "libavutil/md5.h"
#include "libavutil/opt.h"
#include "avcodec.h"
@@ -66,6 +67,7 @@ typedef struct FlacSubframe {
int type;
int type_code;
int obits;
+ int wasted;
int order;
int32_t coefs[MAX_LPC_ORDER];
int shift;
@@ -416,8 +418,10 @@ static void init_frame(FlacEncodeContext *s, int nb_samples)
}
}
- for (ch = 0; ch < s->channels; ch++)
+ for (ch = 0; ch < s->channels; ch++) {
+ frame->subframes[ch].wasted = 0;
frame->subframes[ch].obits = 16;
+ }
frame->verbatim_only = 0;
}
@@ -972,6 +976,33 @@ static int encode_frame(FlacEncodeContext *s)
}
+static void remove_wasted_bits(FlacEncodeContext *s)
+{
+ int ch, i;
+
+ for (ch = 0; ch < s->channels; ch++) {
+ FlacSubframe *sub = &s->frame.subframes[ch];
+ int32_t v = 0;
+
+ for (i = 0; i < s->frame.blocksize; i++) {
+ v |= sub->samples[i];
+ if (v & 1)
+ break;
+ }
+
+ if (v && !(v & 1)) {
+ v = av_ctz(v);
+
+ for (i = 0; i < s->frame.blocksize; i++)
+ sub->samples[i] >>= v;
+
+ sub->wasted = v;
+ sub->obits -= v;
+ }
+ }
+}
+
+
static int estimate_stereo_mode(int32_t *left_ch, int32_t *right_ch, int n)
{
int i, best;
@@ -1117,7 +1148,9 @@ static void write_subframes(FlacEncodeContext *s)
/* subframe header */
put_bits(&s->pb, 1, 0);
put_bits(&s->pb, 6, sub->type_code);
- put_bits(&s->pb, 1, 0); /* no wasted bits */
+ put_bits(&s->pb, 1, !!sub->wasted);
+ if (sub->wasted)
+ put_bits(&s->pb, sub->wasted, 1);
/* subframe */
if (sub->type == FLAC_SUBFRAME_CONSTANT) {
@@ -1235,6 +1268,8 @@ static int flac_encode_frame(AVCodecContext *avctx, AVPacket *avpkt,
channel_decorrelation(s);
+ remove_wasted_bits(s);
+
frame_bytes = encode_frame(s);
/* fallback to verbatim mode if the compressed frame is larger than it