1cabdff1aSopenharmony_ci/* 2cabdff1aSopenharmony_ci * AAC encoder trellis codebook selector 3cabdff1aSopenharmony_ci * Copyright (C) 2008-2009 Konstantin Shishkov 4cabdff1aSopenharmony_ci * 5cabdff1aSopenharmony_ci * This file is part of FFmpeg. 6cabdff1aSopenharmony_ci * 7cabdff1aSopenharmony_ci * FFmpeg is free software; you can redistribute it and/or 8cabdff1aSopenharmony_ci * modify it under the terms of the GNU Lesser General Public 9cabdff1aSopenharmony_ci * License as published by the Free Software Foundation; either 10cabdff1aSopenharmony_ci * version 2.1 of the License, or (at your option) any later version. 11cabdff1aSopenharmony_ci * 12cabdff1aSopenharmony_ci * FFmpeg is distributed in the hope that it will be useful, 13cabdff1aSopenharmony_ci * but WITHOUT ANY WARRANTY; without even the implied warranty of 14cabdff1aSopenharmony_ci * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15cabdff1aSopenharmony_ci * Lesser General Public License for more details. 16cabdff1aSopenharmony_ci * 17cabdff1aSopenharmony_ci * You should have received a copy of the GNU Lesser General Public 18cabdff1aSopenharmony_ci * License along with FFmpeg; if not, write to the Free Software 19cabdff1aSopenharmony_ci * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 20cabdff1aSopenharmony_ci */ 21cabdff1aSopenharmony_ci 22cabdff1aSopenharmony_ci/** 23cabdff1aSopenharmony_ci * @file 24cabdff1aSopenharmony_ci * AAC encoder trellis codebook selector 25cabdff1aSopenharmony_ci * @author Konstantin Shishkov 26cabdff1aSopenharmony_ci */ 27cabdff1aSopenharmony_ci 28cabdff1aSopenharmony_ci/** 29cabdff1aSopenharmony_ci * This file contains a template for the codebook_trellis_rate selector function. 30cabdff1aSopenharmony_ci * It needs to be provided, externally, as an already included declaration, 31cabdff1aSopenharmony_ci * the following functions from aacenc_quantization/util.h. They're not included 32cabdff1aSopenharmony_ci * explicitly here to make it possible to provide alternative implementations: 33cabdff1aSopenharmony_ci * - quantize_band_cost_bits 34cabdff1aSopenharmony_ci * - abs_pow34_v 35cabdff1aSopenharmony_ci */ 36cabdff1aSopenharmony_ci 37cabdff1aSopenharmony_ci#ifndef AVCODEC_AACCODER_TRELLIS_H 38cabdff1aSopenharmony_ci#define AVCODEC_AACCODER_TRELLIS_H 39cabdff1aSopenharmony_ci 40cabdff1aSopenharmony_ci#include <float.h> 41cabdff1aSopenharmony_ci#include "libavutil/mathematics.h" 42cabdff1aSopenharmony_ci#include "avcodec.h" 43cabdff1aSopenharmony_ci#include "put_bits.h" 44cabdff1aSopenharmony_ci#include "aac.h" 45cabdff1aSopenharmony_ci#include "aacenc.h" 46cabdff1aSopenharmony_ci#include "aactab.h" 47cabdff1aSopenharmony_ci#include "aacenctab.h" 48cabdff1aSopenharmony_ci 49cabdff1aSopenharmony_ci/** 50cabdff1aSopenharmony_ci * structure used in optimal codebook search 51cabdff1aSopenharmony_ci */ 52cabdff1aSopenharmony_citypedef struct TrellisBandCodingPath { 53cabdff1aSopenharmony_ci int prev_idx; ///< pointer to the previous path point 54cabdff1aSopenharmony_ci float cost; ///< path cost 55cabdff1aSopenharmony_ci int run; 56cabdff1aSopenharmony_ci} TrellisBandCodingPath; 57cabdff1aSopenharmony_ci 58cabdff1aSopenharmony_ci 59cabdff1aSopenharmony_cistatic void codebook_trellis_rate(AACEncContext *s, SingleChannelElement *sce, 60cabdff1aSopenharmony_ci int win, int group_len, const float lambda) 61cabdff1aSopenharmony_ci{ 62cabdff1aSopenharmony_ci TrellisBandCodingPath path[120][CB_TOT_ALL]; 63cabdff1aSopenharmony_ci int w, swb, cb, start, size; 64cabdff1aSopenharmony_ci int i, j; 65cabdff1aSopenharmony_ci const int max_sfb = sce->ics.max_sfb; 66cabdff1aSopenharmony_ci const int run_bits = sce->ics.num_windows == 1 ? 5 : 3; 67cabdff1aSopenharmony_ci const int run_esc = (1 << run_bits) - 1; 68cabdff1aSopenharmony_ci int idx, ppos, count; 69cabdff1aSopenharmony_ci int stackrun[120], stackcb[120], stack_len; 70cabdff1aSopenharmony_ci float next_minbits = INFINITY; 71cabdff1aSopenharmony_ci int next_mincb = 0; 72cabdff1aSopenharmony_ci 73cabdff1aSopenharmony_ci s->abs_pow34(s->scoefs, sce->coeffs, 1024); 74cabdff1aSopenharmony_ci start = win*128; 75cabdff1aSopenharmony_ci for (cb = 0; cb < CB_TOT_ALL; cb++) { 76cabdff1aSopenharmony_ci path[0][cb].cost = run_bits+4; 77cabdff1aSopenharmony_ci path[0][cb].prev_idx = -1; 78cabdff1aSopenharmony_ci path[0][cb].run = 0; 79cabdff1aSopenharmony_ci } 80cabdff1aSopenharmony_ci for (swb = 0; swb < max_sfb; swb++) { 81cabdff1aSopenharmony_ci size = sce->ics.swb_sizes[swb]; 82cabdff1aSopenharmony_ci if (sce->zeroes[win*16 + swb]) { 83cabdff1aSopenharmony_ci float cost_stay_here = path[swb][0].cost; 84cabdff1aSopenharmony_ci float cost_get_here = next_minbits + run_bits + 4; 85cabdff1aSopenharmony_ci if ( run_value_bits[sce->ics.num_windows == 8][path[swb][0].run] 86cabdff1aSopenharmony_ci != run_value_bits[sce->ics.num_windows == 8][path[swb][0].run+1]) 87cabdff1aSopenharmony_ci cost_stay_here += run_bits; 88cabdff1aSopenharmony_ci if (cost_get_here < cost_stay_here) { 89cabdff1aSopenharmony_ci path[swb+1][0].prev_idx = next_mincb; 90cabdff1aSopenharmony_ci path[swb+1][0].cost = cost_get_here; 91cabdff1aSopenharmony_ci path[swb+1][0].run = 1; 92cabdff1aSopenharmony_ci } else { 93cabdff1aSopenharmony_ci path[swb+1][0].prev_idx = 0; 94cabdff1aSopenharmony_ci path[swb+1][0].cost = cost_stay_here; 95cabdff1aSopenharmony_ci path[swb+1][0].run = path[swb][0].run + 1; 96cabdff1aSopenharmony_ci } 97cabdff1aSopenharmony_ci next_minbits = path[swb+1][0].cost; 98cabdff1aSopenharmony_ci next_mincb = 0; 99cabdff1aSopenharmony_ci for (cb = 1; cb < CB_TOT_ALL; cb++) { 100cabdff1aSopenharmony_ci path[swb+1][cb].cost = 61450; 101cabdff1aSopenharmony_ci path[swb+1][cb].prev_idx = -1; 102cabdff1aSopenharmony_ci path[swb+1][cb].run = 0; 103cabdff1aSopenharmony_ci } 104cabdff1aSopenharmony_ci } else { 105cabdff1aSopenharmony_ci float minbits = next_minbits; 106cabdff1aSopenharmony_ci int mincb = next_mincb; 107cabdff1aSopenharmony_ci int startcb = sce->band_type[win*16+swb]; 108cabdff1aSopenharmony_ci startcb = aac_cb_in_map[startcb]; 109cabdff1aSopenharmony_ci next_minbits = INFINITY; 110cabdff1aSopenharmony_ci next_mincb = 0; 111cabdff1aSopenharmony_ci for (cb = 0; cb < startcb; cb++) { 112cabdff1aSopenharmony_ci path[swb+1][cb].cost = 61450; 113cabdff1aSopenharmony_ci path[swb+1][cb].prev_idx = -1; 114cabdff1aSopenharmony_ci path[swb+1][cb].run = 0; 115cabdff1aSopenharmony_ci } 116cabdff1aSopenharmony_ci for (cb = startcb; cb < CB_TOT_ALL; cb++) { 117cabdff1aSopenharmony_ci float cost_stay_here, cost_get_here; 118cabdff1aSopenharmony_ci float bits = 0.0f; 119cabdff1aSopenharmony_ci if (cb >= 12 && sce->band_type[win*16+swb] != aac_cb_out_map[cb]) { 120cabdff1aSopenharmony_ci path[swb+1][cb].cost = 61450; 121cabdff1aSopenharmony_ci path[swb+1][cb].prev_idx = -1; 122cabdff1aSopenharmony_ci path[swb+1][cb].run = 0; 123cabdff1aSopenharmony_ci continue; 124cabdff1aSopenharmony_ci } 125cabdff1aSopenharmony_ci for (w = 0; w < group_len; w++) { 126cabdff1aSopenharmony_ci bits += quantize_band_cost_bits(s, &sce->coeffs[start + w*128], 127cabdff1aSopenharmony_ci &s->scoefs[start + w*128], size, 128cabdff1aSopenharmony_ci sce->sf_idx[win*16+swb], 129cabdff1aSopenharmony_ci aac_cb_out_map[cb], 130cabdff1aSopenharmony_ci 0, INFINITY, NULL, NULL, 0); 131cabdff1aSopenharmony_ci } 132cabdff1aSopenharmony_ci cost_stay_here = path[swb][cb].cost + bits; 133cabdff1aSopenharmony_ci cost_get_here = minbits + bits + run_bits + 4; 134cabdff1aSopenharmony_ci if ( run_value_bits[sce->ics.num_windows == 8][path[swb][cb].run] 135cabdff1aSopenharmony_ci != run_value_bits[sce->ics.num_windows == 8][path[swb][cb].run+1]) 136cabdff1aSopenharmony_ci cost_stay_here += run_bits; 137cabdff1aSopenharmony_ci if (cost_get_here < cost_stay_here) { 138cabdff1aSopenharmony_ci path[swb+1][cb].prev_idx = mincb; 139cabdff1aSopenharmony_ci path[swb+1][cb].cost = cost_get_here; 140cabdff1aSopenharmony_ci path[swb+1][cb].run = 1; 141cabdff1aSopenharmony_ci } else { 142cabdff1aSopenharmony_ci path[swb+1][cb].prev_idx = cb; 143cabdff1aSopenharmony_ci path[swb+1][cb].cost = cost_stay_here; 144cabdff1aSopenharmony_ci path[swb+1][cb].run = path[swb][cb].run + 1; 145cabdff1aSopenharmony_ci } 146cabdff1aSopenharmony_ci if (path[swb+1][cb].cost < next_minbits) { 147cabdff1aSopenharmony_ci next_minbits = path[swb+1][cb].cost; 148cabdff1aSopenharmony_ci next_mincb = cb; 149cabdff1aSopenharmony_ci } 150cabdff1aSopenharmony_ci } 151cabdff1aSopenharmony_ci } 152cabdff1aSopenharmony_ci start += sce->ics.swb_sizes[swb]; 153cabdff1aSopenharmony_ci } 154cabdff1aSopenharmony_ci 155cabdff1aSopenharmony_ci //convert resulting path from backward-linked list 156cabdff1aSopenharmony_ci stack_len = 0; 157cabdff1aSopenharmony_ci idx = 0; 158cabdff1aSopenharmony_ci for (cb = 1; cb < CB_TOT_ALL; cb++) 159cabdff1aSopenharmony_ci if (path[max_sfb][cb].cost < path[max_sfb][idx].cost) 160cabdff1aSopenharmony_ci idx = cb; 161cabdff1aSopenharmony_ci ppos = max_sfb; 162cabdff1aSopenharmony_ci while (ppos > 0) { 163cabdff1aSopenharmony_ci av_assert1(idx >= 0); 164cabdff1aSopenharmony_ci cb = idx; 165cabdff1aSopenharmony_ci stackrun[stack_len] = path[ppos][cb].run; 166cabdff1aSopenharmony_ci stackcb [stack_len] = cb; 167cabdff1aSopenharmony_ci idx = path[ppos-path[ppos][cb].run+1][cb].prev_idx; 168cabdff1aSopenharmony_ci ppos -= path[ppos][cb].run; 169cabdff1aSopenharmony_ci stack_len++; 170cabdff1aSopenharmony_ci } 171cabdff1aSopenharmony_ci //perform actual band info encoding 172cabdff1aSopenharmony_ci start = 0; 173cabdff1aSopenharmony_ci for (i = stack_len - 1; i >= 0; i--) { 174cabdff1aSopenharmony_ci cb = aac_cb_out_map[stackcb[i]]; 175cabdff1aSopenharmony_ci put_bits(&s->pb, 4, cb); 176cabdff1aSopenharmony_ci count = stackrun[i]; 177cabdff1aSopenharmony_ci memset(sce->zeroes + win*16 + start, !cb, count); 178cabdff1aSopenharmony_ci //XXX: memset when band_type is also uint8_t 179cabdff1aSopenharmony_ci for (j = 0; j < count; j++) { 180cabdff1aSopenharmony_ci sce->band_type[win*16 + start] = cb; 181cabdff1aSopenharmony_ci start++; 182cabdff1aSopenharmony_ci } 183cabdff1aSopenharmony_ci while (count >= run_esc) { 184cabdff1aSopenharmony_ci put_bits(&s->pb, run_bits, run_esc); 185cabdff1aSopenharmony_ci count -= run_esc; 186cabdff1aSopenharmony_ci } 187cabdff1aSopenharmony_ci put_bits(&s->pb, run_bits, count); 188cabdff1aSopenharmony_ci } 189cabdff1aSopenharmony_ci} 190cabdff1aSopenharmony_ci 191cabdff1aSopenharmony_ci 192cabdff1aSopenharmony_ci#endif /* AVCODEC_AACCODER_TRELLIS_H */ 193