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