view libavcodec/h264_ompss.c @ 8:6c1433f5a562

remove need for end_thread()
author Nina Engelhardt <nengel@mailbox.tu-berlin.de>
date Fri, 17 May 2013 17:50:05 +0200
parents c8259123d224
children ea1ba68cf0ed
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[4] = {INOUT, INOUT, OUTPUT, NONCTLD};
40 int32 parse_taskArgSizes[4] = {sizeof(ParserContext), sizeof(NalContext), sizeof(SliceBufferEntry), sizeof(H264Context)};
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 .numCtldArgs = 3,
67 .numTotalArgs = 4,
68 .sizeOfArgs = sizeof(parse_taskArgs),
69 .argTypes = parse_taskArgTypes,
70 .argSizes = parse_taskArgSizes};
73 typedef struct{
74 EntropyContext *ec;
75 SliceBufferEntry *sbe;
76 H264Context *h;
77 } decode_slice_entropy_taskArgs;
79 int32 decode_slice_entropy_taskArgTypes[3] = {INOUT, INOUT, NONCTLD};
80 int32 decode_slice_entropy_taskArgSizes[3] = {sizeof(EntropyContext), sizeof(SliceBufferEntry), sizeof(H264Context)};
82 //#pragma omp task inout(*ec) inout(*sbe)
83 static void decode_slice_entropy_task(void *_data){
84 decode_slice_entropy_taskArgs* args = (decode_slice_entropy_taskArgs*) _data;
85 EntropyContext *ec = args->ec;
86 SliceBufferEntry *sbe = args->sbe;
87 H264Context *h = args->h;
88 int i,j;
89 H264Slice *s = &sbe->slice;
90 GetBitContext *gb = &sbe->gb;
91 H264Mb *mbs = sbe->mbs;
92 // GetBitContext *gb = s->gb;
93 CABACContext *c = &ec->c;
95 if( !s->pps.cabac ){
96 av_log(AV_LOG_ERROR, "Only cabac encoded streams are supported\n");
97 return;
98 }
100 init_dequant_tables(s, ec);
101 ec->curr_qscale = s->qscale;
102 ec->last_qscale_diff = 0;
103 ec->chroma_qp[0] = get_chroma_qp((H264Slice *) s, 0, s->qscale);
104 ec->chroma_qp[1] = get_chroma_qp((H264Slice *) s, 1, s->qscale);
106 /* realign */
107 align_get_bits( gb );
108 /* init cabac */
109 ff_init_cabac_decoder( c, gb->buffer + get_bits_count(gb)/8, (get_bits_left(gb) + 7)/8);
111 ff_h264_init_cabac_states(ec, s, c);
113 for(j=0; j<ec->mb_height; j++){
114 init_entropy_buf(ec, s, j);
115 for(i=0; i<ec->mb_width; i++){
116 int eos,ret;
117 H264Mb *m = &mbs[i + j*ec->mb_width];
118 m->mb_x=i;
119 m->mb_y=j;
120 ec->m = m;
122 ret = ff_h264_decode_mb_cabac(ec, s, c);
123 eos = get_cabac_terminate( c);
124 (void) eos;
125 if( ret < 0 || c->bytestream > c->bytestream_end + 2) {
126 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);
127 return;
128 }
129 }
130 }
131 return;
132 }
134 VSsTaskType decode_slice_entropy_taskType = {
135 .fn = &decode_slice_entropy_task,
136 .numCtldArgs = 2,
137 .numTotalArgs = 3,
138 .sizeOfArgs = sizeof(decode_slice_entropy_taskArgs),
139 .argTypes = decode_slice_entropy_taskArgTypes,
140 .argSizes = decode_slice_entropy_taskArgSizes};
143 static void decode_super_mb_block(MBRecContext *d, H264Slice *s, SuperMBContext *smbc, H264Mb *mbs, int smb_x, int smb_y){
144 MBRecState mrs;
145 // memset(&mrs, 0, sizeof(MBRecState));
147 for (int k=0, i= smb_y; i< smb_y + smbc->smb_height; i++, k++){
148 init_mbrec_context(d, &mrs, s, i);
149 for (int j= smb_x -k ; j< smb_x - k + smbc->smb_width; j++){
150 if (i< d->mb_height && j >= 0 && j < d->mb_width){
151 h264_decode_mb_internal (d, &mrs, s, &mbs[i*d->mb_width+j]);
152 }
153 }
154 }
155 }
157 typedef struct{
158 MBRecContext *d;
159 SliceBufferEntry *sbe;
160 SuperMBTask *ml;
161 SuperMBTask *mur;
162 SuperMBTask *m;
163 SuperMBContext *smbc;
164 } decode_super_mb_taskArgs;
166 int32 decode_super_mb_taskArgTypes[6] = {IN, IN, IN, IN, INOUT, NONCTLD};
167 int32 decode_super_mb_taskArgSizes[6] = {sizeof(MBRecContext), sizeof(SliceBufferEntry), sizeof(SuperMBTask), sizeof(SuperMBTask), sizeof(SuperMBTask), sizeof(SuperMBContext)};
169 //#pragma omp task input(*d, *sbe, *ml, *mur) inout(*m)
170 static void decode_super_mb_task(void *_data){
171 decode_super_mb_taskArgs* args = (decode_super_mb_taskArgs*) _data;
172 MBRecContext *d = args->d;
173 SliceBufferEntry *sbe = args->sbe;
174 SuperMBTask *ml = args->ml;
175 SuperMBTask *mur = args->mur;
176 SuperMBTask *m = args->m;
177 SuperMBContext *smbc = args->smbc;
178 H264Slice *s = &sbe->slice;
179 H264Mb *mbs = sbe->mbs;
180 decode_super_mb_block(d, s, smbc, mbs, m->smb_x, m->smb_y);
181 return;
182 }
184 VSsTaskType decode_super_mb_taskType = {
185 .fn = &decode_super_mb_task,
186 .numCtldArgs = 5,
187 .numTotalArgs = 6,
188 .sizeOfArgs = sizeof(decode_super_mb_taskArgs),
189 .argTypes = decode_super_mb_taskArgTypes,
190 .argSizes = decode_super_mb_taskArgSizes};
194 typedef struct{
195 MBRecContext *d;
196 SliceBufferEntry *sbe;
197 SuperMBTask *sm;
198 SuperMBContext *smbc;
199 int* line;
200 } draw_edges_taskArgs;
202 int32 draw_edges_taskArgTypes[5] = {IN, IN, INOUT, NONCTLD, NONCTLD};
203 int32 draw_edges_taskArgSizes[5] = {sizeof(MBRecContext), sizeof(SliceBufferEntry), sizeof(SuperMBTask),sizeof(SuperMBContext),sizeof(int)};
205 //#pragma omp task input(*d, *sbe) inout(*sm)
206 static void draw_edges_task(void *_data){
207 draw_edges_taskArgs* args = (draw_edges_taskArgs*) _data;
208 MBRecContext *d = args->d;
209 SliceBufferEntry *sbe = args->sbe;
210 SuperMBTask *sm = args->sm;
211 SuperMBContext *smbc = args->smbc;
212 int line = *(args->line);
213 H264Slice *s = &sbe->slice;
214 for (int i=line*smbc->smb_height; i< (line+1)*smbc->smb_height && i< d->mb_height; i++)
215 draw_edges(d, s, i);
216 VMS_App__free(args->line);
217 return;
218 }
219 VSsTaskType draw_edges_taskType = {
220 .fn = &draw_edges_task,
221 .numCtldArgs = 3,
222 .numTotalArgs = 5,
223 .sizeOfArgs = sizeof(draw_edges_taskArgs),
224 .argTypes = draw_edges_taskArgTypes,
225 .argSizes = draw_edges_taskArgSizes};
228 static void decode_mb_in_slice(H264Context *h, MBRecContext *d, SliceBufferEntry *sbe){
229 int i,j;
231 SuperMBContext *smbc = acquire_smbc(h);
232 int smb_height =smbc->nsmb_height, smb_width= smbc->nsmb_width;
233 SuperMBTask *smbs = smbc->smbs[0];
235 SuperMBTask *sm=NULL, *sml, *smur;
236 for(j=0; j< smb_height; j++){
237 for(i=0; i< smb_width; i++){
238 sm = smbs + j*smb_width + i;
239 sml = sm - ((i > 0) ? 1: 0);
240 smur = sm + (((i < smb_width-1) && (j >0)) ? -smb_width+1: 0);
241 decode_super_mb_taskArgs decode_super_mb_task_args;
242 decode_super_mb_task_args.d = d;
243 decode_super_mb_task_args.sbe = sbe;
244 decode_super_mb_task_args.smbc = smbc;
245 decode_super_mb_task_args.ml = sml;
246 decode_super_mb_task_args.mur = smur;
247 decode_super_mb_task_args.m = sm;
248 VSs__submit_task(&decode_super_mb_taskType, &decode_super_mb_task_args);
249 }
250 draw_edges_taskArgs draw_edges_task_args;
251 draw_edges_task_args.d = d;
252 draw_edges_task_args.sbe = sbe;
253 draw_edges_task_args.sm = sm;
254 draw_edges_task_args.smbc = smbc;
255 draw_edges_task_args.line = VMS_App__malloc( sizeof(int) );
256 *(draw_edges_task_args.line) = j;
257 VSs__submit_task(&draw_edges_taskType, &draw_edges_task_args);
258 }
259 VSs__taskwait_on(sm);
260 //#pragma omp taskwait on(*sm)
262 release_smbc(h, smbc);
263 }
265 typedef struct{
266 MBRecContext *d;
267 SliceBufferEntry *sbe;
268 H264Context *h;
269 } decode_slice_mb_taskArgs;
271 int32 decode_slice_mb_taskArgTypes[3] = {INOUT, INOUT, NONCTLD};
272 int32 decode_slice_mb_taskArgSizes[3] = {sizeof(MBRecContext), sizeof(SliceBufferEntry), sizeof(H264Context)};
274 //#pragma omp task inout(*d) inout(*sbe)
275 static void decode_slice_mb_task(void *_data){
276 decode_slice_mb_taskArgs* args = (decode_slice_mb_taskArgs*) _data;
277 MBRecContext *d = args->d;
278 SliceBufferEntry *sbe = args->sbe;
279 H264Context *h = args->h;
281 H264Slice *s = &sbe->slice;
283 for (int i=0; i<2; i++){
284 for(int j=0; j< s->ref_count[i]; j++){
285 if (s->ref_list_cpn[i][j] ==-1)
286 continue;
287 int k;
288 for (k=0; k< h->max_dpb_cnt; k++){
289 if(h->dpb[k].reference >= 2 && h->dpb[k].cpn == s->ref_list_cpn[i][j]){
290 s->dp_ref_list[i][j] = &h->dpb[k];
291 break;
292 }
293 }
294 }
295 }
297 //#pragma omp critical (dpb)
298 VSs__start_critical(0);
299 get_dpb_entry(h, s);
300 VSs__end_critical(0);
302 if (!h->no_mbd){
303 decode_mb_in_slice (h, d, sbe);
304 }
306 for (int i=0; i<s->release_cnt; i++){
307 for(int j=0; j<h->max_dpb_cnt; j++){
308 if(h->dpb[j].cpn== s->release_ref_cpn[i]){
309 //#pragma omp critical (dpb)
310 VSs__start_critical(0);
311 release_dpb_entry(h, &h->dpb[j], 2);
312 VSs__end_critical(0);
313 break;
314 }
315 }
316 }
317 s->release_cnt=0;
318 return;
319 }
321 VSsTaskType decode_slice_mb_taskType = {
322 .fn = &decode_slice_mb_task,
323 .numCtldArgs = 2,
324 .numTotalArgs = 3,
325 .sizeOfArgs = sizeof(decode_slice_mb_taskArgs),
326 .argTypes = decode_slice_mb_taskArgTypes,
327 .argSizes = decode_slice_mb_taskArgSizes};
329 // for static 3d wave
330 /*-------------------------------------------------------------------------------*/
331 typedef struct{
332 MBRecContext *d;
333 SliceBufferEntry *sbe;
334 SuperMBTask *ml;
335 SuperMBTask *mur;
336 SuperMBTask *mprev;
337 SuperMBTask *m;
338 SuperMBContext *smbc;
339 } decode_3dwave_super_mb_taskArgs;
341 int32 decode_3dwave_super_mb_taskArgTypes[7] = {IN, IN, IN, IN, IN, INOUT, NONCTLD};
342 int32 decode_3dwave_super_mb_taskArgSizes[7] = {sizeof(MBRecContext), sizeof(SliceBufferEntry), sizeof(SuperMBTask),
343 sizeof(SuperMBTask), sizeof(SuperMBTask), sizeof(SuperMBTask), sizeof(SuperMBContext)};
345 //#pragma omp task input(*d, *sbe, *ml, *mur, *mprev) inout(*m)
346 static void decode_3dwave_super_mb_task(void *_data){
347 decode_3dwave_super_mb_taskArgs* args = (decode_3dwave_super_mb_taskArgs*) _data;
348 MBRecContext *d = args->d;
349 SliceBufferEntry *sbe = args->sbe;
350 SuperMBTask *ml = args->ml;
351 SuperMBTask *mur = args->mur;
352 SuperMBTask *mprev = args->mprev;
353 SuperMBTask *m = args->m;
354 SuperMBContext *smbc = args->smbc;
356 H264Slice *s = &sbe->slice;
357 H264Mb *mbs = sbe->mbs;
359 decode_super_mb_block(d, s, smbc, mbs, m->smb_x, m->smb_y);
360 return;
361 }
363 VSsTaskType decode_3dwave_super_mb_taskType = {
364 .fn = &decode_3dwave_super_mb_task,
365 .numCtldArgs = 6,
366 .numTotalArgs = 7,
367 .sizeOfArgs = sizeof(decode_3dwave_super_mb_taskArgs),
368 .argTypes = decode_3dwave_super_mb_taskArgTypes,
369 .argSizes = decode_3dwave_super_mb_taskArgSizes};
371 // int init_ref_count=0;
372 typedef struct{
373 MBRecContext *d;
374 SliceBufferEntry *sbe;
375 int* init;
376 H264Context *h;
377 } init_ref_list_and_get_dpb_taskArgs;
379 int32 init_ref_list_and_get_dpb_taskArgTypes[4] = {INOUT, INOUT, INOUT, NONCTLD};
380 int32 init_ref_list_and_get_dpb_taskArgSizes[4] = {sizeof(MBRecContext), sizeof(SliceBufferEntry), sizeof(int), sizeof(H264Context)};
382 //#pragma omp task inout(*d, *sbe, *init)
383 static void init_ref_list_and_get_dpb_task(void *_data){
384 init_ref_list_and_get_dpb_taskArgs* args = (init_ref_list_and_get_dpb_taskArgs*) _data;
385 MBRecContext *d = args->d;
386 SliceBufferEntry *sbe = args->sbe;
387 int* initp = args->init;
388 H264Context *h = args->h;
390 H264Slice *s = &sbe->slice;
391 for (int i=0; i<2; i++){
392 for(int j=0; j< s->ref_count[i]; j++){
393 if (s->ref_list_cpn[i][j] ==-1)
394 continue;
395 int k;
396 for (k=0; k<h->max_dpb_cnt; k++){
397 if(h->dpb[k].reference >= 2 && h->dpb[k].cpn == s->ref_list_cpn[i][j]){
398 s->dp_ref_list[i][j] = &h->dpb[k];
399 break;
400 }
401 }
402 }
403 }
405 //#pragma omp critical (dpb)
406 VSs__start_critical(0);
407 get_dpb_entry(h, s);
408 VSs__end_critical(0);
410 return;
411 }
413 VSsTaskType init_ref_list_and_get_dpb_taskType = {
414 .fn = &init_ref_list_and_get_dpb_task,
415 .numCtldArgs = 3,
416 .numTotalArgs = 4,
417 .sizeOfArgs = sizeof(init_ref_list_and_get_dpb_taskArgs),
418 .argTypes = init_ref_list_and_get_dpb_taskArgTypes,
419 .argSizes = init_ref_list_and_get_dpb_taskArgSizes};
421 static SuperMBTask* add_decode_slice_3dwave_tasks(MBRecContext *d, SliceBufferEntry *sbe, SuperMBContext *smbc, int k){
422 int i,j;
424 int32* taskID;
426 int smb_3d_height =smbc->nsmb_3dheight;
427 int smb_height =smbc->nsmb_height, smb_width= smbc->nsmb_width;
428 int smb_diff_prev = smb_height - smb_3d_height;
429 SuperMBTask *sm=NULL, *sml, *smur, *smprev;
431 SuperMBTask *smbs = smbc->smbs[smbc->index++]; smbc->index%=2;
432 SuperMBTask *smbs_prev = smbc->smbs[smbc->index]; // index rotates -> next == prev
434 for(j=0; j<smb_3d_height ; j++){
435 for(i=0; i< smb_width; i++){
436 sm = smbs + j*smb_width + i;
437 sml = sm - ((i > 0) ? 1: 0);
438 smur = sm + (((i < smb_width-1) && (j >0)) ? -smb_width+1: 0);
439 smprev = smbs_prev + (j + smb_diff_prev+1)*smb_width -1;
440 decode_3dwave_super_mb_taskArgs decode_3dwave_super_mb_task_args;
441 decode_3dwave_super_mb_task_args.d = d;
442 decode_3dwave_super_mb_task_args.sbe = sbe;
443 decode_3dwave_super_mb_task_args.smbc = smbc;
444 decode_3dwave_super_mb_task_args.ml = sml;
445 decode_3dwave_super_mb_task_args.mur = smur;
446 decode_3dwave_super_mb_task_args.mprev = smprev;
447 decode_3dwave_super_mb_task_args.m = sm;
448 taskID = VSs__create_taskID_of_size(3 );
449 taskID[1] = k;
450 taskID[2] = j;
451 taskID[3] = i;
452 VSs__submit_task_with_ID(&decode_3dwave_super_mb_taskType, &decode_3dwave_super_mb_task_args, taskID);
453 }
454 draw_edges_taskArgs draw_edges_task_args;
455 draw_edges_task_args.d = d;
456 draw_edges_task_args.sbe = sbe;
457 draw_edges_task_args.sm = sm;
458 draw_edges_task_args.smbc = smbc;
459 draw_edges_task_args.line = VMS_App__malloc( sizeof(int) );
460 *(draw_edges_task_args.line) = j;
461 taskID = VSs__create_taskID_of_size(3);
462 taskID[1] = k;
463 taskID[2] = j;
464 taskID[3] = i;
465 VSs__submit_task_with_ID(&draw_edges_taskType, &draw_edges_task_args, taskID);
466 }
468 for(; j< smb_height; j++){
469 for(i=0; i< smb_width; i++){
470 sm = smbs + j*smb_width + i;
471 sml = sm - ((i > 0) ? 1: 0);
472 smur = sm + (((i < smb_width-1) && (j >0)) ? -smb_width+1: 0);
473 decode_super_mb_taskArgs decode_super_mb_task_args;
474 decode_super_mb_task_args.d = d;
475 decode_super_mb_task_args.sbe = sbe;
476 decode_super_mb_task_args.smbc = smbc;
477 decode_super_mb_task_args.ml = sml;
478 decode_super_mb_task_args.mur = smur;
479 decode_super_mb_task_args.m = sm;
480 taskID = VSs__create_taskID_of_size(3 );
481 taskID[1] = k;
482 taskID[2] = j;
483 taskID[3] = i;
484 VSs__submit_task_with_ID(&decode_super_mb_taskType, &decode_super_mb_task_args, taskID);
485 }
486 draw_edges_taskArgs draw_edges_task_args;
487 draw_edges_task_args.d = d;
488 draw_edges_task_args.sbe = sbe;
489 draw_edges_task_args.sm = sm;
490 draw_edges_task_args.smbc = smbc;
491 draw_edges_task_args.line = VMS_App__malloc( sizeof(int) );
492 *(draw_edges_task_args.line) = j;
493 taskID = VSs__create_taskID_of_size(3);
494 taskID[1] = k;
495 taskID[2] = j;
496 taskID[3] = i;
497 VSs__submit_task_with_ID(&draw_edges_taskType, &draw_edges_task_args, taskID);
498 }
499 return sm;
500 }
502 typedef struct{
503 MBRecContext *d;
504 SliceBufferEntry *sbe;
505 SuperMBTask *lastsmb;
506 int* release;
507 H264Context *h;
508 SuperMBContext *smbc;
509 } release_ref_list_taskArgs;
511 int32 release_ref_list_taskArgTypes[6] = {INOUT, INOUT, IN, INOUT, NONCTLD, NONCTLD};
512 int32 release_ref_list_taskArgSizes[6] = {sizeof(MBRecContext), sizeof(SliceBufferEntry), sizeof(SuperMBTask), sizeof(int), sizeof(H264Context), sizeof(SuperMBContext)};
514 //#pragma omp task inout(*d, *sbe, *release) input (*lastsmb)
515 static void release_ref_list_task(void *_data){
516 release_ref_list_taskArgs* args = (release_ref_list_taskArgs*) _data;
517 MBRecContext *d = args->d;
518 SliceBufferEntry *sbe = args->sbe;
519 SuperMBTask *lastsmb = args->lastsmb;
520 int* releasep = args->release;
521 H264Context *h = args->h;
522 SuperMBContext *smbc = args->smbc;
524 H264Slice *s = &sbe->slice;
525 for (int i=0; i<s->release_cnt; i++){
526 for(int j=0; j<h->max_dpb_cnt; j++){
527 if(h->dpb[j].cpn== s->release_ref_cpn[i]){
528 //#pragma omp critical (dpb)
529 VSs__start_critical(0);
530 release_dpb_entry(h, &h->dpb[j], 2);
531 VSs__end_critical(0);
532 break;
533 }
534 }
535 }
536 s->release_cnt=0;
538 release_smbc(h, smbc);
540 return;
541 }
543 VSsTaskType release_ref_list_taskType = {
544 .fn = &release_ref_list_task,
545 .numCtldArgs = 4,
546 .numTotalArgs = 6,
547 .sizeOfArgs = sizeof(release_ref_list_taskArgs),
548 .argTypes = release_ref_list_taskArgTypes,
549 .argSizes = release_ref_list_taskArgSizes};
551 // 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){
552 //
553 // }
554 /*-------------------------------------------------------------------------------*/
555 //end for static 3d wave
557 typedef struct{
558 OutputContext *oc;
559 SliceBufferEntry *sbe;
560 H264Context *h;
561 } output_taskArgs;
563 int32 output_taskArgTypes[3] = {INOUT, IN, NONCTLD};
564 int32 output_taskArgSizes[3] = {sizeof(OutputContext), sizeof(SliceBufferEntry), sizeof(H264Context)};
566 //#pragma omp task inout (*oc) input(*sbe)
567 static void output_task(void *_data){
568 output_taskArgs* args = (output_taskArgs*) _data;
569 OutputContext *oc = args->oc;
570 SliceBufferEntry *sbe = args->sbe;
571 H264Context *h = args->h;
573 DecodedPicture* out =output_frame(h, oc, sbe->slice.curr_pic, h->ofile, h->frame_width, h->frame_height);
574 if (out){
575 //#pragma omp critical (dpb)
576 VSs__start_critical(0);
577 release_dpb_entry(h, out, 1);
578 VSs__end_critical(0);
579 }
580 //print_report(oc->frame_number, oc->video_size, 0, h->verbose);
582 return;
583 }
585 VSsTaskType output_taskType = {
586 .fn = &output_task,
587 .numCtldArgs = 2,
588 .numTotalArgs = 3,
589 .sizeOfArgs = sizeof(output_taskArgs),
590 .argTypes = output_taskArgTypes,
591 .argSizes = output_taskArgSizes};
593 /*
594 * The following code is the main loop of the file converter
595 */
597 int h264_decode_ompss( H264Context *h) {
599 const int bufs = h->pipe_bufs;
601 ParserContext *pc;
602 NalContext *nc;
603 EntropyContext *ec[bufs];
604 MBRecContext *rc[2];
605 OutputContext *oc;
606 SliceBufferEntry *sbe;
607 SuperMBContext *smbc;
609 DecodedPicture *out;
610 int frames=0;
612 int32* taskID;
614 #if HAVE_LIBSDL2
615 pthread_t sdl_thr;
616 if (h->display){
617 pthread_create(&sdl_thr, NULL, sdl_thread, h);
618 }
619 #endif
620 /*sbe= VMS_WL__malloc(sizeof(SliceBufferEntry) * bufs);
621 if (sbe)
622 memset(sbe, 0, sizeof(SliceBufferEntry) * bufs);*/
623 sbe= av_mallocz(sizeof(SliceBufferEntry) * bufs);
625 pc = get_parse_context(h->ifile);
626 nc = get_nal_context(h->width, h->height);
628 for(int i=0; i<bufs; i++){
629 ec[i] = get_entropy_context( h );
630 }
632 for(int i=0; i<2; i++){
633 rc[i] = get_mbrec_context(h);
634 }
636 oc = get_output_context( h );
638 av_start_timer();
639 int k=0; int init, release;
640 if (h->static_3d && bufs < h->num_frames ){
641 int num_pre_ed =0;
642 for (num_pre_ed=0; num_pre_ed< bufs -1 && !pc->final_frame; num_pre_ed++){
643 parse_taskArgs parse_task_args;
644 parse_task_args.h = h;
645 parse_task_args.pc = pc;
646 parse_task_args.nc = nc;
647 parse_task_args.sbe = &sbe[k%bufs];
648 taskID = VSs__create_taskID_of_size(2);
649 taskID[1] = 1;
650 taskID[2] = k;
651 VSs__submit_task_with_ID(&parse_taskType, &parse_task_args, taskID);
653 decode_slice_entropy_taskArgs decode_slice_entropy_task_args;
654 decode_slice_entropy_task_args.h = h;
655 decode_slice_entropy_task_args.ec = ec[k%bufs];
656 decode_slice_entropy_task_args.sbe = &sbe[k%bufs];
657 taskID = VSs__create_taskID_of_size(2);
658 taskID[1] = 2;
659 taskID[2] = k;
660 VSs__submit_task_with_ID(&decode_slice_entropy_taskType, &decode_slice_entropy_task_args, taskID);
661 //#pragma omp taskwait on(*pc)
662 VSs__taskwait_on(pc);
663 k++;
664 }
666 while(!pc->final_frame && frames++ < h->num_frames && !h->quit){
667 parse_taskArgs parse_task_args;
668 parse_task_args.h = h;
669 parse_task_args.pc = pc;
670 parse_task_args.nc = nc;
671 parse_task_args.sbe = &sbe[k%bufs];
672 taskID = VSs__create_taskID_of_size(2);
673 taskID[1] = 3;
674 taskID[2] = k;
675 VSs__submit_task_with_ID(&parse_taskType, &parse_task_args, taskID);
677 decode_slice_entropy_taskArgs decode_slice_entropy_task_args;
678 decode_slice_entropy_task_args.h = h;
679 decode_slice_entropy_task_args.ec = ec[k%bufs];
680 decode_slice_entropy_task_args.sbe = &sbe[k%bufs];
681 taskID = VSs__create_taskID_of_size(2);
682 taskID[1] = 4;
683 taskID[2] = k;
684 VSs__submit_task_with_ID(&decode_slice_entropy_taskType, &decode_slice_entropy_task_args, taskID);
686 k++;
688 init_ref_list_and_get_dpb_taskArgs init_ref_list_and_get_dpb_task_args;
689 init_ref_list_and_get_dpb_task_args.h = h;
690 init_ref_list_and_get_dpb_task_args.d = rc[k%2];
691 init_ref_list_and_get_dpb_task_args.sbe = &sbe[k%bufs];
692 init_ref_list_and_get_dpb_task_args.init = &init;
693 taskID = VSs__create_taskID_of_size(2);
694 taskID[1] = 5;
695 taskID[2] = k;
696 VSs__submit_task_with_ID(&init_ref_list_and_get_dpb_taskType, &init_ref_list_and_get_dpb_task_args, taskID);
698 smbc = acquire_smbc(h);
699 SuperMBTask *lastsmb= add_decode_slice_3dwave_tasks(rc[k%2], &sbe[k%bufs], smbc, k);
700 release_ref_list_taskArgs release_ref_list_task_args;
701 release_ref_list_task_args.h = h;
702 release_ref_list_task_args.smbc = smbc;
703 release_ref_list_task_args.d = rc[k%2];
704 release_ref_list_task_args.sbe = &sbe[k%bufs];
705 release_ref_list_task_args.lastsmb = lastsmb;
706 release_ref_list_task_args.release = &release;
707 taskID = VSs__create_taskID_of_size(2);
708 taskID[1] = 6;
709 taskID[2] = k;
710 VSs__submit_task_with_ID(&release_ref_list_taskType, &release_ref_list_task_args, taskID);
712 output_taskArgs output_task_args;
713 output_task_args.h = h;
714 output_task_args.oc = oc;
715 output_task_args.sbe = &sbe[k%bufs];
716 taskID = VSs__create_taskID_of_size(2);
717 taskID[1] = 7;
718 taskID[2] = k;
719 VSs__submit_task_with_ID(&output_taskType, &output_task_args, taskID);
720 //#pragma omp taskwait on(*pc)
721 VSs__taskwait_on(pc);
722 }
724 for (int i=0; i< num_pre_ed; i++){
725 k++;
726 init_ref_list_and_get_dpb_taskArgs init_ref_list_and_get_dpb_task_args;
727 init_ref_list_and_get_dpb_task_args.h = h;
728 init_ref_list_and_get_dpb_task_args.d = rc[k%2];
729 init_ref_list_and_get_dpb_task_args.sbe = &sbe[k%bufs];
730 init_ref_list_and_get_dpb_task_args.init = &init;
731 taskID = VSs__create_taskID_of_size(2);
732 taskID[1] = 8;
733 taskID[2] = i;
734 VSs__submit_task_with_ID(&init_ref_list_and_get_dpb_taskType, &init_ref_list_and_get_dpb_task_args, taskID);
735 smbc = acquire_smbc(h);
736 SuperMBTask *lastsmb= add_decode_slice_3dwave_tasks(rc[k%2], &sbe[k%bufs], smbc, k);
737 release_ref_list_taskArgs release_ref_list_task_args;
738 release_ref_list_task_args.h = h;
739 release_ref_list_task_args.smbc = smbc;
740 release_ref_list_task_args.d = rc[k%2];
741 release_ref_list_task_args.sbe = &sbe[k%bufs];
742 release_ref_list_task_args.lastsmb = lastsmb;
743 release_ref_list_task_args.release = &release;
744 taskID = VSs__create_taskID_of_size(2);
745 taskID[1] = 9;
746 taskID[2] = k;
747 VSs__submit_task_with_ID(&release_ref_list_taskType, &release_ref_list_task_args, taskID);
749 output_taskArgs output_task_args;
750 output_task_args.h = h;
751 output_task_args.oc = oc;
752 output_task_args.sbe = &sbe[k%bufs];
753 taskID = VSs__create_taskID_of_size(2);
754 taskID[1] = 10;
755 taskID[2] = k;
756 VSs__submit_task_with_ID(&output_taskType, &output_task_args, taskID);
757 }
759 } else {
760 while(!pc->final_frame && frames++ < h->num_frames && !h->quit){
762 taskID = VSs__create_taskID_of_size(1);
763 taskID[1] = frames*10+1;
764 parse_taskArgs parse_task_args;
765 parse_task_args.h = h;
766 parse_task_args.pc = pc;
767 parse_task_args.nc = nc;
768 parse_task_args.sbe = &sbe[k%bufs];
769 VSs__submit_task_with_ID(&parse_taskType, &parse_task_args, taskID);
771 taskID = VSs__create_taskID_of_size(1);
772 taskID[1] = frames*10+2;
773 decode_slice_entropy_taskArgs decode_slice_entropy_task_args;
774 decode_slice_entropy_task_args.h = h;
775 decode_slice_entropy_task_args.ec = ec[k%bufs];
776 decode_slice_entropy_task_args.sbe = &sbe[k%bufs];
777 VSs__submit_task_with_ID(&decode_slice_entropy_taskType, &decode_slice_entropy_task_args,taskID);
779 taskID = VSs__create_taskID_of_size(1);
780 taskID[1] = frames*10+3;
781 decode_slice_mb_taskArgs decode_slice_mb_task_args;
782 decode_slice_mb_task_args.h = h;
783 decode_slice_mb_task_args.d = rc[0];
784 decode_slice_mb_task_args.sbe = &sbe[k%bufs];
785 VSs__submit_task_with_ID(&decode_slice_mb_taskType, &decode_slice_mb_task_args,taskID);
787 taskID = VSs__create_taskID_of_size(1);
788 taskID[1] = frames*10+4;
789 output_taskArgs output_task_args;
790 output_task_args.h = h;
791 output_task_args.oc = oc;
792 output_task_args.sbe = &sbe[k%bufs];
793 VSs__submit_task_with_ID(&output_taskType, &output_task_args,taskID);
794 //#pragma omp taskwait on(*pc)
795 VSs__taskwait_on(pc);
796 k++;
797 }
798 }
799 //#pragma omp taskwait
800 VSs__taskwait();
802 while ((out=output_frame(h, oc, NULL, h->ofile, h->frame_width, h->frame_height))) ;
804 //print_report(oc->frame_number, oc->video_size, 1, h->verbose);
805 h->num_frames = oc->frame_number;
806 /* finished ! */
808 free_parse_context(pc);
809 free_nal_context (nc);
810 free_output_context(oc);
811 for (int i=0; i<bufs; i++){
812 free_sb_entry(&sbe[i]);
813 free_entropy_context(ec[i]);
814 }
815 av_free(sbe);
817 for (int i=0; i<2; i++){
818 free_mbrec_context(rc[i]);
819 }
821 #if HAVE_LIBSDL2
822 if (h->display){
823 signal_sdl_exit(h);
824 pthread_join(sdl_thr, NULL);
825 }
826 #endif
828 return 0;
829 }