diff options
Diffstat (limited to 'apps/codecs/libtremor/block.c')
-rw-r--r-- | apps/codecs/libtremor/block.c | 181 |
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 | ||
30 | static int ilog(unsigned int v){ | 31 | static 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 | ||
40 | static ogg_int32_t* _pcmp [CHANNELS] IBSS_ATTR; | ||
41 | static ogg_int32_t* _pcmbp[CHANNELS] IBSS_ATTR; | 41 | static ogg_int32_t* _pcmbp[CHANNELS] IBSS_ATTR; |
42 | static ogg_int32_t* _pcmret[CHANNELS] IBSS_ATTR; | 42 | static 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 */ |
44 | static ogg_int32_t* pcm_copy[CHANNELS] = {NULL}; | 44 | static 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){ | |||
153 | static int _vds_init(vorbis_dsp_state *v,vorbis_info *vi){ | 153 | static 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: | |||
274 | int vorbis_synthesis_restart(vorbis_dsp_state *v){ | 275 | int 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 |