FFmpeg  4.3
aaccoder_trellis.h
Go to the documentation of this file.
1 /*
2  * AAC encoder trellis codebook selector
3  * Copyright (C) 2008-2009 Konstantin Shishkov
4  *
5  * This file is part of FFmpeg.
6  *
7  * FFmpeg is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public
9  * License as published by the Free Software Foundation; either
10  * version 2.1 of the License, or (at your option) any later version.
11  *
12  * FFmpeg is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with FFmpeg; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20  */
21 
22 /**
23  * @file
24  * AAC encoder trellis codebook selector
25  * @author Konstantin Shishkov
26  */
27 
28 /**
29  * This file contains a template for the codebook_trellis_rate selector function.
30  * It needs to be provided, externally, as an already included declaration,
31  * the following functions from aacenc_quantization/util.h. They're not included
32  * explicitly here to make it possible to provide alternative implementations:
33  * - quantize_band_cost_bits
34  * - abs_pow34_v
35  */
36 
37 #ifndef AVCODEC_AACCODER_TRELLIS_H
38 #define AVCODEC_AACCODER_TRELLIS_H
39 
40 #include <float.h>
41 #include "libavutil/mathematics.h"
42 #include "avcodec.h"
43 #include "put_bits.h"
44 #include "aac.h"
45 #include "aacenc.h"
46 #include "aactab.h"
47 #include "aacenctab.h"
48 
49 /**
50  * structure used in optimal codebook search
51  */
52 typedef struct TrellisBandCodingPath {
53  int prev_idx; ///< pointer to the previous path point
54  float cost; ///< path cost
55  int run;
57 
58 
60  int win, int group_len, const float lambda)
61 {
63  int w, swb, cb, start, size;
64  int i, j;
65  const int max_sfb = sce->ics.max_sfb;
66  const int run_bits = sce->ics.num_windows == 1 ? 5 : 3;
67  const int run_esc = (1 << run_bits) - 1;
68  int idx, ppos, count;
69  int stackrun[120], stackcb[120], stack_len;
70  float next_minbits = INFINITY;
71  int next_mincb = 0;
72 
73  s->abs_pow34(s->scoefs, sce->coeffs, 1024);
74  start = win*128;
75  for (cb = 0; cb < CB_TOT_ALL; cb++) {
76  path[0][cb].cost = run_bits+4;
77  path[0][cb].prev_idx = -1;
78  path[0][cb].run = 0;
79  }
80  for (swb = 0; swb < max_sfb; swb++) {
81  size = sce->ics.swb_sizes[swb];
82  if (sce->zeroes[win*16 + swb]) {
83  float cost_stay_here = path[swb][0].cost;
84  float cost_get_here = next_minbits + run_bits + 4;
85  if ( run_value_bits[sce->ics.num_windows == 8][path[swb][0].run]
86  != run_value_bits[sce->ics.num_windows == 8][path[swb][0].run+1])
87  cost_stay_here += run_bits;
88  if (cost_get_here < cost_stay_here) {
89  path[swb+1][0].prev_idx = next_mincb;
90  path[swb+1][0].cost = cost_get_here;
91  path[swb+1][0].run = 1;
92  } else {
93  path[swb+1][0].prev_idx = 0;
94  path[swb+1][0].cost = cost_stay_here;
95  path[swb+1][0].run = path[swb][0].run + 1;
96  }
97  next_minbits = path[swb+1][0].cost;
98  next_mincb = 0;
99  for (cb = 1; cb < CB_TOT_ALL; cb++) {
100  path[swb+1][cb].cost = 61450;
101  path[swb+1][cb].prev_idx = -1;
102  path[swb+1][cb].run = 0;
103  }
104  } else {
105  float minbits = next_minbits;
106  int mincb = next_mincb;
107  int startcb = sce->band_type[win*16+swb];
108  startcb = aac_cb_in_map[startcb];
109  next_minbits = INFINITY;
110  next_mincb = 0;
111  for (cb = 0; cb < startcb; cb++) {
112  path[swb+1][cb].cost = 61450;
113  path[swb+1][cb].prev_idx = -1;
114  path[swb+1][cb].run = 0;
115  }
116  for (cb = startcb; cb < CB_TOT_ALL; cb++) {
117  float cost_stay_here, cost_get_here;
118  float bits = 0.0f;
119  if (cb >= 12 && sce->band_type[win*16+swb] != aac_cb_out_map[cb]) {
120  path[swb+1][cb].cost = 61450;
121  path[swb+1][cb].prev_idx = -1;
122  path[swb+1][cb].run = 0;
123  continue;
124  }
125  for (w = 0; w < group_len; w++) {
126  bits += quantize_band_cost_bits(s, &sce->coeffs[start + w*128],
127  &s->scoefs[start + w*128], size,
128  sce->sf_idx[win*16+swb],
130  0, INFINITY, NULL, NULL, 0);
131  }
132  cost_stay_here = path[swb][cb].cost + bits;
133  cost_get_here = minbits + bits + run_bits + 4;
134  if ( run_value_bits[sce->ics.num_windows == 8][path[swb][cb].run]
135  != run_value_bits[sce->ics.num_windows == 8][path[swb][cb].run+1])
136  cost_stay_here += run_bits;
137  if (cost_get_here < cost_stay_here) {
138  path[swb+1][cb].prev_idx = mincb;
139  path[swb+1][cb].cost = cost_get_here;
140  path[swb+1][cb].run = 1;
141  } else {
142  path[swb+1][cb].prev_idx = cb;
143  path[swb+1][cb].cost = cost_stay_here;
144  path[swb+1][cb].run = path[swb][cb].run + 1;
145  }
146  if (path[swb+1][cb].cost < next_minbits) {
147  next_minbits = path[swb+1][cb].cost;
148  next_mincb = cb;
149  }
150  }
151  }
152  start += sce->ics.swb_sizes[swb];
153  }
154 
155  //convert resulting path from backward-linked list
156  stack_len = 0;
157  idx = 0;
158  for (cb = 1; cb < CB_TOT_ALL; cb++)
159  if (path[max_sfb][cb].cost < path[max_sfb][idx].cost)
160  idx = cb;
161  ppos = max_sfb;
162  while (ppos > 0) {
163  av_assert1(idx >= 0);
164  cb = idx;
165  stackrun[stack_len] = path[ppos][cb].run;
166  stackcb [stack_len] = cb;
167  idx = path[ppos-path[ppos][cb].run+1][cb].prev_idx;
168  ppos -= path[ppos][cb].run;
169  stack_len++;
170  }
171  //perform actual band info encoding
172  start = 0;
173  for (i = stack_len - 1; i >= 0; i--) {
174  cb = aac_cb_out_map[stackcb[i]];
175  put_bits(&s->pb, 4, cb);
176  count = stackrun[i];
177  memset(sce->zeroes + win*16 + start, !cb, count);
178  //XXX: memset when band_type is also uint8_t
179  for (j = 0; j < count; j++) {
180  sce->band_type[win*16 + start] = cb;
181  start++;
182  }
183  while (count >= run_esc) {
184  put_bits(&s->pb, run_bits, run_esc);
185  count -= run_esc;
186  }
187  put_bits(&s->pb, run_bits, count);
188  }
189 }
190 
191 
192 #endif /* AVCODEC_AACCODER_TRELLIS_H */
INFINITY
#define INFINITY
Definition: mathematics.h:67
cb
static double cb(void *priv, double x, double y)
Definition: vf_geq.c:215
aacenctab.h
CB_TOT_ALL
#define CB_TOT_ALL
Total number of codebooks, including special ones.
Definition: aacenctab.h:37
SingleChannelElement::zeroes
uint8_t zeroes[128]
band is not coded (used by encoder)
Definition: aac.h:257
put_bits
static void put_bits(Jpeg2000EncoderContext *s, int val, int n)
put n times val bit
Definition: j2kenc.c:208
float.h
mathematics.h
TrellisBandCodingPath::run
int run
Definition: aaccoder_trellis.h:55
win
static float win(SuperEqualizerContext *s, float n, int N)
Definition: af_superequalizer.c:119
TrellisBandCodingPath::cost
float cost
path cost
Definition: aaccoder_trellis.h:54
quantize_band_cost_bits
static int quantize_band_cost_bits(struct AACEncContext *s, const float *in, const float *scaled, int size, int scale_idx, int cb, const float lambda, const float uplim, int *bits, float *energy, int rtz)
Definition: aacenc_quantization.h:259
SingleChannelElement::ics
IndividualChannelStream ics
Definition: aac.h:249
s
#define s(width, name)
Definition: cbs_vp9.c:257
SingleChannelElement::coeffs
INTFLOAT coeffs[1024]
coefficients for IMDCT, maybe processed
Definition: aac.h:262
IndividualChannelStream::swb_sizes
const uint8_t * swb_sizes
table of scalefactor band sizes for a particular window
Definition: aac.h:182
bits
uint8_t bits
Definition: vp3data.h:202
NULL
#define NULL
Definition: coverity.c:32
codebook_trellis_rate
static void codebook_trellis_rate(AACEncContext *s, SingleChannelElement *sce, int win, int group_len, const float lambda)
Definition: aaccoder_trellis.h:59
aac.h
aactab.h
run_value_bits
static const uint8_t *const run_value_bits[2]
Definition: aacenctab.h:116
SingleChannelElement::sf_idx
int sf_idx[128]
scalefactor indices (used by encoder)
Definition: aac.h:256
aac_cb_out_map
static const uint8_t aac_cb_out_map[CB_TOT_ALL]
Map to convert values from BandCodingPath index to a codebook index.
Definition: aacenctab.h:121
TrellisBandCodingPath
This file contains a template for the codebook_trellis_rate selector function.
Definition: aaccoder_trellis.h:52
size
int size
Definition: twinvq_data.h:11134
run_bits
static const uint8_t run_bits[7][16]
Definition: h264_cavlc.c:229
SingleChannelElement
Single Channel Element - used for both SCE and LFE elements.
Definition: aac.h:248
i
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:269
IndividualChannelStream::num_windows
int num_windows
Definition: aac.h:184
aac_cb_in_map
static const uint8_t aac_cb_in_map[CB_TOT_ALL+1]
Inverse map to convert from codebooks to BandCodingPath indices.
Definition: aacenctab.h:123
av_assert1
#define av_assert1(cond)
assert() equivalent, that does not lie in speed critical code.
Definition: avassert.h:53
avcodec.h
w
FFmpeg Automated Testing Environment ************************************Introduction Using FATE from your FFmpeg source directory Submitting the results to the FFmpeg result aggregation server Uploading new samples to the fate suite FATE makefile targets and variables Makefile targets Makefile variables Examples Introduction **************FATE is an extended regression suite on the client side and a means for results aggregation and presentation on the server side The first part of this document explains how you can use FATE from your FFmpeg source directory to test your ffmpeg binary The second part describes how you can run FATE to submit the results to FFmpeg’s FATE server In any way you can have a look at the publicly viewable FATE results by visiting this as it can be seen if some test on some platform broke with their recent contribution This usually happens on the platforms the developers could not test on The second part of this document describes how you can run FATE to submit your results to FFmpeg’s FATE server If you want to submit your results be sure to check that your combination of OS and compiler is not already listed on the above mentioned website In the third part you can find a comprehensive listing of FATE makefile targets and variables Using FATE from your FFmpeg source directory **********************************************If you want to run FATE on your machine you need to have the samples in place You can get the samples via the build target fate rsync Use this command from the top level source this will cause FATE to fail NOTE To use a custom wrapper to run the pass ‘ target exec’ to ‘configure’ or set the TARGET_EXEC Make variable Submitting the results to the FFmpeg result aggregation server ****************************************************************To submit your results to the server you should run fate through the shell script ‘tests fate sh’ from the FFmpeg sources This script needs to be invoked with a configuration file as its first argument tests fate sh path to fate_config A configuration file template with comments describing the individual configuration variables can be found at ‘doc fate_config sh template’ Create a configuration that suits your based on the configuration template The ‘slot’ configuration variable can be any string that is not yet but it is suggested that you name it adhering to the following pattern ‘ARCH OS COMPILER COMPILER VERSION’ The configuration file itself will be sourced in a shell therefore all shell features may be used This enables you to setup the environment as you need it for your build For your first test runs the ‘fate_recv’ variable should be empty or commented out This will run everything as normal except that it will omit the submission of the results to the server The following files should be present in $workdir as specified in the configuration it may help to try out the ‘ssh’ command with one or more ‘ v’ options You should get detailed output concerning your SSH configuration and the authentication process The only thing left is to automate the execution of the fate sh script and the synchronisation of the samples directory Uploading new samples to the fate suite *****************************************If you need a sample uploaded send a mail to samples request This is for developers who have an account on the fate suite server If you upload new please make sure they are as small as space on each network bandwidth and so on benefit from smaller test cases Also keep in mind older checkouts use existing sample that means in practice generally do not remove or overwrite files as it likely would break older checkouts or releases Also all needed samples for a commit should be ideally before the push If you need an account for frequently uploading samples or you wish to help others by doing that send a mail to ffmpeg devel rsync vauL Duo ug o o w
Definition: fate.txt:150
AACEncContext
AAC encoder context.
Definition: aacenc.h:376
TrellisBandCodingPath::prev_idx
int prev_idx
pointer to the previous path point
Definition: aaccoder_trellis.h:53
IndividualChannelStream::max_sfb
uint8_t max_sfb
number of scalefactor bands per group
Definition: aac.h:175
put_bits.h
SingleChannelElement::band_type
enum BandType band_type[128]
band types
Definition: aac.h:252
aacenc.h