annotate libavcodec/h264_ompss.c @ 6:55fb61482128

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