Mercurial > cgi-bin > hgwebdir.cgi > PR > Applications > VSs > VSs__H264__App
diff libavcodec/cell/spe_mbd.c @ 2:897f711a7157
rearrange to work with autoconf
| author | Nina Engelhardt <nengel@mailbox.tu-berlin.de> |
|---|---|
| date | Tue, 25 Sep 2012 15:55:33 +0200 |
| parents | |
| children |
line diff
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/libavcodec/cell/spe_mbd.c Tue Sep 25 15:55:33 2012 +0200 1.3 @@ -0,0 +1,356 @@ 1.4 +/* 1.5 + * Copyright (c) 2009 TUDelft 1.6 + * 1.7 + * Cell Parallel SPU - 2DWave Macroblock Decoding. 1.8 + */ 1.9 + 1.10 +/** 1.11 + * @file libavcodec/cell/spu/h264_main_spu.c 1.12 + * Cell Parallel SPU - 2DWave Macroblock Decoding 1.13 + * @author C C Chi <c.c.chi@student.tudelft.nl> 1.14 + * 1.15 + * SIMD kernels 1.16 + * H.264/AVC motion compensation 1.17 + * @author Mauricio Alvarez <alvarez@ac.upc.edu> 1.18 + * @author Albert Paradis <apar7632@hotmail.com> 1.19 + */ 1.20 + 1.21 + 1.22 +/* Enable this lines to enable simulator statistic or generate traces */ 1.23 + 1.24 +//#define ENABLE_SIMULATOR 1.25 +//#define ENABLE_PARAVER_TRACING_CELL 1.26 + 1.27 +#ifdef ENABLE_SIMULATOR 1.28 + #include "/opt/ibm/systemsim-cell/include/callthru/spu/profile.h" 1.29 +#endif 1.30 + 1.31 +#ifdef ENABLE_TRACES 1.32 + #include "spu_trace.h" 1.33 +#endif 1.34 +#include <unistd.h> 1.35 +#include <stdio.h> 1.36 +#include <spu_intrinsics.h> 1.37 +#include <spu_mfcio.h> 1.38 +#include <libsync.h> 1.39 +#include <sys/time.h> 1.40 +#include <assert.h> 1.41 + 1.42 +//#include "dsputil_cell.h" 1.43 +#include "types_spu.h" 1.44 +#include "h264_intra_spu.h" 1.45 +#include "h264_decode_mb_spu.h" 1.46 +#include "h264_mc_spu.h" 1.47 +#include "h264_tables.h" 1.48 +#include "h264_dma.h" 1.49 + 1.50 + 1.51 +/** functions for supporting tracing with paraver for the SPU 1.52 + * 1.53 + */ 1.54 +inline void trace_init_SPU(){ 1.55 +#ifdef ENABLE_PARAVER_TRACING_CELL 1.56 + SPUtrace_init (); 1.57 +#endif 1.58 +} 1.59 + 1.60 +inline void trace_fini_SPU(){ 1.61 +#ifdef ENABLE_PARAVER_TRACING_CELL 1.62 + SPUtrace_fini (); 1.63 +#endif 1.64 +} 1.65 + 1.66 +inline void trace_event_SPU(int event, int id){ 1.67 +#ifdef ENABLE_PARAVER_TRACING_CELL 1.68 + SPUtrace_event (event, id); 1.69 +#else 1.70 + (void) event; 1.71 + (void) id; 1.72 +#endif 1.73 +} 1.74 + 1.75 +// for simulator statistic 1.76 +inline void clear_statistic(){ 1.77 +#ifdef ENABLE_SIMULATOR 1.78 + prof_clear(); 1.79 +#endif 1.80 +} 1.81 + 1.82 +inline void start_statistic(){ 1.83 +#ifdef ENABLE_SIMULATOR 1.84 + prof_start(); 1.85 +#endif 1.86 +} 1.87 + 1.88 +inline void stop_statistic(){ 1.89 +#ifdef ENABLE_SIMULATOR 1.90 + prof_stop(); 1.91 +#endif 1.92 +} 1.93 + 1.94 +H264Context_spu h_context; // struct that contain all the params to decode a macroblock 1.95 + 1.96 +DECLARE_ALIGNED_16(spe_pos, dma_temp); //dma temp for sending 1.97 +//mb position of neighbouring spes 1.98 +DECLARE_ALIGNED_16(volatile spe_pos, src_spe); //written by SPE_ID -1 1.99 +//DECLARE_ALIGNED_16(spe_pos, tgt_spe); //written by SPE_ID +1 1.100 + 1.101 +/** 1.102 +* Initializes the buffering of the mb data and associated mc data. The init_mb_buffer needs to 1.103 +* be called before any get_next_mb and only once at the beginning of the slice. 1.104 +* 1.105 +* Note: init_mc_buffer and get_next_mb expect the width of the picture to be more than 2 mb's 1.106 +*/ 1.107 +#define TAG_OFFSET_MB MBD_buf1 1.108 +#define TAG_OFFSET_MC MBD_mc_buf1 1.109 +static void init_mb_buffer(H264Context_spu* h){ 1.110 + H264slice *s = h->s; 1.111 + H264Mb *next_mb; 1.112 + int mb_height = s->mb_height; 1.113 + int mb_width = s->mb_width; 1.114 + 1.115 + h->mc_idx =0; 1.116 + 1.117 + h->mb_dec = 0; 1.118 + h->mb_mc = 0; 1.119 + h->mb_dma = 0; 1.120 + 1.121 + h->curr_line %= mb_height; 1.122 + h->next_mb_idx = h->curr_line * mb_width; 1.123 + h->mb_id = h->curr_line * mb_width; 1.124 + h->n_mc= h->curr_line * mb_width; 1.125 + 1.126 + next_mb = s->blocks + h->mb_id; 1.127 + spu_dma_get(&h->mb_buf[h->mb_dma], (unsigned) next_mb, sizeof(H264Mb), h->mb_dma + TAG_OFFSET_MB); 1.128 + h->mb_dma++; 1.129 + h->mb_id++; 1.130 + 1.131 + next_mb = s->blocks + h->mb_id; 1.132 + spu_dma_get(&h->mb_buf[h->mb_dma], (unsigned) next_mb, sizeof(H264Mb), h->mb_dma + TAG_OFFSET_MB); 1.133 + h->mb_dma++; 1.134 + h->mb_id++; 1.135 + wait_dma_id(0 + TAG_OFFSET_MB); 1.136 + 1.137 + H264Mb *mb = &h->mb_buf[0]; 1.138 + H264mc *mc = &h->mc_buf[0]; 1.139 + if(!IS_INTRA(mb->mb_type)){ 1.140 + calc_mc_params(mb, mc); 1.141 + fill_ref_buf(h, mb, mc); 1.142 + } 1.143 + h->n_mc++; 1.144 + h->mb_mc++; 1.145 +} 1.146 + 1.147 +static void *get_next_mb(H264Context_spu *h){ 1.148 + H264slice *s = h->s; 1.149 + H264spe *spe = &h->spe; 1.150 + H264Mb *mb_buf = h->mb_buf; 1.151 + H264mc *mc_buf = h->mc_buf; 1.152 + H264Mb *next_mb; 1.153 + H264Mb *next_dma_mb; 1.154 + 1.155 + if (h->curr_line >= s->mb_height) 1.156 + return NULL; 1.157 + 1.158 + if (h->mb_id < h->mb_total){ 1.159 + next_dma_mb = s->blocks + h->mb_id; 1.160 + spu_dma_get(&mb_buf[h->mb_dma], (unsigned) next_dma_mb, sizeof(H264Mb), h->mb_dma + TAG_OFFSET_MB); 1.161 + h->mb_dma = (h->mb_dma+1)%3; 1.162 + h->mb_id++; 1.163 + if (h->mb_id%s->mb_width ==0){ 1.164 + h->mb_id+=(spe->spe_total-1)*s->mb_width; 1.165 + } 1.166 + } 1.167 + 1.168 + h->mc = &mc_buf[h->mc_idx]; 1.169 + wait_dma_id(h->mc_idx + TAG_OFFSET_MC); 1.170 + h->mc_idx = (h->mc_idx+1)%2; 1.171 + if (h->n_mc < h->mb_total){ 1.172 + wait_dma_id(h->mb_mc + TAG_OFFSET_MB); 1.173 + H264Mb *mb = &mb_buf[h->mb_mc]; 1.174 + H264mc *mc = &mc_buf[h->mc_idx]; 1.175 + if(!IS_INTRA(mb->mb_type)){ 1.176 + calc_mc_params(mb, mc); 1.177 + fill_ref_buf(h, mb, mc); 1.178 + } 1.179 + h->n_mc++; 1.180 + if (h->n_mc%s->mb_width ==0){ 1.181 + h->n_mc+=(spe->spe_total-1)*s->mb_width; 1.182 + } 1.183 + } 1.184 + h->next_mb_idx++; 1.185 + if (h->next_mb_idx % s->mb_width ==0){ 1.186 + h->next_mb_idx+=(spe->spe_total-1)*s->mb_width; 1.187 + h->curr_line+=spe->spe_total; 1.188 + } 1.189 + 1.190 + h->mb_mc = (h->mb_mc+1)%3; 1.191 + next_mb = &mb_buf[h->mb_dec]; 1.192 + h->mb_dec = (h->mb_dec+1)%3; 1.193 + return next_mb; 1.194 +} 1.195 + 1.196 +static void *get_next_mb_blocking(H264Context_spu *h){ 1.197 + H264slice *s = h->s; 1.198 + H264spe *spe = &h->spe; 1.199 + H264Mb *mb_buf = h->mb_buf; 1.200 + H264mc *mc_buf = h->mc_buf; 1.201 + H264Mb *next_mb; 1.202 + H264Mb *next_dma_mb; 1.203 + 1.204 + if (h->mb_id >= h->mb_total) 1.205 + return NULL; 1.206 + 1.207 + //printf("%d\n", h->mb_id); 1.208 + next_dma_mb = s->blocks + h->mb_id; 1.209 + spu_dma_get(&mb_buf[0], (unsigned) next_dma_mb, sizeof(H264Mb), MBD_buf1); 1.210 + //h->mb_dma = (h->mb_dma+1)%3; 1.211 + h->mb_id++; 1.212 + if (h->mb_id%s->mb_width ==0){ 1.213 + h->mb_id+=(spe->spe_total-1)*s->mb_width; 1.214 + } 1.215 + wait_dma_id(MBD_buf1); 1.216 + 1.217 + h->mc = &mc_buf[0]; 1.218 + //h->mc_idx = (h->mc_idx+1)%2; 1.219 + //if (h->n_mc < h->mb_total){ 1.220 + H264Mb *mb = &mb_buf[0]; 1.221 + H264mc *mc = &mc_buf[0]; 1.222 + if(!IS_INTRA(mb->mb_type)){ 1.223 + calc_mc_params(mb, mc); 1.224 + fill_ref_buf(h, mb, mc); 1.225 + } 1.226 + //h->n_mc++; 1.227 + /*if (h->n_mc%s->mb_width ==0){ 1.228 + h->n_mc+=(spe->spe_total-1)*s->mb_width; 1.229 + }*/ 1.230 +// wait_dma_id(MBD_mc_buf1); 1.231 + 1.232 +// h->next_mb_idx++; 1.233 +// if (h->next_mb_idx % s->mb_width ==0){ 1.234 +// h->next_mb_idx+=(spe->spe_total-1)*s->mb_width; 1.235 +// h->curr_line+=spe->spe_total; 1.236 +// } 1.237 + 1.238 +// h->mb_mc = (h->mb_mc+1)%3; 1.239 + next_mb = &mb_buf[0]; 1.240 +// h->mb_dec = (h->mb_dec+1)%3; 1.241 + return next_mb; 1.242 +} 1.243 + 1.244 + 1.245 +#undef TAG_OFFSET_MB 1.246 +#undef TAG_OFFSET_MC 1.247 +static inline int dep_resolved(H264Context_spu *h){ 1.248 + H264slice *s = h->s; 1.249 + int spe_id = h->spe.spe_id; 1.250 + volatile int mb_proc_dep = src_spe.count; 1.251 + if (spe_id==0) 1.252 + return (h->mb_proc < mb_proc_dep-1 +s->mb_width)? 1:0; 1.253 + else 1.254 + return (h->mb_proc < mb_proc_dep-1)? 1:0; 1.255 +} 1.256 + 1.257 +void update_tgt_spe_dep(H264Context_spu *h, int end){ 1.258 + H264Mb *mb = h->mb; 1.259 + H264slice *s = h->s; 1.260 + H264spe *spe = &h->spe; 1.261 + int mb_x = mb->mb_x; 1.262 + 1.263 + if (end || (mb_x%2==0 && mb_x!=0) || mb_x==s->mb_width-1){ 1.264 + spe_pos* dma_spe = &dma_temp; 1.265 + spe_pos* tgt_spe = (spe_pos*) ((unsigned) spe->tgt_spe + (unsigned) &src_spe); //located in target spe local store 1.266 + dma_spe->count = end? h->mb_proc+1: h->mb_proc; 1.267 + spu_dma_barrier_put(dma_spe, (unsigned) tgt_spe, sizeof(dma_temp), MBD_put); 1.268 + } 1.269 + h->mb_proc++; 1.270 +} 1.271 + 1.272 + 1.273 +int main(unsigned long long id, unsigned long long argp) 1.274 +{ 1.275 + (void) id; 1.276 + H264Context_spu* h = &h_context; 1.277 + H264spe *spe_params = (H264spe *) (unsigned) argp; 1.278 + 1.279 + spu_dma_get(&h->spe, (unsigned) spe_params, sizeof(H264spe), MBD_slice); //ID_slice is used out of convienience 1.280 + wait_dma_id(MBD_slice); 1.281 + 1.282 + //clear_statistic(); 1.283 + dsputil_h264_init_cell(&h->dsp); 1.284 + ff_cropTbl_init(); 1.285 + init_pred_ptrs(&h->hpc); 1.286 + 1.287 + //send slice_buf to ppe 1.288 + spu_write_out_mbox((unsigned) h->slice_buf); 1.289 + h->sl_idx=0; 1.290 + // initialize tracing with paraver 1.291 + //trace_init_SPU(); 1.292 + h->frames =0; 1.293 + src_spe.count =0; 1.294 + h->mb_proc = 0; 1.295 + 1.296 + h->mb_id=0; 1.297 + h->mc_idx=0; 1.298 + h->mb_dec=0; 1.299 + h->mb_mc=0; 1.300 + h->mb_dma=0; 1.301 + h->next_mb_idx=0; 1.302 + 1.303 + h->blocking=0; 1.304 + 1.305 + 1.306 + H264spe* p = &h->spe; 1.307 + h->curr_line =p->spe_id; 1.308 + h->mb_total = p->mb_height*p->mb_width; 1.309 + int stride_y = 32; 1.310 + int stride_c = 16; 1.311 + //init block_offset array 1.312 + init_block_offset(stride_y, stride_c); 1.313 + for(;;){ 1.314 + spu_read_in_mbox(); 1.315 + 1.316 + h->s = &h->slice_buf[h->sl_idx]; 1.317 + h->sl_idx++; h->sl_idx%=2; 1.318 + 1.319 + if (h->s->state< 0){ 1.320 + break; 1.321 + } 1.322 + 1.323 + { 1.324 + if(!h->blocking){ 1.325 + init_mb_buffer(h); 1.326 + while((h->mb=(H264Mb *)get_next_mb(h))){ 1.327 + while(!dep_resolved(h)); 1.328 + //printf("frame %d mbx %d\t mby %d id %d\n", h->frames, h->mb->mb_x, h->mb->mb_y, p- >spe_id); 1.329 + hl_decode_mb_internal(h, stride_y, stride_c); 1.330 + } 1.331 + update_tgt_spe_dep(h, 1); 1.332 + }else{ 1.333 + h->mb_id=0; 1.334 + while((h->mb=(H264Mb *)get_next_mb_blocking(h))){ 1.335 + while(!dep_resolved(h)); 1.336 + //printf("frame %d mbx %d\t mby %d id %d\n", h->frames, h->mb->mb_x, h->mb->mb_y, p- >spe_id); 1.337 + hl_decode_mb_internal(h, stride_y, stride_c); 1.338 + } 1.339 + update_tgt_spe_dep(h, 1); 1.340 + } 1.341 + 1.342 + } 1.343 + 1.344 + h->frames++; 1.345 + 1.346 + if (p->spe_id == ((h->frames*p->mb_height -1)%p->spe_total)){ 1.347 + //printf("spe %d, %d\n", atomic_read(p->rl_cnt), h->frames); 1.348 + //MBSlice is copied beforehand. 1.349 + //only inc cnt. 1.350 + atomic_inc(p->rl_cnt); 1.351 + } 1.352 + { 1.353 + atomic_dec(p->cnt); 1.354 + } 1.355 + } 1.356 + 1.357 + return 0; 1.358 +} 1.359 +
