view libavcodec/h264_ompss.c @ 9:ea1ba68cf0ed

update to match api changes + add sscc produced source
author Nina Engelhardt <nengel@mailbox.tu-berlin.de>
date Wed, 05 Jun 2013 14:43:26 +0200
parents 6c1433f5a562
children
line source
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 #include "VSs_impl/VSs.h"
32 typedef struct{
33 ParserContext *pc;
34 NalContext *nc;
35 SliceBufferEntry *sbe;
36 H264Context *h;
37 } parse_taskArgs;
39 int32 parse_taskArgTypes[3] = {INOUT, INOUT, OUTPUT};
40 size_t parse_taskArgSizes[3] = {sizeof(ParserContext), sizeof(NalContext), sizeof(SliceBufferEntry)};
42 //#pragma omp task inout(*pc, *nc) output(*sbe)
43 static void parse_task(void *_data){
44 parse_taskArgs* args = (parse_taskArgs*) _data;
45 ParserContext *pc = args->pc;
46 NalContext *nc = args->nc;
47 SliceBufferEntry *sbe = args->sbe;
48 H264Context *h = args->h;
49 H264Slice *s;
51 if (!sbe->initialized){
52 init_sb_entry(h, sbe);
53 sbe->lines_total=h->mb_height;
54 }
56 av_read_frame_internal(pc, &sbe->gb);
57 s = &sbe->slice;
59 decode_nal_units(nc, s, &sbe->gb);
61 return;
62 }
64 VSsTaskType parse_taskType = {
65 .fn = &parse_task,
66 .numDeps = 3,
67 .sizeOfArgs = sizeof(parse_taskArgs),
68 .depsTypes = parse_taskArgTypes,
69 .depsSizes = parse_taskArgSizes};
72 typedef struct{
73 EntropyContext *ec;
74 SliceBufferEntry *sbe;
75 H264Context *h;
76 } decode_slice_entropy_taskArgs;
78 int32 decode_slice_entropy_taskArgTypes[2] = {INOUT, INOUT};
79 size_t decode_slice_entropy_taskArgSizes[2] = {sizeof(EntropyContext), sizeof(SliceBufferEntry)};
81 //#pragma omp task inout(*ec) inout(*sbe)
82 static void decode_slice_entropy_task(void *_data){
83 decode_slice_entropy_taskArgs* args = (decode_slice_entropy_taskArgs*) _data;
84 EntropyContext *ec = args->ec;
85 SliceBufferEntry *sbe = args->sbe;
86 H264Context *h = args->h;
87 int i,j;
88 H264Slice *s = &sbe->slice;
89 GetBitContext *gb = &sbe->gb;
90 H264Mb *mbs = sbe->mbs;
91 // GetBitContext *gb = s->gb;
92 CABACContext *c = &ec->c;
94 if( !s->pps.cabac ){
95 av_log(AV_LOG_ERROR, "Only cabac encoded streams are supported\n");
96 return;
97 }
99 init_dequant_tables(s, ec);
100 ec->curr_qscale = s->qscale;
101 ec->last_qscale_diff = 0;
102 ec->chroma_qp[0] = get_chroma_qp((H264Slice *) s, 0, s->qscale);
103 ec->chroma_qp[1] = get_chroma_qp((H264Slice *) s, 1, s->qscale);
105 /* realign */
106 align_get_bits( gb );
107 /* init cabac */
108 ff_init_cabac_decoder( c, gb->buffer + get_bits_count(gb)/8, (get_bits_left(gb) + 7)/8);
110 ff_h264_init_cabac_states(ec, s, c);
112 for(j=0; j<ec->mb_height; j++){
113 init_entropy_buf(ec, s, j);
114 for(i=0; i<ec->mb_width; i++){
115 int eos,ret;
116 H264Mb *m = &mbs[i + j*ec->mb_width];
117 m->mb_x=i;
118 m->mb_y=j;
119 ec->m = m;
121 ret = ff_h264_decode_mb_cabac(ec, s, c);
122 eos = get_cabac_terminate( c);
123 (void) eos;
124 if( ret < 0 || c->bytestream > c->bytestream_end + 2) {
125 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);
126 return;
127 }
128 }
129 }
130 return;
131 }
133 VSsTaskType decode_slice_entropy_taskType = {
134 .fn = &decode_slice_entropy_task,
135 .numDeps = 2,
136 .sizeOfArgs = sizeof(decode_slice_entropy_taskArgs),
137 .depsTypes = decode_slice_entropy_taskArgTypes,
138 .depsSizes = decode_slice_entropy_taskArgSizes};
141 static void decode_super_mb_block(MBRecContext *d, H264Slice *s, SuperMBContext *smbc, H264Mb *mbs, int smb_x, int smb_y){
142 MBRecState mrs;
143 // memset(&mrs, 0, sizeof(MBRecState));
145 for (int k=0, i= smb_y; i< smb_y + smbc->smb_height; i++, k++){
146 init_mbrec_context(d, &mrs, s, i);
147 for (int j= smb_x -k ; j< smb_x - k + smbc->smb_width; j++){
148 if (i< d->mb_height && j >= 0 && j < d->mb_width){
149 h264_decode_mb_internal (d, &mrs, s, &mbs[i*d->mb_width+j]);
150 }
151 }
152 }
153 }
155 typedef struct{
156 MBRecContext *d;
157 SliceBufferEntry *sbe;
158 SuperMBTask *ml;
159 SuperMBTask *mur;
160 SuperMBTask *m;
161 SuperMBContext *smbc;
162 } decode_super_mb_taskArgs;
164 int32 decode_super_mb_taskArgTypes[5] = {IN, IN, IN, IN, INOUT};
165 size_t decode_super_mb_taskArgSizes[5] = {sizeof(MBRecContext), sizeof(SliceBufferEntry), sizeof(SuperMBTask), sizeof(SuperMBTask), sizeof(SuperMBTask)};
167 //#pragma omp task input(*d, *sbe, *ml, *mur) inout(*m)
168 static void decode_super_mb_task(void *_data){
169 decode_super_mb_taskArgs* args = (decode_super_mb_taskArgs*) _data;
170 MBRecContext *d = args->d;
171 SliceBufferEntry *sbe = args->sbe;
172 SuperMBTask *ml = args->ml;
173 SuperMBTask *mur = args->mur;
174 SuperMBTask *m = args->m;
175 SuperMBContext *smbc = args->smbc;
176 H264Slice *s = &sbe->slice;
177 H264Mb *mbs = sbe->mbs;
178 decode_super_mb_block(d, s, smbc, mbs, m->smb_x, m->smb_y);
179 return;
180 }
182 VSsTaskType decode_super_mb_taskType = {
183 .fn = &decode_super_mb_task,
184 .numDeps = 5,
185 .sizeOfArgs = sizeof(decode_super_mb_taskArgs),
186 .depsTypes = decode_super_mb_taskArgTypes,
187 .depsSizes = decode_super_mb_taskArgSizes};
191 typedef struct{
192 MBRecContext *d;
193 SliceBufferEntry *sbe;
194 SuperMBTask *sm;
195 SuperMBContext *smbc;
196 int* line;
197 } draw_edges_taskArgs;
199 int32 draw_edges_taskArgTypes[3] = {IN, IN, INOUT};
200 size_t draw_edges_taskArgSizes[3] = {sizeof(MBRecContext), sizeof(SliceBufferEntry), sizeof(SuperMBTask)};
202 //#pragma omp task input(*d, *sbe) inout(*sm)
203 static void draw_edges_task(void *_data){
204 draw_edges_taskArgs* args = (draw_edges_taskArgs*) _data;
205 MBRecContext *d = args->d;
206 SliceBufferEntry *sbe = args->sbe;
207 SuperMBTask *sm = args->sm;
208 SuperMBContext *smbc = args->smbc;
209 int line = *(args->line);
210 H264Slice *s = &sbe->slice;
211 for (int i=line*smbc->smb_height; i< (line+1)*smbc->smb_height && i< d->mb_height; i++)
212 draw_edges(d, s, i);
213 VMS_App__free(args->line);
214 return;
215 }
216 VSsTaskType draw_edges_taskType = {
217 .fn = &draw_edges_task,
218 .numDeps = 3,
219 .sizeOfArgs = sizeof(draw_edges_taskArgs),
220 .depsTypes = draw_edges_taskArgTypes,
221 .depsSizes = draw_edges_taskArgSizes};
224 static void decode_mb_in_slice(H264Context *h, MBRecContext *d, SliceBufferEntry *sbe){
225 int i,j;
227 SuperMBContext *smbc = acquire_smbc(h);
228 int smb_height =smbc->nsmb_height, smb_width= smbc->nsmb_width;
229 SuperMBTask *smbs = smbc->smbs[0];
231 SuperMBTask *sm=NULL, *sml, *smur;
232 for(j=0; j< smb_height; j++){
233 for(i=0; i< smb_width; i++){
234 sm = smbs + j*smb_width + i;
235 sml = sm - ((i > 0) ? 1: 0);
236 smur = sm + (((i < smb_width-1) && (j >0)) ? -smb_width+1: 0);
237 decode_super_mb_taskArgs decode_super_mb_task_args;
238 decode_super_mb_task_args.d = d;
239 decode_super_mb_task_args.sbe = sbe;
240 decode_super_mb_task_args.smbc = smbc;
241 decode_super_mb_task_args.ml = sml;
242 decode_super_mb_task_args.mur = smur;
243 decode_super_mb_task_args.m = sm;
244 void** depsAddrs = malloc(decode_super_mb_taskType.numDeps * sizeof(void*));
245 /*sizeof(MBRecContext), sizeof(SliceBufferEntry), sizeof(SuperMBTask), sizeof(SuperMBTask), sizeof(SuperMBTask)*/
246 depsAddrs[0] = d;
247 depsAddrs[1] = sbe;
248 depsAddrs[2] = sml;
249 depsAddrs[3] = smur;
250 depsAddrs[4] = sm;
251 VSs__submit_task(&decode_super_mb_taskType, &decode_super_mb_task_args, depsAddrs);
252 }
253 draw_edges_taskArgs draw_edges_task_args;
254 draw_edges_task_args.d = d;
255 draw_edges_task_args.sbe = sbe;
256 draw_edges_task_args.sm = sm;
257 draw_edges_task_args.smbc = smbc;
258 draw_edges_task_args.line = VMS_App__malloc( sizeof(int) );
259 *(draw_edges_task_args.line) = j;
260 void** depsAddrs = malloc(sizeof (void*) * draw_edges_taskType.numDeps);
261 /*sizeof(MBRecContext), sizeof(SliceBufferEntry), sizeof(SuperMBTask)*/
262 depsAddrs[0] = d;
263 depsAddrs[1] = sbe;
264 depsAddrs[2] = sm;
265 VSs__submit_task(&draw_edges_taskType, &draw_edges_task_args, depsAddrs);
266 }
267 VSs__taskwait_on(sm);
268 //#pragma omp taskwait on(*sm)
270 release_smbc(h, smbc);
271 }
273 typedef struct{
274 MBRecContext *d;
275 SliceBufferEntry *sbe;
276 H264Context *h;
277 } decode_slice_mb_taskArgs;
279 int32 decode_slice_mb_taskArgTypes[2] = {INOUT, INOUT};
280 size_t decode_slice_mb_taskArgSizes[2] = {sizeof(MBRecContext), sizeof(SliceBufferEntry)};
282 //#pragma omp task inout(*d) inout(*sbe)
283 static void decode_slice_mb_task(void *_data){
284 decode_slice_mb_taskArgs* args = (decode_slice_mb_taskArgs*) _data;
285 MBRecContext *d = args->d;
286 SliceBufferEntry *sbe = args->sbe;
287 H264Context *h = args->h;
289 H264Slice *s = &sbe->slice;
291 for (int i=0; i<2; i++){
292 for(int j=0; j< s->ref_count[i]; j++){
293 if (s->ref_list_cpn[i][j] ==-1)
294 continue;
295 int k;
296 for (k=0; k< h->max_dpb_cnt; k++){
297 if(h->dpb[k].reference >= 2 && h->dpb[k].cpn == s->ref_list_cpn[i][j]){
298 s->dp_ref_list[i][j] = &h->dpb[k];
299 break;
300 }
301 }
302 }
303 }
305 //#pragma omp critical (dpb)
306 VSs__start_critical(0);
307 get_dpb_entry(h, s);
308 VSs__end_critical(0);
310 if (!h->no_mbd){
311 decode_mb_in_slice (h, d, sbe);
312 }
314 for (int i=0; i<s->release_cnt; i++){
315 for(int j=0; j<h->max_dpb_cnt; j++){
316 if(h->dpb[j].cpn== s->release_ref_cpn[i]){
317 //#pragma omp critical (dpb)
318 VSs__start_critical(0);
319 release_dpb_entry(h, &h->dpb[j], 2);
320 VSs__end_critical(0);
321 break;
322 }
323 }
324 }
325 s->release_cnt=0;
326 return;
327 }
329 VSsTaskType decode_slice_mb_taskType = {
330 .fn = &decode_slice_mb_task,
331 .numDeps = 2,
332 .sizeOfArgs = sizeof(decode_slice_mb_taskArgs),
333 .depsTypes = decode_slice_mb_taskArgTypes,
334 .depsSizes = decode_slice_mb_taskArgSizes};
336 // for static 3d wave
337 /*-------------------------------------------------------------------------------*/
338 typedef struct{
339 MBRecContext *d;
340 SliceBufferEntry *sbe;
341 SuperMBTask *ml;
342 SuperMBTask *mur;
343 SuperMBTask *mprev;
344 SuperMBTask *m;
345 SuperMBContext *smbc;
346 } decode_3dwave_super_mb_taskArgs;
348 int32 decode_3dwave_super_mb_taskArgTypes[6] = {IN, IN, IN, IN, IN, INOUT};
349 size_t decode_3dwave_super_mb_taskArgSizes[6] = {sizeof(MBRecContext), sizeof(SliceBufferEntry), sizeof(SuperMBTask),
350 sizeof(SuperMBTask), sizeof(SuperMBTask), sizeof(SuperMBTask)};
352 //#pragma omp task input(*d, *sbe, *ml, *mur, *mprev) inout(*m)
353 static void decode_3dwave_super_mb_task(void *_data){
354 decode_3dwave_super_mb_taskArgs* args = (decode_3dwave_super_mb_taskArgs*) _data;
355 MBRecContext *d = args->d;
356 SliceBufferEntry *sbe = args->sbe;
357 SuperMBTask *ml = args->ml;
358 SuperMBTask *mur = args->mur;
359 SuperMBTask *mprev = args->mprev;
360 SuperMBTask *m = args->m;
361 SuperMBContext *smbc = args->smbc;
363 H264Slice *s = &sbe->slice;
364 H264Mb *mbs = sbe->mbs;
366 decode_super_mb_block(d, s, smbc, mbs, m->smb_x, m->smb_y);
367 return;
368 }
370 VSsTaskType decode_3dwave_super_mb_taskType = {
371 .fn = &decode_3dwave_super_mb_task,
372 .numDeps = 6,
373 .sizeOfArgs = sizeof(decode_3dwave_super_mb_taskArgs),
374 .depsTypes = decode_3dwave_super_mb_taskArgTypes,
375 .depsSizes = decode_3dwave_super_mb_taskArgSizes};
377 // int init_ref_count=0;
378 typedef struct{
379 MBRecContext *d;
380 SliceBufferEntry *sbe;
381 int* init;
382 H264Context *h;
383 } init_ref_list_and_get_dpb_taskArgs;
385 int32 init_ref_list_and_get_dpb_taskArgTypes[3] = {INOUT, INOUT, INOUT};
386 size_t init_ref_list_and_get_dpb_taskArgSizes[3] = {sizeof(MBRecContext), sizeof(SliceBufferEntry), sizeof(int)};
388 //#pragma omp task inout(*d, *sbe, *init)
389 static void init_ref_list_and_get_dpb_task(void *_data){
390 init_ref_list_and_get_dpb_taskArgs* args = (init_ref_list_and_get_dpb_taskArgs*) _data;
391 MBRecContext *d = args->d;
392 SliceBufferEntry *sbe = args->sbe;
393 int* initp = args->init;
394 H264Context *h = args->h;
396 H264Slice *s = &sbe->slice;
397 for (int i=0; i<2; i++){
398 for(int j=0; j< s->ref_count[i]; j++){
399 if (s->ref_list_cpn[i][j] ==-1)
400 continue;
401 int k;
402 for (k=0; k<h->max_dpb_cnt; k++){
403 if(h->dpb[k].reference >= 2 && h->dpb[k].cpn == s->ref_list_cpn[i][j]){
404 s->dp_ref_list[i][j] = &h->dpb[k];
405 break;
406 }
407 }
408 }
409 }
411 //#pragma omp critical (dpb)
412 VSs__start_critical(0);
413 get_dpb_entry(h, s);
414 VSs__end_critical(0);
416 return;
417 }
419 VSsTaskType init_ref_list_and_get_dpb_taskType = {
420 .fn = &init_ref_list_and_get_dpb_task,
421 .numDeps = 3,
422 .sizeOfArgs = sizeof(init_ref_list_and_get_dpb_taskArgs),
423 .depsTypes = init_ref_list_and_get_dpb_taskArgTypes,
424 .depsSizes = init_ref_list_and_get_dpb_taskArgSizes};
426 static SuperMBTask* add_decode_slice_3dwave_tasks(MBRecContext *d, SliceBufferEntry *sbe, SuperMBContext *smbc, int k){
427 int i,j;
429 int32* taskID;
431 int smb_3d_height =smbc->nsmb_3dheight;
432 int smb_height =smbc->nsmb_height, smb_width= smbc->nsmb_width;
433 int smb_diff_prev = smb_height - smb_3d_height;
434 SuperMBTask *sm=NULL, *sml, *smur, *smprev;
436 SuperMBTask *smbs = smbc->smbs[smbc->index++]; smbc->index%=2;
437 SuperMBTask *smbs_prev = smbc->smbs[smbc->index]; // index rotates -> next == prev
439 for(j=0; j<smb_3d_height ; j++){
440 for(i=0; i< smb_width; i++){
441 sm = smbs + j*smb_width + i;
442 sml = sm - ((i > 0) ? 1: 0);
443 smur = sm + (((i < smb_width-1) && (j >0)) ? -smb_width+1: 0);
444 smprev = smbs_prev + (j + smb_diff_prev+1)*smb_width -1;
445 decode_3dwave_super_mb_taskArgs decode_3dwave_super_mb_task_args;
446 decode_3dwave_super_mb_task_args.d = d;
447 decode_3dwave_super_mb_task_args.sbe = sbe;
448 decode_3dwave_super_mb_task_args.smbc = smbc;
449 decode_3dwave_super_mb_task_args.ml = sml;
450 decode_3dwave_super_mb_task_args.mur = smur;
451 decode_3dwave_super_mb_task_args.mprev = smprev;
452 decode_3dwave_super_mb_task_args.m = sm;
453 taskID = VSs__create_taskID_of_size(3 );
454 void** depsAddrs = malloc(sizeof(void*) * decode_3dwave_super_mb_taskType.numDeps);
455 /*sizeof(MBRecContext), sizeof(SliceBufferEntry), sizeof(SuperMBTask),
456 sizeof(SuperMBTask), sizeof(SuperMBTask), sizeof(SuperMBTask)*/
457 depsAddrs[0] = d;
458 depsAddrs[1] = sbe;
459 depsAddrs[2] = sml;
460 depsAddrs[3] = smur;
461 depsAddrs[4] = smprev;
462 taskID[1] = k;
463 taskID[2] = j;
464 taskID[3] = i;
465 VSs__submit_task_with_ID(&decode_3dwave_super_mb_taskType, &decode_3dwave_super_mb_task_args, depsAddrs, taskID);
466 }
467 draw_edges_taskArgs draw_edges_task_args;
468 draw_edges_task_args.d = d;
469 draw_edges_task_args.sbe = sbe;
470 draw_edges_task_args.sm = sm;
471 draw_edges_task_args.smbc = smbc;
472 draw_edges_task_args.line = VMS_App__malloc( sizeof(int) );
473 *(draw_edges_task_args.line) = j;
474 void** depsAddrs = malloc(sizeof (void*) * draw_edges_taskType.numDeps);
475 /*sizeof(MBRecContext), sizeof(SliceBufferEntry), sizeof(SuperMBTask)*/
476 depsAddrs[0] = d;
477 depsAddrs[1] = sbe;
478 depsAddrs[2] = sm;
479 taskID = VSs__create_taskID_of_size(3);
480 taskID[1] = k;
481 taskID[2] = j;
482 taskID[3] = i;
483 VSs__submit_task_with_ID(&draw_edges_taskType, &draw_edges_task_args, depsAddrs, taskID);
484 }
486 for(; j< smb_height; j++){
487 for(i=0; i< smb_width; i++){
488 sm = smbs + j*smb_width + i;
489 sml = sm - ((i > 0) ? 1: 0);
490 smur = sm + (((i < smb_width-1) && (j >0)) ? -smb_width+1: 0);
491 decode_super_mb_taskArgs decode_super_mb_task_args;
492 decode_super_mb_task_args.d = d;
493 decode_super_mb_task_args.sbe = sbe;
494 decode_super_mb_task_args.smbc = smbc;
495 decode_super_mb_task_args.ml = sml;
496 decode_super_mb_task_args.mur = smur;
497 decode_super_mb_task_args.m = sm;
498 void** depsAddrs = malloc(sizeof(void*) * decode_super_mb_taskType.numDeps);
499 /*sizeof(MBRecContext), sizeof(SliceBufferEntry), sizeof(SuperMBTask), sizeof(SuperMBTask), sizeof(SuperMBTask)*/
500 depsAddrs[0] = d;
501 depsAddrs[1] = sbe;
502 depsAddrs[2] = sml;
503 depsAddrs[3] = smur;
504 depsAddrs[4] = sm;
505 taskID = VSs__create_taskID_of_size(3 );
506 taskID[1] = k;
507 taskID[2] = j;
508 taskID[3] = i;
509 VSs__submit_task_with_ID(&decode_super_mb_taskType, &decode_super_mb_task_args, depsAddrs, taskID);
510 }
511 draw_edges_taskArgs draw_edges_task_args;
512 draw_edges_task_args.d = d;
513 draw_edges_task_args.sbe = sbe;
514 draw_edges_task_args.sm = sm;
515 draw_edges_task_args.smbc = smbc;
516 draw_edges_task_args.line = VMS_App__malloc( sizeof(int) );
517 *(draw_edges_task_args.line) = j;
518 void** depsAddrs = malloc(sizeof (void*) * draw_edges_taskType.numDeps);
519 /*sizeof(MBRecContext), sizeof(SliceBufferEntry), sizeof(SuperMBTask)*/
520 depsAddrs[0] = d;
521 depsAddrs[1] = sbe;
522 depsAddrs[2] = sm;
523 taskID = VSs__create_taskID_of_size(3);
524 taskID[1] = k;
525 taskID[2] = j;
526 taskID[3] = i;
527 VSs__submit_task_with_ID(&draw_edges_taskType, &draw_edges_task_args, depsAddrs, taskID);
528 }
529 return sm;
530 }
532 typedef struct{
533 MBRecContext *d;
534 SliceBufferEntry *sbe;
535 SuperMBTask *lastsmb;
536 int* release;
537 H264Context *h;
538 SuperMBContext *smbc;
539 } release_ref_list_taskArgs;
541 int32 release_ref_list_taskArgTypes[4] = {INOUT, INOUT, IN, INOUT};
542 size_t release_ref_list_taskArgSizes[4] = {sizeof(MBRecContext), sizeof(SliceBufferEntry), sizeof(SuperMBTask), sizeof(int)};
544 //#pragma omp task inout(*d, *sbe, *release) input (*lastsmb)
545 static void release_ref_list_task(void *_data){
546 release_ref_list_taskArgs* args = (release_ref_list_taskArgs*) _data;
547 MBRecContext *d = args->d;
548 SliceBufferEntry *sbe = args->sbe;
549 SuperMBTask *lastsmb = args->lastsmb;
550 int* releasep = args->release;
551 H264Context *h = args->h;
552 SuperMBContext *smbc = args->smbc;
554 H264Slice *s = &sbe->slice;
555 for (int i=0; i<s->release_cnt; i++){
556 for(int j=0; j<h->max_dpb_cnt; j++){
557 if(h->dpb[j].cpn== s->release_ref_cpn[i]){
558 //#pragma omp critical (dpb)
559 VSs__start_critical(0);
560 release_dpb_entry(h, &h->dpb[j], 2);
561 VSs__end_critical(0);
562 break;
563 }
564 }
565 }
566 s->release_cnt=0;
568 release_smbc(h, smbc);
570 return;
571 }
573 VSsTaskType release_ref_list_taskType = {
574 .fn = &release_ref_list_task,
575 .numDeps = 4,
576 .sizeOfArgs = sizeof(release_ref_list_taskArgs),
577 .depsTypes = release_ref_list_taskArgTypes,
578 .depsSizes = release_ref_list_taskArgSizes};
580 // 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){
581 //
582 // }
583 /*-------------------------------------------------------------------------------*/
584 //end for static 3d wave
586 typedef struct{
587 OutputContext *oc;
588 SliceBufferEntry *sbe;
589 H264Context *h;
590 } output_taskArgs;
592 int32 output_taskArgTypes[2] = {INOUT, IN};
593 size_t output_taskArgSizes[2] = {sizeof(OutputContext), sizeof(SliceBufferEntry)};
595 //#pragma omp task inout (*oc) input(*sbe)
596 static void output_task(void *_data){
597 output_taskArgs* args = (output_taskArgs*) _data;
598 OutputContext *oc = args->oc;
599 SliceBufferEntry *sbe = args->sbe;
600 H264Context *h = args->h;
602 DecodedPicture* out =output_frame(h, oc, sbe->slice.curr_pic, h->ofile, h->frame_width, h->frame_height);
603 if (out){
604 //#pragma omp critical (dpb)
605 VSs__start_critical(0);
606 release_dpb_entry(h, out, 1);
607 VSs__end_critical(0);
608 }
609 //print_report(oc->frame_number, oc->video_size, 0, h->verbose);
611 return;
612 }
614 VSsTaskType output_taskType = {
615 .fn = &output_task,
616 .numDeps = 2,
617 .sizeOfArgs = sizeof(output_taskArgs),
618 .depsTypes = output_taskArgTypes,
619 .depsSizes = output_taskArgSizes};
621 /*
622 * The following code is the main loop of the file converter
623 */
625 int h264_decode_ompss( H264Context *h) {
627 const int bufs = h->pipe_bufs;
629 ParserContext *pc;
630 NalContext *nc;
631 EntropyContext *ec[bufs];
632 MBRecContext *rc[2];
633 OutputContext *oc;
634 SliceBufferEntry *sbe;
635 SuperMBContext *smbc;
637 DecodedPicture *out;
638 int frames=0;
640 int32* taskID;
641 void** depsAddrs;
643 #if HAVE_LIBSDL2
644 pthread_t sdl_thr;
645 if (h->display){
646 pthread_create(&sdl_thr, NULL, sdl_thread, h);
647 }
648 #endif
649 /*sbe= VMS_WL__malloc(sizeof(SliceBufferEntry) * bufs);
650 if (sbe)
651 memset(sbe, 0, sizeof(SliceBufferEntry) * bufs);*/
652 sbe= av_mallocz(sizeof(SliceBufferEntry) * bufs);
654 pc = get_parse_context(h->ifile);
655 nc = get_nal_context(h->width, h->height);
657 for(int i=0; i<bufs; i++){
658 ec[i] = get_entropy_context( h );
659 }
661 for(int i=0; i<2; i++){
662 rc[i] = get_mbrec_context(h);
663 }
665 oc = get_output_context( h );
667 av_start_timer();
668 int k=0; int init, release;
669 if (h->static_3d && bufs < h->num_frames ){
670 int num_pre_ed =0;
671 for (num_pre_ed=0; num_pre_ed< bufs -1 && !pc->final_frame; num_pre_ed++){
672 parse_taskArgs parse_task_args;
673 parse_task_args.h = h;
674 parse_task_args.pc = pc;
675 parse_task_args.nc = nc;
676 parse_task_args.sbe = &sbe[k%bufs];
677 depsAddrs = malloc(sizeof(void*) * parse_taskType.numDeps);
678 /*sizeof(ParserContext), sizeof(NalContext), sizeof(SliceBufferEntry)*/
679 depsAddrs[0] = pc;
680 depsAddrs[1] = nc;
681 depsAddrs[2] = &sbe[k%bufs];
682 taskID = VSs__create_taskID_of_size(2);
683 taskID[1] = 1;
684 taskID[2] = k;
685 VSs__submit_task_with_ID(&parse_taskType, &parse_task_args, depsAddrs, taskID);
687 decode_slice_entropy_taskArgs decode_slice_entropy_task_args;
688 decode_slice_entropy_task_args.h = h;
689 decode_slice_entropy_task_args.ec = ec[k%bufs];
690 decode_slice_entropy_task_args.sbe = &sbe[k%bufs];
691 depsAddrs = malloc(sizeof(void*) * decode_slice_entropy_taskType.numDeps);
692 /*sizeof(EntropyContext), sizeof(SliceBufferEntry)*/
693 depsAddrs[0] = ec[k%bufs];
694 depsAddrs[1] = &sbe[k%bufs];
695 taskID = VSs__create_taskID_of_size(2);
696 taskID[1] = 2;
697 taskID[2] = k;
698 VSs__submit_task_with_ID(&decode_slice_entropy_taskType, &decode_slice_entropy_task_args, depsAddrs, taskID);
699 //#pragma omp taskwait on(*pc)
700 VSs__taskwait_on(pc);
701 k++;
702 }
704 while(!pc->final_frame && frames++ < h->num_frames && !h->quit){
705 parse_taskArgs parse_task_args;
706 parse_task_args.h = h;
707 parse_task_args.pc = pc;
708 parse_task_args.nc = nc;
709 parse_task_args.sbe = &sbe[k%bufs];
710 depsAddrs = malloc(sizeof(void*) * parse_taskType.numDeps);
711 /*sizeof(ParserContext), sizeof(NalContext), sizeof(SliceBufferEntry)*/
712 depsAddrs[0] = pc;
713 depsAddrs[1] = nc;
714 depsAddrs[2] = &sbe[k%bufs];
715 taskID = VSs__create_taskID_of_size(2);
716 taskID[1] = 3;
717 taskID[2] = k;
718 VSs__submit_task_with_ID(&parse_taskType, &parse_task_args, depsAddrs, taskID);
720 decode_slice_entropy_taskArgs decode_slice_entropy_task_args;
721 decode_slice_entropy_task_args.h = h;
722 decode_slice_entropy_task_args.ec = ec[k%bufs];
723 decode_slice_entropy_task_args.sbe = &sbe[k%bufs];
724 depsAddrs = malloc(sizeof(void*) * decode_slice_entropy_taskType.numDeps);
725 /*sizeof(EntropyContext), sizeof(SliceBufferEntry)*/
726 depsAddrs[0] = ec[k%bufs];
727 depsAddrs[1] = &sbe[k%bufs];
728 taskID = VSs__create_taskID_of_size(2);
729 taskID[1] = 4;
730 taskID[2] = k;
731 VSs__submit_task_with_ID(&decode_slice_entropy_taskType, &decode_slice_entropy_task_args, depsAddrs, taskID);
733 k++;
735 init_ref_list_and_get_dpb_taskArgs init_ref_list_and_get_dpb_task_args;
736 init_ref_list_and_get_dpb_task_args.h = h;
737 init_ref_list_and_get_dpb_task_args.d = rc[k%2];
738 init_ref_list_and_get_dpb_task_args.sbe = &sbe[k%bufs];
739 init_ref_list_and_get_dpb_task_args.init = &init;
740 depsAddrs = malloc(sizeof(void*) * init_ref_list_and_get_dpb_taskType.numDeps);
741 /*sizeof(MBRecContext), sizeof(SliceBufferEntry), sizeof(int)*/
742 depsAddrs[0] = rc[k%2];
743 depsAddrs[1] = &sbe[k%bufs];
744 depsAddrs[2] = &init;
745 taskID = VSs__create_taskID_of_size(2);
746 taskID[1] = 5;
747 taskID[2] = k;
748 VSs__submit_task_with_ID(&init_ref_list_and_get_dpb_taskType, &init_ref_list_and_get_dpb_task_args, depsAddrs, taskID);
750 smbc = acquire_smbc(h);
751 SuperMBTask *lastsmb= add_decode_slice_3dwave_tasks(rc[k%2], &sbe[k%bufs], smbc, k);
752 release_ref_list_taskArgs release_ref_list_task_args;
753 release_ref_list_task_args.h = h;
754 release_ref_list_task_args.smbc = smbc;
755 release_ref_list_task_args.d = rc[k%2];
756 release_ref_list_task_args.sbe = &sbe[k%bufs];
757 release_ref_list_task_args.lastsmb = lastsmb;
758 release_ref_list_task_args.release = &release;
759 depsAddrs = malloc(sizeof(void*) * release_ref_list_taskType.numDeps);
760 /*sizeof(MBRecContext), sizeof(SliceBufferEntry), sizeof(SuperMBTask), sizeof(int)*/
761 depsAddrs[0] = rc[k%2];
762 depsAddrs[1] = &sbe[k%bufs];
763 depsAddrs[2] = smbc;
764 depsAddrs[3] = &release;
765 taskID = VSs__create_taskID_of_size(2);
766 taskID[1] = 6;
767 taskID[2] = k;
768 VSs__submit_task_with_ID(&release_ref_list_taskType, &release_ref_list_task_args, depsAddrs, taskID);
770 output_taskArgs output_task_args;
771 output_task_args.h = h;
772 output_task_args.oc = oc;
773 output_task_args.sbe = &sbe[k%bufs];
774 depsAddrs = malloc(sizeof(void*) * output_taskType.numDeps);
775 /*sizeof(OutputContext), sizeof(SliceBufferEntry)*/
776 depsAddrs[0] = oc;
777 depsAddrs[1] = &sbe[k%bufs];
778 taskID = VSs__create_taskID_of_size(2);
779 taskID[1] = 7;
780 taskID[2] = k;
781 VSs__submit_task_with_ID(&output_taskType, &output_task_args, depsAddrs, taskID);
782 //#pragma omp taskwait on(*pc)
783 VSs__taskwait_on(pc);
784 }
786 for (int i=0; i< num_pre_ed; i++){
787 k++;
788 init_ref_list_and_get_dpb_taskArgs init_ref_list_and_get_dpb_task_args;
789 init_ref_list_and_get_dpb_task_args.h = h;
790 init_ref_list_and_get_dpb_task_args.d = rc[k%2];
791 init_ref_list_and_get_dpb_task_args.sbe = &sbe[k%bufs];
792 init_ref_list_and_get_dpb_task_args.init = &init;
793 depsAddrs = malloc(sizeof(void*) * init_ref_list_and_get_dpb_taskType.numDeps);
794 /*sizeof(MBRecContext), sizeof(SliceBufferEntry), sizeof(int)*/
795 depsAddrs[0] = rc[k%2];
796 depsAddrs[1] = &sbe[k%bufs];
797 depsAddrs[2] = &init;
798 taskID = VSs__create_taskID_of_size(2);
799 taskID[1] = 8;
800 taskID[2] = i;
801 VSs__submit_task_with_ID(&init_ref_list_and_get_dpb_taskType, &init_ref_list_and_get_dpb_task_args, depsAddrs, taskID);
802 smbc = acquire_smbc(h);
803 SuperMBTask *lastsmb= add_decode_slice_3dwave_tasks(rc[k%2], &sbe[k%bufs], smbc, k);
804 release_ref_list_taskArgs release_ref_list_task_args;
805 release_ref_list_task_args.h = h;
806 release_ref_list_task_args.smbc = smbc;
807 release_ref_list_task_args.d = rc[k%2];
808 release_ref_list_task_args.sbe = &sbe[k%bufs];
809 release_ref_list_task_args.lastsmb = lastsmb;
810 release_ref_list_task_args.release = &release;
811 depsAddrs = malloc(sizeof(void*) * release_ref_list_taskType.numDeps);
812 /*sizeof(MBRecContext), sizeof(SliceBufferEntry), sizeof(SuperMBTask), sizeof(int)*/
813 depsAddrs[0] = rc[k%2];
814 depsAddrs[1] = &sbe[k%bufs];
815 depsAddrs[2] = smbc;
816 depsAddrs[3] = &release;
817 taskID = VSs__create_taskID_of_size(2);
818 taskID[1] = 9;
819 taskID[2] = k;
820 VSs__submit_task_with_ID(&release_ref_list_taskType, &release_ref_list_task_args, depsAddrs, taskID);
822 output_taskArgs output_task_args;
823 output_task_args.h = h;
824 output_task_args.oc = oc;
825 output_task_args.sbe = &sbe[k%bufs];
826 depsAddrs = malloc(sizeof(void*) * output_taskType.numDeps);
827 /*sizeof(OutputContext), sizeof(SliceBufferEntry)*/
828 depsAddrs[0] = oc;
829 depsAddrs[1] = &sbe[k%bufs];
830 taskID = VSs__create_taskID_of_size(2);
831 taskID[1] = 10;
832 taskID[2] = k;
833 VSs__submit_task_with_ID(&output_taskType, &output_task_args, depsAddrs, taskID);
834 }
836 } else {
837 while(!pc->final_frame && frames++ < h->num_frames && !h->quit){
839 taskID = VSs__create_taskID_of_size(1);
840 taskID[1] = frames*10+1;
841 parse_taskArgs parse_task_args;
842 parse_task_args.h = h;
843 parse_task_args.pc = pc;
844 parse_task_args.nc = nc;
845 parse_task_args.sbe = &sbe[k%bufs];
846 depsAddrs = malloc(sizeof(void*) * parse_taskType.numDeps);
847 /*sizeof(ParserContext), sizeof(NalContext), sizeof(SliceBufferEntry)*/
848 depsAddrs[0] = pc;
849 depsAddrs[1] = nc;
850 depsAddrs[2] = &sbe[k%bufs];
851 VSs__submit_task_with_ID(&parse_taskType, &parse_task_args, depsAddrs, taskID);
853 taskID = VSs__create_taskID_of_size(1);
854 taskID[1] = frames*10+2;
855 decode_slice_entropy_taskArgs decode_slice_entropy_task_args;
856 decode_slice_entropy_task_args.h = h;
857 decode_slice_entropy_task_args.ec = ec[k%bufs];
858 decode_slice_entropy_task_args.sbe = &sbe[k%bufs];
859 depsAddrs = malloc(sizeof(void*) * decode_slice_entropy_taskType.numDeps);
860 /*sizeof(EntropyContext), sizeof(SliceBufferEntry)*/
861 depsAddrs[0] = ec[k%bufs];
862 depsAddrs[1] = &sbe[k%bufs];
863 VSs__submit_task_with_ID(&decode_slice_entropy_taskType, &decode_slice_entropy_task_args, depsAddrs, taskID);
865 taskID = VSs__create_taskID_of_size(1);
866 taskID[1] = frames*10+3;
867 decode_slice_mb_taskArgs decode_slice_mb_task_args;
868 decode_slice_mb_task_args.h = h;
869 decode_slice_mb_task_args.d = rc[0];
870 decode_slice_mb_task_args.sbe = &sbe[k%bufs];
871 depsAddrs = malloc(sizeof(void*) * decode_slice_mb_taskType.numDeps);
872 /*sizeof(MBRecContext), sizeof(SliceBufferEntry)*/
873 depsAddrs[0] = rc[0];
874 depsAddrs[1] = &sbe[k%bufs];
875 VSs__submit_task_with_ID(&decode_slice_mb_taskType, &decode_slice_mb_task_args, depsAddrs, taskID);
877 taskID = VSs__create_taskID_of_size(1);
878 taskID[1] = frames*10+4;
879 output_taskArgs output_task_args;
880 output_task_args.h = h;
881 output_task_args.oc = oc;
882 output_task_args.sbe = &sbe[k%bufs];
883 depsAddrs = malloc(sizeof(void*) * output_taskType.numDeps);
884 /*sizeof(OutputContext), sizeof(SliceBufferEntry)*/
885 depsAddrs[0] = oc;
886 depsAddrs[1] = &sbe[k%bufs];
887 VSs__submit_task_with_ID(&output_taskType, &output_task_args, depsAddrs, taskID);
888 //#pragma omp taskwait on(*pc)
889 VSs__taskwait_on(pc);
890 k++;
891 }
892 }
893 //#pragma omp taskwait
894 VSs__taskwait();
896 while ((out=output_frame(h, oc, NULL, h->ofile, h->frame_width, h->frame_height))) ;
898 //print_report(oc->frame_number, oc->video_size, 1, h->verbose);
899 h->num_frames = oc->frame_number;
900 /* finished ! */
902 free_parse_context(pc);
903 free_nal_context (nc);
904 free_output_context(oc);
905 for (int i=0; i<bufs; i++){
906 free_sb_entry(&sbe[i]);
907 free_entropy_context(ec[i]);
908 }
909 av_free(sbe);
911 for (int i=0; i<2; i++){
912 free_mbrec_context(rc[i]);
913 }
915 #if HAVE_LIBSDL2
916 if (h->display){
917 signal_sdl_exit(h);
918 pthread_join(sdl_thr, NULL);
919 }
920 #endif
922 return 0;
923 }