| 299 | } |
| 300 | |
| 301 | int ff_thread_video_encode_frame(AVCodecContext *avctx, AVPacket *pkt, |
| 302 | AVFrame *frame, int *got_packet_ptr) |
| 303 | { |
| 304 | ThreadContext *c = avctx->internal->frame_thread_encoder; |
| 305 | Task *outtask; |
| 306 | |
| 307 | av_assert1(!*got_packet_ptr); |
| 308 | |
| 309 | if(frame){ |
| 310 | av_frame_move_ref(c->tasks[c->task_index].indata, frame); |
| 311 | |
| 312 | pthread_mutex_lock(&c->task_fifo_mutex); |
| 313 | c->task_index = (c->task_index + 1) % c->max_tasks; |
| 314 | pthread_cond_signal(&c->task_fifo_cond); |
| 315 | pthread_mutex_unlock(&c->task_fifo_mutex); |
| 316 | } |
| 317 | |
| 318 | outtask = &c->tasks[c->finished_task_index]; |
| 319 | pthread_mutex_lock(&c->finished_task_mutex); |
| 320 | /* The access to task_index in the following code is ok, |
| 321 | * because it is only ever changed by the main thread. */ |
| 322 | if (c->task_index == c->finished_task_index || |
| 323 | (frame && !outtask->finished && |
| 324 | (c->task_index - c->finished_task_index + c->max_tasks) % c->max_tasks <= avctx->thread_count)) { |
| 325 | pthread_mutex_unlock(&c->finished_task_mutex); |
| 326 | return 0; |
| 327 | } |
| 328 | while (!outtask->finished) { |
| 329 | pthread_cond_wait(&c->finished_task_cond, &c->finished_task_mutex); |
| 330 | } |
| 331 | pthread_mutex_unlock(&c->finished_task_mutex); |
| 332 | /* We now own outtask completely: No worker thread touches it any more, |
| 333 | * because there is no outstanding task with this index. */ |
| 334 | outtask->finished = 0; |
| 335 | av_packet_move_ref(pkt, outtask->outdata); |
| 336 | *got_packet_ptr = outtask->got_packet; |
| 337 | c->finished_task_index = (c->finished_task_index + 1) % c->max_tasks; |
| 338 | |
| 339 | return outtask->return_code; |
| 340 | } |
no test coverage detected