[FFmpeg-soc] [soc]: r3668 - mlp/mlpenc.c
ramiro
subversion at mplayerhq.hu
Fri Aug 29 05:25:28 CEST 2008
Author: ramiro
Date: Fri Aug 29 05:25:27 2008
New Revision: 3668
Log:
Find the best (well, a fairly good one) path for changing huff_lsbs and the
codebook on different access units. This minimizes overhead on writing a new
header to change these parameters all the fime.
Modified:
mlp/mlpenc.c
Modified: mlp/mlpenc.c
==============================================================================
--- mlp/mlpenc.c (original)
+++ mlp/mlpenc.c Fri Aug 29 05:25:27 2008
@@ -22,6 +22,7 @@
#include "avcodec.h"
#include "bitstream.h"
#include "libavutil/crc.h"
+#include "libavutil/avstring.h"
#include "mlp.h"
#include "dsputil.h"
#include "lpc.h"
@@ -132,7 +133,7 @@ typedef struct {
ChannelParams channel_params[MAJOR_HEADER_INTERVAL][MAJOR_HEADER_INTERVAL][MAJOR_HEADER_INTERVAL+1][MAX_CHANNELS];
- BestOffset best_offset[MAJOR_HEADER_INTERVAL][MAJOR_HEADER_INTERVAL][MAJOR_HEADER_INTERVAL+1][MAX_CHANNELS][NUM_CODEBOOKS];
+ BestOffset best_offset[MAJOR_HEADER_INTERVAL+1][MAX_CHANNELS][NUM_CODEBOOKS];
DecodingParams decoding_params[MAJOR_HEADER_INTERVAL][MAJOR_HEADER_INTERVAL][MAJOR_HEADER_INTERVAL+1][MAX_SUBSTREAMS];
RestartHeader restart_header [MAX_SUBSTREAMS];
@@ -163,6 +164,7 @@ typedef struct {
static ChannelParams restart_channel_params[MAX_CHANNELS];
static DecodingParams restart_decoding_params[MAX_SUBSTREAMS];
+static BestOffset restart_best_offset[NUM_CODEBOOKS] = {{0}};
#define SYNC_MAJOR 0xf8726f
@@ -285,13 +287,6 @@ static int compare_decoding_params(MLPEn
return retval;
}
-static void copy_codebook_params(ChannelParams *dst, ChannelParams *src)
-{
- dst->huff_offset = src->huff_offset;
- dst->huff_lsbs = src->huff_lsbs;
- dst->codebook = src->codebook;
-}
-
static void copy_filter_params(FilterParams *dst, FilterParams *src)
{
dst->order = src->order;
@@ -1878,31 +1873,136 @@ static void rematrix_channels(MLPEncodeC
**** Functions that deal with determining the best parameters and output ***
****************************************************************************/
-static void set_best_offset(MLPEncodeContext *ctx, int index)
+typedef struct {
+ char path[MAJOR_HEADER_INTERVAL + 3];
+ int bitcount;
+} PathCounter;
+
+static const char *path_counter_codebook[] = { "0", "1", "2", "3", };
+
+#define ZERO_PATH '0'
+#define CODEBOOK_CHANGE_BITS 21
+
+static void clear_path_counter(PathCounter *path_counter)
+{
+ unsigned int i;
+
+ for (i = 0; i < NUM_CODEBOOKS + 1; i++) {
+ path_counter[i].path[0] = ZERO_PATH;
+ path_counter[i].path[1] = 0x00;
+ path_counter[i].bitcount = 0;
+ }
+}
+
+static int compare_best_offset(BestOffset *prev, BestOffset *cur)
+{
+ if (prev->lsb_bits != cur->lsb_bits)
+ return 1;
+
+ return 0;
+}
+
+static int best_codebook_path_cost(MLPEncodeContext *ctx, unsigned int channel,
+ PathCounter *src, int cur_codebook)
+{
+ BestOffset *cur_bo, *prev_bo = restart_best_offset;
+ int bitcount = src->bitcount;
+ char *path = src->path + 1;
+ int prev_codebook;
+ int i;
+
+ for (i = 0; path[i]; i++)
+ prev_bo = ctx->best_offset[i][channel];
+
+ prev_codebook = path[i - 1] - ZERO_PATH;
+
+ cur_bo = ctx->best_offset[i][channel];
+
+ bitcount += cur_bo[cur_codebook].bitcount;
+
+ if (prev_codebook != cur_codebook ||
+ compare_best_offset(&prev_bo[prev_codebook], &cur_bo[cur_codebook]))
+ bitcount += CODEBOOK_CHANGE_BITS;
+
+ return bitcount;
+}
+
+static void set_best_codebook(MLPEncodeContext *ctx)
{
DecodingParams *dp = ctx->cur_decoding_params;
RestartHeader *rh = ctx->cur_restart_header;
unsigned int channel;
for (channel = rh->min_channel; channel <= rh->max_channel; channel++) {
- ChannelParams *major_cp = &ctx->major_channel_params[index][channel];
- ChannelParams *cp = &ctx->cur_channel_params[channel];
- BestOffset bo = { 0, INT_MAX, 0, 0, 0, };
- unsigned int best_codebook = 0, i;
+ BestOffset *cur_bo, *prev_bo = restart_best_offset;
+ PathCounter path_counter[NUM_CODEBOOKS + 1];
+ unsigned int best_codebook;
+ unsigned int index;
+ char *best_path;
- for (i = 0; i < NUM_CODEBOOKS; i++) {
- if (ctx->cur_best_offset[channel][i].bitcount < bo.bitcount) {
- bo = ctx->cur_best_offset[channel][i];
- best_codebook = i;
+ clear_path_counter(path_counter);
+
+ for (index = 0; index < ctx->number_of_frames + 1; index++) {
+ unsigned int best_bitcount = INT_MAX;
+ unsigned int codebook;
+
+ cur_bo = ctx->best_offset[index][channel];
+
+ for (codebook = 0; codebook < NUM_CODEBOOKS; codebook++) {
+ int prev_best_bitcount = INT_MAX;
+ int last_best;
+
+ for (last_best = 0; last_best < 2; last_best++) {
+ PathCounter *dst_path = &path_counter[codebook];
+ PathCounter *src_path;
+ int temp_bitcount;
+
+ /* First test last path with same headers,
+ * then with last best. */
+ if (last_best) {
+ src_path = &path_counter[NUM_CODEBOOKS];
+ } else {
+ if (compare_best_offset(&prev_bo[codebook], &cur_bo[codebook]))
+ continue;
+ else
+ src_path = &path_counter[codebook];
+ }
+
+ temp_bitcount = best_codebook_path_cost(ctx, channel, src_path, codebook);
+
+ if (temp_bitcount < best_bitcount) {
+ best_bitcount = temp_bitcount;
+ best_codebook = codebook;
+ }
+
+ if (temp_bitcount < prev_best_bitcount) {
+ prev_best_bitcount = temp_bitcount;
+ if (src_path != dst_path)
+ memcpy(dst_path, src_path, sizeof(PathCounter));
+ av_strlcat(dst_path->path, path_counter_codebook[codebook], sizeof(dst_path->path));
+ dst_path->bitcount = temp_bitcount;
+ }
+ }
}
+
+ prev_bo = cur_bo;
+
+ memcpy(&path_counter[NUM_CODEBOOKS], &path_counter[best_codebook], sizeof(PathCounter));
}
+ best_path = path_counter[NUM_CODEBOOKS].path + 1;
+
/* Update context. */
- cp->huff_offset = bo.offset;
- cp->huff_lsbs = bo.lsb_bits + dp->quant_step_size[channel];
- cp->codebook = best_codebook;
+ for (index = 0; index < ctx->number_of_frames + 1; index++) {
+ ChannelParams *cp = &ctx->channel_params[ctx->seq_index][ctx->frame_index][index][channel];
- copy_codebook_params(major_cp, cp);
+ best_codebook = *best_path++ - ZERO_PATH;
+ cur_bo = &ctx->best_offset[index][channel][best_codebook];
+
+ cp->huff_offset = cur_bo->offset;
+ cp->huff_lsbs = cur_bo->lsb_bits + dp->quant_step_size[channel];
+ cp->codebook = best_codebook;
+ }
}
}
@@ -1928,9 +2028,6 @@ static void set_major_params(MLPEncodeCo
for (index = 0; index < MAJOR_HEADER_INTERVAL + 1; index++) {
ctx->cur_decoding_params = &ctx->decoding_params[MAJOR_HEADER_INTERVAL-1][MAJOR_HEADER_INTERVAL-1][index][substr];
ctx->cur_channel_params = ctx->channel_params[MAJOR_HEADER_INTERVAL-1][MAJOR_HEADER_INTERVAL-1][index];
- ctx->cur_best_offset = ctx->best_offset[MAJOR_HEADER_INTERVAL-1][MAJOR_HEADER_INTERVAL-1][index];
-
- set_best_offset(ctx, index);
ctx->major_params_changed[index][substr] = compare_decoding_params(ctx);
@@ -1971,10 +2068,12 @@ static void analyze_sample_buffer(MLPEnc
for (index = 0; index < ctx->number_of_frames + 1; index++) {
ctx->cur_decoding_params = &ctx->decoding_params[ctx->seq_index][ctx->frame_index][index][substr];
ctx->cur_channel_params = ctx->channel_params[ctx->seq_index][ctx->frame_index][index];
- ctx->cur_best_offset = ctx->best_offset[ctx->seq_index][ctx->frame_index][index];
+ ctx->cur_best_offset = ctx->best_offset[index];
determine_bits(ctx);
ctx->sample_buffer += ctx->cur_decoding_params->blocksize * ctx->num_channels;
}
+
+ set_best_codebook(ctx);
}
}
More information about the FFmpeg-soc
mailing list