Mercurial > cgi-bin > hgwebdir.cgi > PR > Applications > VSs > VSs__H264__App
diff libavcodec/h264_pthread.c @ 2:897f711a7157
rearrange to work with autoconf
| author | Nina Engelhardt <nengel@mailbox.tu-berlin.de> |
|---|---|
| date | Tue, 25 Sep 2012 15:55:33 +0200 |
| parents | |
| children |
line diff
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/libavcodec/h264_pthread.c Tue Sep 25 15:55:33 2012 +0200 1.3 @@ -0,0 +1,604 @@ 1.4 +#include "config.h" 1.5 + 1.6 +#include "h264_types.h" 1.7 +#include "h264_parser.h" 1.8 +#include "h264_nal.h" 1.9 +#include "h264_entropy.h" 1.10 +#include "h264_rec.h" 1.11 +#include "h264_misc.h" 1.12 +// #undef NDEBUG 1.13 +#include <assert.h> 1.14 +#include <pthread.h> 1.15 + 1.16 +#define XOANON 1 1.17 + 1.18 +#ifdef XOANON 1.19 +static int ed_rec_affinity[40] = { 0, 4, 8, 12, 16, 20, 24, 28, 32, 36, 1.20 + 1, 5, 9, 13, 17, 21, 25, 29, 33, 37, 1.21 + 2, 6, 10, 14, 18, 22, 26, 30, 34, 38, 1.22 + 3, 7, 11, 15, 19, 23, 27, 31, 35, 39 }; 1.23 +static int ed_rec_smt_aff[80] = { 0, 40, 4, 44, 8, 48, 12, 52, 16, 56, 20, 60, 24, 64, 28, 68, 32, 72, 36, 76, 1.24 + 1, 41, 5, 45, 9, 49, 13, 53, 17, 57, 21, 61, 25, 65, 29, 69, 33, 73, 37, 77, 1.25 + 2, 42, 6, 46, 10, 50, 14, 54, 18, 58, 22, 62, 26, 66, 30, 70, 34, 74, 38, 78, 1.26 + 3, 43, 7, 47, 11, 51, 15, 55, 19, 59, 23, 63, 27, 67, 31, 71, 35, 75, 39, 79 }; 1.27 +#else 1.28 +static int ed_rec_affinity[10] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; 1.29 +static int ed_rec_smt_aff[20] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, }; 1.30 +#endif 1.31 + 1.32 +static int frames=0; 1.33 + 1.34 +static void notify_one_worker(H264Context *h){ 1.35 + pthread_mutex_lock(&h->task_lock); 1.36 + pthread_cond_signal(&h->task_cond); 1.37 + pthread_mutex_unlock(&h->task_lock); 1.38 +} 1.39 + 1.40 +static void notify_all_workers(H264Context *h){ 1.41 + pthread_mutex_lock(&h->task_lock); 1.42 + pthread_cond_broadcast(&h->task_cond); 1.43 + pthread_mutex_unlock(&h->task_lock); 1.44 +} 1.45 + 1.46 +static void push_sbe (SliceBufferQueue *sbq, SliceBufferEntry *sbe, int notify ){ 1.47 + pthread_mutex_lock(&sbq->lock); 1.48 + while (sbq->cnt >= sbq->size) 1.49 + pthread_cond_wait(&sbq->cond, &sbq->lock); 1.50 + sbq->queue[sbq->fi] = sbe; 1.51 + sbq->cnt++; 1.52 + sbq->fi++; sbq->fi %= sbq->size; 1.53 + if (notify) 1.54 + pthread_cond_signal(&sbq->cond); 1.55 + pthread_mutex_unlock(&sbq->lock); 1.56 +} 1.57 + 1.58 +static SliceBufferEntry* pop_sbe (SliceBufferQueue *sbq, int block){ 1.59 + SliceBufferEntry *sbe=NULL; 1.60 + 1.61 + pthread_mutex_lock(&sbq->lock); 1.62 + if (block){ 1.63 + while (sbq->cnt <= 0) 1.64 + pthread_cond_wait(&sbq->cond, &sbq->lock); 1.65 + }else { 1.66 + if (sbq->cnt <= 0) 1.67 + goto nonblock; 1.68 + } 1.69 + sbe = sbq->queue[sbq->fo]; 1.70 + sbq->cnt--; 1.71 + sbq->fo++; sbq->fo %= sbq->size; 1.72 + pthread_cond_signal(&sbq->cond); 1.73 +nonblock: 1.74 + pthread_mutex_unlock(&sbq->lock); 1.75 + 1.76 + return sbe; 1.77 +} 1.78 + 1.79 +// static void push_rle (RingLineQueue *rlq, SliceBufferEntry *sbe, int line, int notify){ 1.80 +// 1.81 +// //check for free slots 1.82 +// pthread_mutex_lock(&rlq->wslock); 1.83 +// while (rlq->free <= 0){ 1.84 +// pthread_cond_wait(&rlq->wscond, &rlq->wslock); 1.85 +// } 1.86 +// //free slot is available, decrement one in this lock 1.87 +// rlq->free--; 1.88 +// pthread_mutex_unlock(&rlq->wslock); 1.89 +// 1.90 +// pthread_mutex_lock(&rlq->swlock); 1.91 +// rlq->queue[rlq->fi]->sbe=sbe; 1.92 +// rlq->queue[rlq->fi]->line=line; 1.93 +// rlq->queue[rlq->fi]->mb_cnt=0; 1.94 +// rlq->fi++; rlq->fi %= rlq->size; 1.95 +// rlq->ready++; 1.96 +// if(notify) 1.97 +// pthread_cond_signal(&rlq->swcond); 1.98 +// pthread_mutex_unlock(&rlq->swlock); 1.99 +// } 1.100 + 1.101 +// static RingLineEntry* pop_rle (RingLineQueue *rlq, int block){ 1.102 +// RingLineEntry *rle=NULL; 1.103 +// 1.104 +// pthread_mutex_lock(&rlq->swlock); 1.105 +// if (block){ 1.106 +// while (rlq->ready <= 0) 1.107 +// pthread_cond_wait(&rlq->swcond, &rlq->swlock); 1.108 +// }else { 1.109 +// if (rlq->ready <= 0) 1.110 +// goto nonblock; 1.111 +// } 1.112 +// rle = rlq->queue[rlq->fo]; 1.113 +// rlq->fo++; rlq->fo %= rlq->size; 1.114 +// rlq->ready--; 1.115 +// nonblock: 1.116 +// pthread_mutex_unlock(&rlq->swlock); 1.117 +// 1.118 +// return rle; 1.119 +// } 1.120 +// 1.121 +// static void rel_rle (RingLineQueue *rlq){ 1.122 +// pthread_mutex_lock(&rlq->wslock); 1.123 +// rlq->free++; 1.124 +// pthread_cond_signal(&rlq->wscond); 1.125 +// pthread_mutex_unlock(&rlq->wslock); 1.126 +// } 1.127 + 1.128 +static RingLineEntry* pop_rle (SliceBufferQueue *sbq, RingLineQueue *rlq, int *has_token){ 1.129 + RingLineEntry *rle=NULL; 1.130 + SliceBufferEntry *sbe=NULL; 1.131 + int line=-1; 1.132 + 1.133 + pthread_mutex_lock(&sbq->lock); 1.134 + if (sbq->cnt <= 0) 1.135 + goto unlock; 1.136 + sbe = sbq->queue[sbq->fo]; 1.137 + line = sbe->lines_taken; 1.138 + 1.139 + 1.140 + pthread_mutex_lock(&rlq->swlock); 1.141 + if (!*has_token){ 1.142 + if (rlq->free <= 0) 1.143 + goto unlock2; 1.144 + rlq->free--; 1.145 + *has_token=1; 1.146 + } 1.147 + rle = rlq->queue[rlq->fo]; 1.148 + rlq->fo++; rlq->fo %= rlq->size; 1.149 + rle->sbe=sbe; 1.150 + rle->line = line; 1.151 + rle->mb_cnt =0; 1.152 + if (++sbe->lines_taken >= sbe->lines_total){ 1.153 + sbq->cnt--; 1.154 + sbq->fo++; sbq->fo %= sbq->size; 1.155 + pthread_cond_signal(&sbq->cond); 1.156 + } 1.157 +unlock2: 1.158 + pthread_mutex_unlock(&rlq->swlock); 1.159 +unlock: 1.160 + pthread_mutex_unlock(&sbq->lock); 1.161 + 1.162 + 1.163 + return rle; 1.164 +} 1.165 + 1.166 +static void rel_rle (RingLineQueue *rlq, int *rec_token){ 1.167 + pthread_mutex_lock(&rlq->swlock); 1.168 + rlq->free++; 1.169 + *rec_token=0; 1.170 +// pthread_cond_signal(&rlq->swcond); 1.171 + pthread_mutex_unlock(&rlq->swlock); 1.172 + 1.173 +} 1.174 + 1.175 +//get either a entropy or a line reconstruct task 1.176 +static void pop_next_task(H264Context *h, SliceBufferEntry **psbe, RingLineEntry **prle, int *rec_token){ 1.177 + 1.178 + pthread_mutex_lock(&h->task_lock); 1.179 + 1.180 + for(;;){ 1.181 + if ( (*psbe = pop_sbe(&h->sb_q[ENTROPY], 0)) ){ 1.182 + if (*rec_token){ 1.183 + rel_rle(&h->rl_q, rec_token); 1.184 + pthread_cond_signal(&h->task_cond); 1.185 + } 1.186 + break; 1.187 + } 1.188 + else if ( (*prle = pop_rle(&h->sb_q[MBDEC], &h->rl_q, rec_token)) ) 1.189 + break; 1.190 + pthread_cond_wait(&h->task_cond, &h->task_lock); 1.191 + } 1.192 + 1.193 + pthread_mutex_unlock(&h->task_lock); 1.194 +} 1.195 + 1.196 +void *parse_thread(void *arg){ 1.197 + H264Context *h = (H264Context *) arg; 1.198 + ParserContext *pc = get_parse_context(h->ifile); 1.199 + NalContext *nc = get_nal_context(h->width, h->height); 1.200 + H264Slice *s; 1.201 + SliceBufferEntry *sbe = NULL; 1.202 + 1.203 + while(!pc->final_frame && frames++ <h->num_frames && !h->quit){ 1.204 + sbe = get_sb_entry(h); 1.205 + 1.206 + av_read_frame_internal(pc, &sbe->gb); 1.207 + s = &sbe->slice; 1.208 + 1.209 + decode_nal_units(nc, s, &sbe->gb); 1.210 + 1.211 + push_sbe(&h->sb_q[ENTROPY], sbe, 0); 1.212 + notify_one_worker(h); 1.213 + } 1.214 + 1.215 + if (!h->no_mbd){ 1.216 + sbe = get_sb_entry(h); 1.217 + sbe->state=-1; 1.218 + sbe->slice.coded_pic_num=nc->coded_pic_num; 1.219 + sbe->lines_total=h->threads; 1.220 + 1.221 + push_sbe(&h->sb_q[REORDER], sbe, 1); 1.222 + }else{ 1.223 + for (int i=0; i<h->threads; i++){ 1.224 + sbe = get_sb_entry(h); 1.225 + sbe->state=-1; 1.226 + push_sbe(&h->sb_q[ENTROPY], sbe, 1); 1.227 + notify_one_worker(h); 1.228 + } 1.229 + } 1.230 + free_nal_context(nc); 1.231 + free_parse_context(pc); 1.232 + 1.233 + pthread_exit(NULL); 1.234 + return NULL; 1.235 +} 1.236 + 1.237 +int decode_slice_entropy(EntropyContext *ec, SliceBufferEntry *sbe){ 1.238 + int i,j; 1.239 + H264Slice *s = &sbe->slice; 1.240 + GetBitContext *gb = &sbe->gb; 1.241 + CABACContext *c = &ec->c; 1.242 + H264Mb *mbs = sbe->mbs; 1.243 + 1.244 + if( !s->pps.cabac ){ 1.245 + av_log(AV_LOG_ERROR, "Only cabac encoded streams are supported\n"); 1.246 + return -1; 1.247 + } 1.248 + 1.249 + init_dequant_tables(s, ec); 1.250 + ec->curr_qscale = s->qscale; 1.251 + ec->last_qscale_diff = 0; 1.252 + ec->chroma_qp[0] = get_chroma_qp( s, 0, s->qscale); 1.253 + ec->chroma_qp[1] = get_chroma_qp( s, 1, s->qscale); 1.254 + 1.255 + /* realign */ 1.256 + align_get_bits( gb ); 1.257 + /* init cabac */ 1.258 + ff_init_cabac_decoder( c, gb->buffer + get_bits_count(gb)/8, (get_bits_left(gb) + 7)/8); 1.259 + 1.260 + ff_h264_init_cabac_states(ec, s, c); 1.261 + 1.262 + for(j=0; j<ec->mb_height; j++){ 1.263 + init_entropy_buf(ec, s, j); 1.264 + for(i=0; i<ec->mb_width; i++){ 1.265 + int eos,ret; 1.266 + H264Mb *m = &mbs[i + j*ec->mb_width]; 1.267 + //memset(m, 0, sizeof(H264Mb)); 1.268 + m->mb_x=i; 1.269 + m->mb_y=j; 1.270 + ec->m = m; 1.271 + 1.272 + ret = ff_h264_decode_mb_cabac(ec, s, c); 1.273 + eos = get_cabac_terminate( c); (void) eos; 1.274 + 1.275 + if( ret < 0 || c->bytestream > c->bytestream_end + 2) { 1.276 + 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); 1.277 + return -1; 1.278 + } 1.279 + } 1.280 + } 1.281 + 1.282 + return 0; 1.283 +} 1.284 + 1.285 +static int decode_slice_mb(MBRecContext *d, RingLineEntry *rle, int frames){ 1.286 + SliceBufferEntry *sbe= rle->sbe; 1.287 + H264Slice *s = &sbe->slice; 1.288 + H264Mb *mbs = sbe->mbs; 1.289 + 1.290 + int mb_width= d->mb_width; 1.291 + int i; 1.292 + const int line = rle->line; 1.293 + 1.294 + init_mbrec_context(d, d->mrs, s, line); 1.295 + 1.296 + H264Mb *m = &mbs[line*mb_width]; 1.297 + d->top=rle->prev_line->top; 1.298 + d->top_next=rle->top; 1.299 + 1.300 +// assert(rle->mb_cnt ==0); 1.301 + for(i=0; i< mb_width; i++){ 1.302 + if (frames || line>0){ 1.303 + while (rle->mb_cnt >= rle->prev_line->mb_cnt -1); 1.304 + } 1.305 + h264_decode_mb_internal( d, d->mrs, s, &m[i]); 1.306 + rle->mb_cnt++; 1.307 + } 1.308 + draw_edges(d, s, line); 1.309 + 1.310 + return 0; 1.311 +} 1.312 + 1.313 +// static int decode_slice_mb_static(MBRecContext *d, H264Slice *s, RLThreadContext *r, RLThreadContext *rp, int frames){ 1.314 +// int mb_height= d->mb_height; 1.315 +// int mb_width= d->mb_width; 1.316 +// int thread_num = r->thread_num; 1.317 +// int thread_total = r->thread_total; 1.318 +// int i; 1.319 +// int j = thread_num; 1.320 +// 1.321 +// r->mb_cnt=frames* mb_height*mb_width; 1.322 +// for(; j<mb_height; j+=thread_total){ 1.323 +// H264Mb *m = &s->mbs[j*mb_width]; 1.324 +// for(i=0; i< mb_width; i++){ 1.325 +// if (j>0){ 1.326 +// while (r->mb_cnt- (thread_num? 0:mb_width) >= rp->mb_cnt-1); 1.327 +// } 1.328 +// h264_decode_mb_internal(d, s, m++); 1.329 +// r->mb_cnt++; 1.330 +// } 1.331 +// draw_edges(d, s, j); 1.332 +// } 1.333 +// return 0; 1.334 +// } 1.335 + 1.336 +static void *ed_rec_thread(void *arg){ 1.337 + H264Context *h = (H264Context*) arg; 1.338 + EntropyContext *ec=NULL; 1.339 + MBRecContext *mrc=NULL; 1.340 + 1.341 + RingLineEntry *rle=NULL; 1.342 + SliceBufferEntry *sbe=NULL; 1.343 + H264Slice *s; 1.344 + int rec_token=0; 1.345 + 1.346 + if (!h->no_mbd){ 1.347 + mrc = get_mbrec_context(h); 1.348 + } 1.349 + ec = get_entropy_context(h); 1.350 + 1.351 + for(;;){ 1.352 + pop_next_task(h, &sbe, &rle, &rec_token); 1.353 + if (sbe){ 1.354 + if (h->no_mbd && sbe->state<0){ 1.355 + break; 1.356 + } 1.357 + if (!sbe->initialized){ 1.358 + init_sb_entry(h, sbe); 1.359 + } 1.360 + decode_slice_entropy(ec, sbe); 1.361 + 1.362 + if (h->no_mbd){ 1.363 + release_sb_entry(h, sbe); 1.364 + sbe=NULL; 1.365 + } else { 1.366 + push_sbe(&h->sb_q[REORDER], sbe, 1); 1.367 + } 1.368 + } else if (rle){ 1.369 + if (rle->sbe->state<0) 1.370 + break; 1.371 + s = &rle->sbe->slice; 1.372 + 1.373 + decode_slice_mb(mrc, rle, s->coded_pic_num); 1.374 + 1.375 + if (rle->line == h->mb_height-1){ 1.376 + push_sbe(&h->sb_q[OUTPUT], rle->sbe, 1); 1.377 + } 1.378 + rle->mb_cnt++; 1.379 + } 1.380 + } 1.381 + 1.382 + //make sure threads quit in order of rle assignment 1.383 + if (!h->no_mbd){ 1.384 + while (rle->prev_line->mb_cnt <= h->mb_width); 1.385 + rel_rle(&h->rl_q, &rec_token); 1.386 + notify_one_worker(h); 1.387 + rle->mb_cnt = h->mb_width +1; 1.388 + if (rle->line == h->threads-1){ 1.389 + push_sbe(&h->sb_q[OUTPUT], rle->sbe, 1); 1.390 + } 1.391 + 1.392 + free_mbrec_context(mrc); 1.393 + } 1.394 + 1.395 + free_entropy_context(ec); 1.396 + 1.397 + pthread_exit(NULL); 1.398 + return NULL; 1.399 +} 1.400 + 1.401 +static void *reorder_thread(void *arg){ 1.402 + H264Context *h = (H264Context *) arg; 1.403 + int i; 1.404 + SliceBufferEntry *reorder[h->sb_size]; 1.405 + SliceBufferEntry *sbe, *next_sbe; 1.406 + H264Slice *s; 1.407 + int reorder_cnt=0; 1.408 + unsigned next_pic_num=0; 1.409 + 1.410 + for(;;){ 1.411 + 1.412 + sbe = pop_sbe(&h->sb_q[REORDER], 1); 1.413 + 1.414 + s = &sbe->slice; 1.415 + for(i=reorder_cnt; i>0; i--){ 1.416 + if (s->coded_pic_num < reorder[i-1]->slice.coded_pic_num) 1.417 + break; 1.418 + reorder[i]=reorder[i-1]; 1.419 + } 1.420 + reorder[i]=sbe; 1.421 + 1.422 + while(reorder_cnt>=0){ 1.423 + if (next_pic_num!=reorder[reorder_cnt]->slice.coded_pic_num){ 1.424 + break; 1.425 + } 1.426 + next_sbe = reorder[reorder_cnt]; 1.427 + H264Slice *es = &next_sbe->slice; 1.428 + 1.429 + if (next_sbe->state<0) 1.430 + goto end; 1.431 + 1.432 + for (int i=0; i<2; i++){ 1.433 + for(int j=0; j< es->ref_count[i]; j++){ 1.434 + if (es->ref_list_cpn[i][j] ==-1) 1.435 + continue; 1.436 + int k; 1.437 + for (k=0; k<h->max_dpb_cnt; k++){ 1.438 + if(h->dpb[k].reference >= 2 && h->dpb[k].cpn == es->ref_list_cpn[i][j]){ 1.439 + es->dp_ref_list[i][j] = &h->dpb[k]; 1.440 + break; 1.441 + } 1.442 + } 1.443 + } 1.444 + } 1.445 + next_sbe->dp = get_dpb_entry(h, es); 1.446 + 1.447 + push_sbe(&h->sb_q[MBDEC], next_sbe, 0); 1.448 + notify_all_workers(h); 1.449 + 1.450 +// for (int i=0; i< h->mb_height; i++){ 1.451 +// push_rle(&h->rl_q, next_sbe, i, 0); 1.452 +// notify_one_worker(h); 1.453 +// } 1.454 + 1.455 + 1.456 + next_pic_num++; 1.457 + reorder_cnt--; 1.458 + } 1.459 + reorder_cnt++; 1.460 + } 1.461 + 1.462 +end: 1.463 + { 1.464 + push_sbe(&h->sb_q[MBDEC], next_sbe, 0); 1.465 + notify_all_workers(h); 1.466 + if (h->no_mbd){ 1.467 + push_sbe(&h->sb_q[OUTPUT], next_sbe, 1); 1.468 + } 1.469 +// for (int i=0; i< h->threads; i++){ 1.470 +// push_rle(&h->rl_q, next_sbe, i, 0); 1.471 +// notify_one_worker(h); 1.472 +// } 1.473 + } 1.474 + 1.475 + pthread_exit(NULL); 1.476 + return NULL; 1.477 +} 1.478 + 1.479 +void create_ed_rec_threads(H264Context *h){ 1.480 + cpu_set_t cpuset; 1.481 + int* aff; 1.482 + 1.483 + if (h->setaff){ 1.484 + aff = h->smt ? ed_rec_smt_aff : ed_rec_affinity ; 1.485 + for (int i=0; i<h->threads; i++){ 1.486 + pthread_attr_init(&h->ed_rec_attr[i]); 1.487 + CPU_ZERO(&cpuset); 1.488 + CPU_SET(aff[i], &cpuset); 1.489 + pthread_attr_setaffinity_np(&h->ed_rec_attr[i], sizeof(cpu_set_t), &cpuset); 1.490 + pthread_create(&h->ed_rec_thr[i], &h->ed_rec_attr[i], ed_rec_thread, h); 1.491 + } 1.492 + } else { 1.493 + for (int i=0; i<h->threads; i++){ 1.494 + pthread_create(&h->ed_rec_thr[i], NULL, ed_rec_thread, h); 1.495 + } 1.496 + } 1.497 +} 1.498 + 1.499 +void join_ed_rec_threads(H264Context *h){ 1.500 + for (int i=0; i< h->threads; i++){ 1.501 + pthread_join(h->ed_rec_thr[i], NULL); 1.502 + } 1.503 +} 1.504 + 1.505 +void *output_thread(void *arg){ 1.506 + H264Context *h = (H264Context *) arg; 1.507 + 1.508 + OutputContext *oc = get_output_context( h ); 1.509 + 1.510 + SliceBufferEntry *sbe = NULL; 1.511 + H264Slice *s=NULL; 1.512 + for(;;) { 1.513 + DecodedPicture *out, *dp; 1.514 + sbe = pop_sbe(&h->sb_q[OUTPUT], 1); 1.515 + 1.516 + if (sbe->state <0) 1.517 + break; 1.518 + 1.519 + s = &sbe->slice; 1.520 + for (int i=0; i<s->release_cnt; i++){ 1.521 + for(int j=0; j<h->max_dpb_cnt; j++){ 1.522 + if(h->dpb[j].cpn== s->release_ref_cpn[i]){ 1.523 + release_dpb_entry(h, &h->dpb[j], 2); 1.524 + break; 1.525 + } 1.526 + } 1.527 + } 1.528 + 1.529 + dp=sbe->dp; 1.530 + release_sb_entry(h, sbe); 1.531 + 1.532 + out =output_frame(h, oc, dp, h->ofile, h->frame_width, h->frame_height); 1.533 + if (out){ 1.534 + release_dpb_entry(h, out, 1); 1.535 + } 1.536 + 1.537 + print_report(oc->frame_number, oc->video_size, 0, h->verbose); 1.538 + 1.539 + } 1.540 + /* at the end of stream, we must flush the decoder buffers */ 1.541 + while (output_frame(h, oc, NULL, h->ofile, h->frame_width, h->frame_height)); 1.542 + print_report(oc->frame_number, oc->video_size, 1, h->verbose); 1.543 + 1.544 + free_output_context(oc); 1.545 + 1.546 + pthread_exit(NULL); 1.547 + return NULL; 1.548 +} 1.549 + 1.550 +/* 1.551 +* The following code is the main loop of the file converter 1.552 +*/ 1.553 +int h264_decode_pthread(H264Context *h) { 1.554 + pthread_t parse_thr, reorder_thr, output_thr; 1.555 + 1.556 + av_start_timer(); 1.557 + 1.558 + pthread_create(&parse_thr, NULL, parse_thread, h); 1.559 + if (!h->no_mbd){ 1.560 + pthread_create(&reorder_thr, NULL, reorder_thread, h); 1.561 + pthread_create(&output_thr, NULL, output_thread, h); 1.562 + } 1.563 +#if HAVE_LIBSDL2 1.564 + pthread_t sdl_thr; 1.565 + if (h->display){ 1.566 + pthread_create(&sdl_thr, NULL, sdl_thread, h); 1.567 + } 1.568 +#endif 1.569 + create_ed_rec_threads(h); 1.570 + 1.571 + 1.572 + if (h->rl_side_touch){ 1.573 + pthread_mutex_lock(&h->ilock); 1.574 + while (h->init_threads< h->threads) 1.575 + pthread_cond_wait(&h->icond, &h->ilock); 1.576 + pthread_mutex_unlock(&h->ilock); 1.577 + 1.578 + pthread_mutex_lock(&h->tlock); 1.579 + h->touch_start =1; 1.580 + pthread_cond_broadcast(&h->tcond); 1.581 + pthread_mutex_unlock(&h->tlock); 1.582 + 1.583 + pthread_mutex_lock(&h->tdlock); 1.584 + while (h->touch_done < h->threads) 1.585 + pthread_cond_wait(&h->tdcond, &h->tdlock); 1.586 + pthread_mutex_unlock(&h->tdlock); 1.587 + 1.588 + pthread_mutex_lock(&h->slock); 1.589 + h->start =1; 1.590 + pthread_cond_broadcast(&h->scond); 1.591 + pthread_mutex_unlock(&h->slock); 1.592 + } 1.593 + join_ed_rec_threads(h); 1.594 + pthread_join(parse_thr, NULL); 1.595 + if (!h->no_mbd){ 1.596 + pthread_join(reorder_thr, NULL); 1.597 + pthread_join(output_thr, NULL); 1.598 + } 1.599 +#if HAVE_LIBSDL2 1.600 + if (h->display) 1.601 + signal_sdl_exit(h); 1.602 + pthread_join(sdl_thr, NULL); 1.603 +#endif 1.604 + 1.605 + 1.606 + return 0; 1.607 +}
