summaryrefslogtreecommitdiff
path: root/apps/codecs/libtremor/block.c
diff options
context:
space:
mode:
Diffstat (limited to 'apps/codecs/libtremor/block.c')
-rw-r--r--apps/codecs/libtremor/block.c181
1 files changed, 46 insertions, 135 deletions
diff --git a/apps/codecs/libtremor/block.c b/apps/codecs/libtremor/block.c
index d678719cbe..b7ce5adc4e 100644
--- a/apps/codecs/libtremor/block.c
+++ b/apps/codecs/libtremor/block.c
@@ -25,6 +25,7 @@
25#include "window.h" 25#include "window.h"
26#include "registry.h" 26#include "registry.h"
27#include "misc.h" 27#include "misc.h"
28#include "ffmpeg_render_line.h"
28//#include <codecs/lib/codeclib.h> 29//#include <codecs/lib/codeclib.h>
29 30
30static int ilog(unsigned int v){ 31static int ilog(unsigned int v){
@@ -37,11 +38,10 @@ static int ilog(unsigned int v){
37 return(ret); 38 return(ret);
38} 39}
39 40
40static ogg_int32_t* _pcmp [CHANNELS] IBSS_ATTR;
41static ogg_int32_t* _pcmbp[CHANNELS] IBSS_ATTR; 41static ogg_int32_t* _pcmbp[CHANNELS] IBSS_ATTR;
42static ogg_int32_t* _pcmret[CHANNELS] IBSS_ATTR; 42static ogg_int32_t* _pcmret[CHANNELS] IBSS_ATTR;
43/* save original pointers returned by malloc so we can free it easily */ 43/* save original pointers returned by malloc so we can free it easily */
44static ogg_int32_t* pcm_copy[CHANNELS] = {NULL}; 44static ogg_int32_t* malloc_pointers[3] = {NULL};
45 45
46/* pcm accumulator examples (not exhaustive): 46/* pcm accumulator examples (not exhaustive):
47 47
@@ -153,14 +153,13 @@ int vorbis_block_clear(vorbis_block *vb){
153static int _vds_init(vorbis_dsp_state *v,vorbis_info *vi){ 153static int _vds_init(vorbis_dsp_state *v,vorbis_info *vi){
154 int i; 154 int i;
155 long b_size[2]; 155 long b_size[2];
156 156
157 codec_setup_info *ci=(codec_setup_info *)vi->codec_setup; 157 codec_setup_info *ci=(codec_setup_info *)vi->codec_setup;
158 private_state *b=NULL; 158 private_state *b=NULL;
159 159
160 if(ci==NULL) return 1; 160 if(ci==NULL) return 1;
161 161
162 memset(v,0,sizeof(*v)); 162 memset(v,0,sizeof(*v));
163 v->reset_pcmb=true;
164 b=(private_state *)(v->backend_state=_ogg_calloc(1,sizeof(*b))); 163 b=(private_state *)(v->backend_state=_ogg_calloc(1,sizeof(*b)));
165 164
166 v->vi=vi; 165 v->vi=vi;
@@ -169,16 +168,42 @@ static int _vds_init(vorbis_dsp_state *v,vorbis_info *vi){
169#ifdef TREMOR_USE_IRAM 168#ifdef TREMOR_USE_IRAM
170 /* allocate IRAM buffer for the PCM data generated by synthesis */ 169 /* allocate IRAM buffer for the PCM data generated by synthesis */
171 iram_malloc_init(); 170 iram_malloc_init();
172 v->first_pcm = iram_malloc(vi->channels*ci->blocksizes[1]*sizeof(ogg_int32_t)); 171
173 /* when can't allocate IRAM buffer, allocate normal RAM buffer */ 172 v->floors = iram_malloc(vi->channels*ci->blocksizes[1]/2*sizeof(ogg_int32_t));
174 if(v->first_pcm == NULL) 173 v->residues[0] = iram_malloc(vi->channels*ci->blocksizes[1]/2*sizeof(ogg_int32_t));
174 /* if we can get away with it, put a double buffer into IRAM too, so that
175 overlap-add runs iram-to-iram and we avoid needing to memcpy */
176 v->residues[1] = iram_malloc(vi->channels*ci->blocksizes[1]/2*sizeof(ogg_int32_t));
177 if (v->residues[1] == NULL)
178 v->saved = iram_malloc(vi->channels*ci->blocksizes[1]/4*sizeof(ogg_int32_t));
179
175#endif 180#endif
176 { 181
177 pcm_copy[0] = _ogg_malloc(vi->channels*ci->blocksizes[1]*sizeof(ogg_int32_t)); 182 if (v->residues[0] == NULL) {
178 v->first_pcm = pcm_copy[0]; 183 malloc_pointers[0] = _ogg_malloc(vi->channels*ci->blocksizes[1]/2*sizeof(ogg_int32_t));
184 v->residues[0] = malloc_pointers[0];
185 }
186
187 if (v->residues[1] == NULL && v->saved == NULL) {
188 malloc_pointers[1] = _ogg_malloc(vi->channels*ci->blocksizes[1]/2*sizeof(ogg_int32_t));
189 v->residues[1] = malloc_pointers[1];
179 } 190 }
180 191
181 v->centerW=0; 192 if (v->floors == NULL) {
193 malloc_pointers[2] = _ogg_malloc(vi->channels*ci->blocksizes[1]/2*sizeof(ogg_int32_t));
194 v->floors = malloc_pointers[2];
195 }
196
197 /* needed for the first overlap/add */
198 if (v->saved) {
199 memset(v->saved, 0, vi->channels*ci->blocksizes[1]/4*sizeof(ogg_int32_t));
200 for (i = 0; i < vi->channels; i++)
201 v->saved_ptr[i] = v->saved + i*ci->blocksizes[1]/4;
202 } else {
203 memset(v->residues[1], 0, vi->channels*ci->blocksizes[1]/2*sizeof(ogg_int32_t));
204 for (i = 0; i < vi->channels; i++)
205 v->saved_ptr[i] = v->residues[1] + i*ci->blocksizes[1]/2;
206 }
182 207
183 /* Vorbis I uses only window type 0 */ 208 /* Vorbis I uses only window type 0 */
184 b_size[0]=ci->blocksizes[0]/2; 209 b_size[0]=ci->blocksizes[0]/2;
@@ -214,37 +239,13 @@ static int _vds_init(vorbis_dsp_state *v,vorbis_info *vi){
214 } 239 }
215 } 240 }
216 241
217 /* if we can get away with it, put a double buffer into IRAM too, so that
218 overlap-add runs iram-to-iram and we avoid needing to memcpy */
219 v->pcm_storage=ci->blocksizes[1]; 242 v->pcm_storage=ci->blocksizes[1];
220 v->pcm=_pcmp;
221 v->pcmret=_pcmret; 243 v->pcmret=_pcmret;
222 v->pcmb=_pcmbp; 244 v->pcmb=_pcmbp;
223 245
224 _pcmp[0]=NULL;
225 _pcmp[1]=NULL;
226 _pcmbp[0]=NULL; 246 _pcmbp[0]=NULL;
227 _pcmbp[1]=NULL; 247 _pcmbp[1]=NULL;
228 248
229#ifdef TREMOR_USE_IRAM
230 if(NULL != (v->iram_double_pcm = iram_malloc(vi->channels*v->pcm_storage*sizeof(ogg_int32_t))))
231 {
232 /* one-time initialisation at codec start or on switch from
233 blocksizes greater than IRAM_PCM_END to sizes that fit */
234 for(i=0;i<vi->channels;i++)
235 v->pcm[i]=&v->iram_double_pcm[i*v->pcm_storage];
236 }
237 else
238#endif
239 {
240 /* one-time initialisation at codec start or on switch from
241 blocksizes that fit in IRAM_PCM_END to those that don't */
242 /* save copy of the pointer so we can free it easily later */
243 pcm_copy[1] = _ogg_calloc(vi->channels*v->pcm_storage,sizeof(*v->pcm[i]));
244 for(i=0;i<vi->channels;i++)
245 v->pcm[i] = pcm_copy[1]+i*v->pcm_storage;
246 }
247
248 /* all 1 (large block) or 0 (small block) */ 249 /* all 1 (large block) or 0 (small block) */
249 /* explicitly set for the sake of clarity */ 250 /* explicitly set for the sake of clarity */
250 v->lW=0; /* previous window size */ 251 v->lW=0; /* previous window size */
@@ -274,35 +275,19 @@ abort_books:
274int vorbis_synthesis_restart(vorbis_dsp_state *v){ 275int vorbis_synthesis_restart(vorbis_dsp_state *v){
275 vorbis_info *vi=v->vi; 276 vorbis_info *vi=v->vi;
276 codec_setup_info *ci; 277 codec_setup_info *ci;
277 int i;
278 278
279 if(!v->backend_state)return -1; 279 if(!v->backend_state)return -1;
280 if(!vi)return -1; 280 if(!vi)return -1;
281 ci=vi->codec_setup; 281 ci=vi->codec_setup;
282 if(!ci)return -1; 282 if(!ci)return -1;
283 283
284 v->centerW=0;
285 v->pcm_current=0; 284 v->pcm_current=0;
286 285
287 v->pcm_returned=-1; 286 v->pcm_returned=-1;
288 v->granulepos=-1; 287 v->granulepos=-1;
289 v->sequence=-1; 288 v->sequence=-1;
290 ((private_state *)(v->backend_state))->sample_count=-1; 289 ((private_state *)(v->backend_state))->sample_count=-1;
291 290
292 /* indicate to synthesis code that buffer pointers no longer valid
293 (if we're using double pcm buffer) and will need to reset them */
294 v->reset_pcmb = true;
295 /* also reset our copy of the double buffer pointers if we have one */
296#ifdef TREMOR_USE_IRAM
297 if(v->iram_double_pcm)
298 {
299 for(i=0;i<vi->channels;i++)
300 v->pcm[i]=&v->iram_double_pcm[i*v->pcm_storage];
301 }
302#else
303 for(i=0;i<vi->channels;i++)
304 v->pcm[i] = pcm_copy[1]+i*v->pcm_storage;
305#endif
306 return(0); 291 return(0);
307} 292}
308 293
@@ -323,11 +308,10 @@ void vorbis_dsp_clear(vorbis_dsp_state *v){
323 if(vi != NULL) 308 if(vi != NULL)
324 { 309 {
325 /* pcm buffer came from oggmalloc rather than iram */ 310 /* pcm buffer came from oggmalloc rather than iram */
326 for(i=0;i<2;i++) 311 for(i=0;i<3;i++)
327 if(pcm_copy[i]) 312 if(malloc_pointers[i]) {
328 { 313 _ogg_free(malloc_pointers[i]);
329 _ogg_free(pcm_copy[i]); 314 malloc_pointers[i] = NULL;
330 pcm_copy[i] = NULL;
331 } 315 }
332 } 316 }
333 317
@@ -359,10 +343,6 @@ int vorbis_synthesis_blockin(vorbis_dsp_state *v,vorbis_block *vb){
359 vorbis_info *vi=v->vi; 343 vorbis_info *vi=v->vi;
360 codec_setup_info *ci=(codec_setup_info *)vi->codec_setup; 344 codec_setup_info *ci=(codec_setup_info *)vi->codec_setup;
361 private_state *b=v->backend_state; 345 private_state *b=v->backend_state;
362 int j;
363#ifdef TREMOR_USE_IRAM
364 bool iram_pcm_doublebuffer = (NULL != v->iram_double_pcm);
365#endif
366 346
367 if(v->pcm_current>v->pcm_returned && v->pcm_returned!=-1)return(OV_EINVAL); 347 if(v->pcm_current>v->pcm_returned && v->pcm_returned!=-1)return(OV_EINVAL);
368 348
@@ -380,79 +360,11 @@ int vorbis_synthesis_blockin(vorbis_dsp_state *v,vorbis_block *vb){
380 int n=ci->blocksizes[v->W]/2; 360 int n=ci->blocksizes[v->W]/2;
381 int ln=ci->blocksizes[v->lW]/2; 361 int ln=ci->blocksizes[v->lW]/2;
382 362
383 if(LIKELY(vb->pcm)){ /* no pcm to process if vorbis_synthesis_trackonly 363 if(LIKELY(vb->pcmend != 0)){ /* no pcm to process if vorbis_synthesis_trackonly
384 was called on block */ 364 was called on block */
385 int prevCenter; 365 window_overlap_add(ci->blocksizes[v->W], ci->blocksizes[v->lW],
386 int n0=ci->blocksizes[0]/2; 366 ci->blocksizes[0], ci->blocksizes[1], vi->channels,
387 int n1=ci->blocksizes[1]/2; 367 b->window[v->W & v->lW], v);
388
389#ifdef TREMOR_USE_IRAM
390 if(!iram_pcm_doublebuffer)
391 {
392 prevCenter = v->centerW;
393 v->centerW = n1 - v->centerW;
394 }
395 else
396#endif
397 prevCenter = ln;
398
399 /* overlap/add PCM */
400 /* nb nothing to overlap with on first block so don't bother */
401 if(LIKELY(v->pcm_returned!=-1))
402 {
403 for(j=0;j<vi->channels;j++)
404 {
405 ogg_int32_t *pcm=v->pcm[j]+prevCenter;
406 ogg_int32_t *p=vb->pcm[j];
407
408 /* the overlap/add section */
409 if(v->lW == v->W)
410 {
411 /* large/large or small/small */
412 vect_add_right_left(pcm,p,n);
413 v->pcmb[j]=pcm;
414 }
415 else if (!v->W)
416 {
417 /* large/small */
418 vect_add_right_left(pcm + (n1-n0)/2, p, n0);
419 v->pcmb[j]=pcm;
420 }
421 else
422 {
423 /* small/large */
424 p += (n1-n0)/2;
425 vect_add_left_right(p,pcm,n0);
426 v->pcmb[j]=p;
427 }
428 }
429 }
430#ifdef TREMOR_USE_IRAM
431 /* the copy section */
432 if(!iram_pcm_doublebuffer)
433 {
434 for(j=0;j<vi->channels;j++)
435 {
436 /* at best only vb->pcm is in iram, and that's where we do the
437 synthesis, so we copy out the right-hand subframe of last
438 synthesis into (noniram) local buffer so we can still do
439 synth in iram */
440 vect_copy(v->pcm[j]+v->centerW, vb->pcm[j]+n, n);
441 }
442 }
443 else
444#endif
445 {
446 /* just flip the pointers over as we have a double buffer in iram */
447 ogg_int32_t *p;
448 p=v->pcm[0];
449 v->pcm[0]=vb->pcm[0];
450 vb->pcm[0] = p;
451 p=v->pcm[1];
452 v->pcm[1]=vb->pcm[1];
453 vb->pcm[1] = p;
454 }
455
456 /* deal with initial packet state; we do this using the explicit 368 /* deal with initial packet state; we do this using the explicit
457 pcm_returned==-1 flag otherwise we're sensitive to first block 369 pcm_returned==-1 flag otherwise we're sensitive to first block
458 being short or long */ 370 being short or long */
@@ -464,7 +376,6 @@ int vorbis_synthesis_blockin(vorbis_dsp_state *v,vorbis_block *vb){
464 v->pcm_returned=0; 376 v->pcm_returned=0;
465 v->pcm_current=(n+ln)/2; 377 v->pcm_current=(n+ln)/2;
466 } 378 }
467
468 } 379 }
469 380
470 /* track the frame number... This is for convenience, but also 381 /* track the frame number... This is for convenience, but also