Mercurial > cgi-bin > hgwebdir.cgi > PR > Applications > VSs > VSs__H264__App
comparison libavcodec/h264_ompss.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 | 0b056460c67d |
comparison
equal
deleted
inserted
replaced
| -1:000000000000 | 0:cad5b3926624 |
|---|---|
| 1 /* | |
| 2 * H.26L/H.264/AVC/JVT/14496-10/... encoder/decoder | |
| 3 * Copyright (c) 2003 Michael Niedermayer <michaelni@gmx.at> | |
| 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 #include "h264_types.h" | |
| 22 #include "h264_parser.h" | |
| 23 #include "h264_nal.h" | |
| 24 #include "h264_entropy.h" | |
| 25 #include "h264_rec.h" | |
| 26 #include "h264_pred_mode.h" | |
| 27 #include "h264_misc.h" | |
| 28 // #undef NDEBUG | |
| 29 #include <assert.h> | |
| 30 | |
| 31 #pragma omp task inout(*pc, *nc) output(*sbe) | |
| 32 static void parse_task(H264Context *h, ParserContext *pc, NalContext *nc, SliceBufferEntry *sbe){ | |
| 33 H264Slice *s; | |
| 34 | |
| 35 if (!sbe->initialized){ | |
| 36 init_sb_entry(h, sbe); | |
| 37 sbe->lines_total=h->mb_height; | |
| 38 } | |
| 39 | |
| 40 av_read_frame_internal(pc, &sbe->gb); | |
| 41 s = &sbe->slice; | |
| 42 | |
| 43 decode_nal_units(nc, s, &sbe->gb); | |
| 44 } | |
| 45 | |
| 46 #pragma omp task inout(*ec) inout(*sbe) | |
| 47 static void decode_slice_entropy_task(H264Context *h, EntropyContext *ec, SliceBufferEntry *sbe){ | |
| 48 int i,j; | |
| 49 H264Slice *s = &sbe->slice; | |
| 50 GetBitContext *gb = &sbe->gb; | |
| 51 H264Mb *mbs = sbe->mbs; | |
| 52 // GetBitContext *gb = s->gb; | |
| 53 CABACContext *c = &ec->c; | |
| 54 | |
| 55 if( !s->pps.cabac ){ | |
| 56 av_log(AV_LOG_ERROR, "Only cabac encoded streams are supported\n"); | |
| 57 return ; | |
| 58 } | |
| 59 | |
| 60 init_dequant_tables(s, ec); | |
| 61 ec->curr_qscale = s->qscale; | |
| 62 ec->last_qscale_diff = 0; | |
| 63 ec->chroma_qp[0] = get_chroma_qp((H264Slice *) s, 0, s->qscale); | |
| 64 ec->chroma_qp[1] = get_chroma_qp((H264Slice *) s, 1, s->qscale); | |
| 65 | |
| 66 /* realign */ | |
| 67 align_get_bits( gb ); | |
| 68 /* init cabac */ | |
| 69 ff_init_cabac_decoder( c, gb->buffer + get_bits_count(gb)/8, (get_bits_left(gb) + 7)/8); | |
| 70 | |
| 71 ff_h264_init_cabac_states(ec, s, c); | |
| 72 | |
| 73 for(j=0; j<ec->mb_height; j++){ | |
| 74 init_entropy_buf(ec, s, j); | |
| 75 for(i=0; i<ec->mb_width; i++){ | |
| 76 int eos,ret; | |
| 77 H264Mb *m = &mbs[i + j*ec->mb_width]; | |
| 78 m->mb_x=i; | |
| 79 m->mb_y=j; | |
| 80 ec->m = m; | |
| 81 | |
| 82 ret = ff_h264_decode_mb_cabac(ec, s, c); | |
| 83 eos = get_cabac_terminate( c); | |
| 84 (void) eos; | |
| 85 if( ret < 0 || c->bytestream > c->bytestream_end + 2) { | |
| 86 av_log(AV_LOG_ERROR, "error while decoding MB %d %d, bytestream (%td)\n", m->mb_x, m->mb_y, c->bytestream_end - c->bytestream); | |
| 87 return ; | |
| 88 } | |
| 89 } | |
| 90 } | |
| 91 } | |
| 92 | |
| 93 static void decode_super_mb_block(MBRecContext *d, H264Slice *s, SuperMBContext *smbc, H264Mb *mbs, int smb_x, int smb_y){ | |
| 94 MBRecState mrs; | |
| 95 // memset(&mrs, 0, sizeof(MBRecState)); | |
| 96 | |
| 97 for (int k=0, i= smb_y; i< smb_y + smbc->smb_height; i++, k++){ | |
| 98 init_mbrec_context(d, &mrs, s, i); | |
| 99 for (int j= smb_x -k ; j< smb_x - k + smbc->smb_width; j++){ | |
| 100 if (i< d->mb_height && j >= 0 && j < d->mb_width){ | |
| 101 h264_decode_mb_internal (d, &mrs, s, &mbs[i*d->mb_width+j]); | |
| 102 } | |
| 103 } | |
| 104 } | |
| 105 } | |
| 106 | |
| 107 #pragma omp task input(*d, *sbe, *ml, *mur) inout(*m) | |
| 108 static void decode_super_mb_task(MBRecContext *d, SliceBufferEntry *sbe, SuperMBContext *smbc, SuperMBTask *ml, | |
| 109 SuperMBTask *mur, SuperMBTask *m){ | |
| 110 H264Slice *s = &sbe->slice; | |
| 111 H264Mb *mbs = sbe->mbs; | |
| 112 decode_super_mb_block(d, s, smbc, mbs, m->smb_x, m->smb_y); | |
| 113 } | |
| 114 | |
| 115 #pragma omp task input(*d, *sbe) inout(*sm) | |
| 116 static void draw_edges_task(MBRecContext *d, SliceBufferEntry *sbe, SuperMBContext *smbc, SuperMBTask *sm, int line){ | |
| 117 H264Slice *s = &sbe->slice; | |
| 118 for (int i=line*smbc->smb_height; i< (line+1)*smbc->smb_height && i< d->mb_height; i++) | |
| 119 draw_edges(d, s, i); | |
| 120 } | |
| 121 | |
| 122 static void decode_mb_in_slice(H264Context *h, MBRecContext *d, SliceBufferEntry *sbe){ | |
| 123 int i,j; | |
| 124 | |
| 125 SuperMBContext *smbc = acquire_smbc(h); | |
| 126 int smb_height =smbc->nsmb_height, smb_width= smbc->nsmb_width; | |
| 127 SuperMBTask *smbs = smbc->smbs[0]; | |
| 128 | |
| 129 SuperMBTask *sm=NULL, *sml, *smur; | |
| 130 for(j=0; j< smb_height; j++){ | |
| 131 for(i=0; i< smb_width; i++){ | |
| 132 sm = smbs + j*smb_width + i; | |
| 133 sml = sm - ((i > 0) ? 1: 0); | |
| 134 smur = sm + (((i < smb_width-1) && (j >0)) ? -smb_width+1: 0); | |
| 135 decode_super_mb_task(d, sbe, smbc, sml, smur, sm); | |
| 136 } | |
| 137 draw_edges_task(d, sbe, smbc, sm, j); | |
| 138 } | |
| 139 #pragma omp taskwait on(*sm) | |
| 140 | |
| 141 release_smbc(h, smbc); | |
| 142 } | |
| 143 | |
| 144 #pragma omp task inout(*d) inout(*sbe) | |
| 145 static void decode_slice_mb_task(H264Context *h, MBRecContext *d, SliceBufferEntry *sbe){ | |
| 146 H264Slice *s = &sbe->slice; | |
| 147 | |
| 148 for (int i=0; i<2; i++){ | |
| 149 for(int j=0; j< s->ref_count[i]; j++){ | |
| 150 if (s->ref_list_cpn[i][j] ==-1) | |
| 151 continue; | |
| 152 int k; | |
| 153 for (k=0; k< h->max_dpb_cnt; k++){ | |
| 154 if(h->dpb[k].reference >= 2 && h->dpb[k].cpn == s->ref_list_cpn[i][j]){ | |
| 155 s->dp_ref_list[i][j] = &h->dpb[k]; | |
| 156 break; | |
| 157 } | |
| 158 } | |
| 159 } | |
| 160 } | |
| 161 | |
| 162 #pragma omp critical (dpb) | |
| 163 get_dpb_entry(h, s); | |
| 164 | |
| 165 if (!h->no_mbd){ | |
| 166 decode_mb_in_slice (h, d, sbe); | |
| 167 } | |
| 168 | |
| 169 for (int i=0; i<s->release_cnt; i++){ | |
| 170 for(int j=0; j<h->max_dpb_cnt; j++){ | |
| 171 if(h->dpb[j].cpn== s->release_ref_cpn[i]){ | |
| 172 #pragma omp critical (dpb) | |
| 173 release_dpb_entry(h, &h->dpb[j], 2); | |
| 174 break; | |
| 175 } | |
| 176 } | |
| 177 } | |
| 178 s->release_cnt=0; | |
| 179 } | |
| 180 | |
| 181 // for static 3d wave | |
| 182 /*-------------------------------------------------------------------------------*/ | |
| 183 #pragma omp task input(*d, *sbe, *ml, *mur, *mprev) inout(*m) | |
| 184 static void decode_3dwave_super_mb_task(MBRecContext *d, SliceBufferEntry *sbe, SuperMBContext *smbc, SuperMBTask *ml, | |
| 185 SuperMBTask *mur, SuperMBTask *mprev, SuperMBTask *m){ | |
| 186 H264Slice *s = &sbe->slice; | |
| 187 H264Mb *mbs = sbe->mbs; | |
| 188 | |
| 189 decode_super_mb_block(d, s, smbc, mbs, m->smb_x, m->smb_y); | |
| 190 } | |
| 191 | |
| 192 // int init_ref_count=0; | |
| 193 #pragma omp task inout(*d, *sbe, *init) | |
| 194 static void init_ref_list_and_get_dpb_task(H264Context *h, MBRecContext *d, SliceBufferEntry *sbe, int *init){ | |
| 195 H264Slice *s = &sbe->slice; | |
| 196 for (int i=0; i<2; i++){ | |
| 197 for(int j=0; j< s->ref_count[i]; j++){ | |
| 198 if (s->ref_list_cpn[i][j] ==-1) | |
| 199 continue; | |
| 200 int k; | |
| 201 for (k=0; k<h->max_dpb_cnt; k++){ | |
| 202 if(h->dpb[k].reference >= 2 && h->dpb[k].cpn == s->ref_list_cpn[i][j]){ | |
| 203 s->dp_ref_list[i][j] = &h->dpb[k]; | |
| 204 break; | |
| 205 } | |
| 206 } | |
| 207 } | |
| 208 } | |
| 209 | |
| 210 #pragma omp critical (dpb) | |
| 211 get_dpb_entry(h, s); | |
| 212 | |
| 213 } | |
| 214 | |
| 215 static SuperMBTask* add_decode_slice_3dwave_tasks(MBRecContext *d, SliceBufferEntry *sbe, SuperMBContext *smbc){ | |
| 216 int i,j; | |
| 217 | |
| 218 int smb_3d_height =smbc->nsmb_3dheight; | |
| 219 int smb_height =smbc->nsmb_height, smb_width= smbc->nsmb_width; | |
| 220 int smb_diff_prev = smb_height - smb_3d_height; | |
| 221 SuperMBTask *sm=NULL, *sml, *smur, *smprev; | |
| 222 | |
| 223 SuperMBTask *smbs = smbc->smbs[smbc->index++]; smbc->index%=2; | |
| 224 SuperMBTask *smbs_prev = smbc->smbs[smbc->index]; // index rotates -> next == prev | |
| 225 | |
| 226 for(j=0; j<smb_3d_height ; j++){ | |
| 227 for(i=0; i< smb_width; i++){ | |
| 228 sm = smbs + j*smb_width + i; | |
| 229 sml = sm - ((i > 0) ? 1: 0); | |
| 230 smur = sm + (((i < smb_width-1) && (j >0)) ? -smb_width+1: 0); | |
| 231 smprev = smbs_prev + (j + smb_diff_prev+1)*smb_width -1; | |
| 232 decode_3dwave_super_mb_task(d, sbe, smbc, sml, smur, smprev, sm); | |
| 233 } | |
| 234 draw_edges_task(d, sbe, smbc, sm, j); | |
| 235 } | |
| 236 | |
| 237 for(; j< smb_height; j++){ | |
| 238 for(i=0; i< smb_width; i++){ | |
| 239 sm = smbs + j*smb_width + i; | |
| 240 sml = sm - ((i > 0) ? 1: 0); | |
| 241 smur = sm + (((i < smb_width-1) && (j >0)) ? -smb_width+1: 0); | |
| 242 decode_super_mb_task(d, sbe, smbc, sml, smur, sm); | |
| 243 } | |
| 244 draw_edges_task(d, sbe, smbc, sm, j); | |
| 245 } | |
| 246 return sm; | |
| 247 } | |
| 248 | |
| 249 #pragma omp task inout(*d, *sbe, *release) input (*lastsmb) | |
| 250 static void release_ref_list_task(H264Context *h, SuperMBContext *smbc, MBRecContext *d, SliceBufferEntry *sbe, SuperMBTask *lastsmb, int *release){ | |
| 251 H264Slice *s = &sbe->slice; | |
| 252 for (int i=0; i<s->release_cnt; i++){ | |
| 253 for(int j=0; j<h->max_dpb_cnt; j++){ | |
| 254 if(h->dpb[j].cpn== s->release_ref_cpn[i]){ | |
| 255 #pragma omp critical (dpb) | |
| 256 release_dpb_entry(h, &h->dpb[j], 2); | |
| 257 break; | |
| 258 } | |
| 259 } | |
| 260 } | |
| 261 s->release_cnt=0; | |
| 262 | |
| 263 release_smbc(h, smbc); | |
| 264 | |
| 265 } | |
| 266 | |
| 267 // static void decode_mb_static_3dwave(H264Context *h, int mb_height, int mb_width, MBRecContext *d, H264Slice *s, H264Mb *mbs, SuperMBTask *smbs, SuperMBTask *smbs_prev){ | |
| 268 // | |
| 269 // } | |
| 270 /*-------------------------------------------------------------------------------*/ | |
| 271 //end for static 3d wave | |
| 272 | |
| 273 #pragma omp task inout (*oc) input(*sbe) | |
| 274 static void output_task(H264Context *h, OutputContext *oc, SliceBufferEntry *sbe){ | |
| 275 DecodedPicture* out =output_frame(h, oc, sbe->slice.curr_pic, h->ofile, h->frame_width, h->frame_height); | |
| 276 if (out){ | |
| 277 #pragma omp critical (dpb) | |
| 278 release_dpb_entry(h, out, 1); | |
| 279 } | |
| 280 print_report(oc->frame_number, oc->video_size, 0, h->verbose); | |
| 281 } | |
| 282 | |
| 283 /* | |
| 284 * The following code is the main loop of the file converter | |
| 285 */ | |
| 286 //Put VMS entry point here | |
| 287 int h264_decode_ompss( H264Context *h) { | |
| 288 const int bufs = h->pipe_bufs; | |
| 289 | |
| 290 ParserContext *pc; | |
| 291 NalContext *nc; | |
| 292 EntropyContext *ec[bufs]; | |
| 293 MBRecContext *rc[2]; | |
| 294 OutputContext *oc; | |
| 295 SliceBufferEntry *sbe; | |
| 296 SuperMBContext *smbc; | |
| 297 | |
| 298 DecodedPicture *out; | |
| 299 int frames=0; | |
| 300 | |
| 301 #if HAVE_LIBSDL2 | |
| 302 pthread_t sdl_thr; | |
| 303 if (h->display){ | |
| 304 pthread_create(&sdl_thr, NULL, sdl_thread, h); | |
| 305 } | |
| 306 #endif | |
| 307 sbe= av_mallocz(sizeof(SliceBufferEntry) * bufs); | |
| 308 | |
| 309 | |
| 310 pc = get_parse_context(h->ifile); | |
| 311 nc = get_nal_context(h->width, h->height); | |
| 312 | |
| 313 for(int i=0; i<bufs; i++){ | |
| 314 ec[i] = get_entropy_context( h ); | |
| 315 } | |
| 316 | |
| 317 for(int i=0; i<2; i++){ | |
| 318 rc[i] = get_mbrec_context(h); | |
| 319 } | |
| 320 | |
| 321 oc = get_output_context( h ); | |
| 322 | |
| 323 av_start_timer(); | |
| 324 int k=0; int init, release; | |
| 325 if (h->static_3d && bufs < h->num_frames ){ | |
| 326 int num_pre_ed =0; | |
| 327 for (num_pre_ed=0; num_pre_ed< bufs -1 && !pc->final_frame; num_pre_ed++){ | |
| 328 parse_task( h, pc, nc, &sbe[k%bufs] ); | |
| 329 decode_slice_entropy_task(h, ec[k%bufs], &sbe[k%bufs]); | |
| 330 #pragma omp taskwait on(*pc) | |
| 331 k++; | |
| 332 } | |
| 333 | |
| 334 while(!pc->final_frame && frames++ < h->num_frames && !h->quit){ | |
| 335 parse_task( h, pc, nc, &sbe[k%bufs] ); | |
| 336 decode_slice_entropy_task(h, ec[k%bufs], &sbe[k%bufs]); | |
| 337 | |
| 338 k++; | |
| 339 | |
| 340 init_ref_list_and_get_dpb_task(h, rc[k%2], &sbe[k%bufs], &init); | |
| 341 smbc = acquire_smbc(h); | |
| 342 SuperMBTask *lastsmb= add_decode_slice_3dwave_tasks(rc[k%2], &sbe[k%bufs], smbc); | |
| 343 release_ref_list_task(h, smbc, rc[k%2], &sbe[k%bufs], lastsmb, &release); | |
| 344 | |
| 345 output_task (h, oc, &sbe[k%bufs]); | |
| 346 #pragma omp taskwait on(*pc) | |
| 347 } | |
| 348 | |
| 349 for (int i=0; i< num_pre_ed; i++){ | |
| 350 k++; | |
| 351 init_ref_list_and_get_dpb_task(h, rc[k%2], &sbe[k%bufs], &init); | |
| 352 smbc = acquire_smbc(h); | |
| 353 SuperMBTask *lastsmb= add_decode_slice_3dwave_tasks(rc[k%2], &sbe[k%bufs], smbc); | |
| 354 release_ref_list_task(h, smbc, rc[k%2], &sbe[k%bufs], lastsmb, &release); | |
| 355 | |
| 356 output_task (h, oc, &sbe[k%bufs]); | |
| 357 } | |
| 358 | |
| 359 } else { | |
| 360 while(!pc->final_frame && frames++ < h->num_frames && !h->quit){ | |
| 361 parse_task( h, pc, nc, &sbe[k%bufs] ); | |
| 362 | |
| 363 decode_slice_entropy_task(h, ec[k%bufs], &sbe[k%bufs]); | |
| 364 | |
| 365 decode_slice_mb_task(h, rc[0], &sbe[k%bufs]); | |
| 366 | |
| 367 output_task (h, oc, &sbe[k%bufs]); | |
| 368 #pragma omp taskwait on(*pc) | |
| 369 k++; | |
| 370 } | |
| 371 } | |
| 372 #pragma omp taskwait | |
| 373 | |
| 374 while ((out=output_frame(h, oc, NULL, h->ofile, h->frame_width, h->frame_height))) ; | |
| 375 | |
| 376 print_report(oc->frame_number, oc->video_size, 1, h->verbose); | |
| 377 h->num_frames = oc->frame_number; | |
| 378 /* finished ! */ | |
| 379 | |
| 380 free_parse_context(pc); | |
| 381 free_nal_context (nc); | |
| 382 free_output_context(oc); | |
| 383 for (int i=0; i<bufs; i++){ | |
| 384 free_sb_entry(&sbe[i]); | |
| 385 free_entropy_context(ec[i]); | |
| 386 } | |
| 387 av_free(sbe); | |
| 388 | |
| 389 for (int i=0; i<2; i++){ | |
| 390 free_mbrec_context(rc[i]); | |
| 391 } | |
| 392 | |
| 393 #if HAVE_LIBSDL2 | |
| 394 if (h->display){ | |
| 395 signal_sdl_exit(h); | |
| 396 pthread_join(sdl_thr, NULL); | |
| 397 } | |
| 398 #endif | |
| 399 | |
| 400 return 0; | |
| 401 } |
