AVCodecContext *avctx = p->avctx;
AVCodec *codec = avctx->codec;
+ pthread_mutex_lock(&p->mutex);
while (1) {
int i;
- if (p->state == STATE_INPUT_READY && !fctx->die) {
- pthread_mutex_lock(&p->mutex);
while (p->state == STATE_INPUT_READY && !fctx->die)
pthread_cond_wait(&p->input_cond, &p->mutex);
- pthread_mutex_unlock(&p->mutex);
- }
if (fctx->die) break;
if (!codec->update_thread_context && (avctx->thread_safe_callbacks || avctx->get_buffer == avcodec_default_get_buffer))
ff_thread_finish_setup(avctx);
- pthread_mutex_lock(&p->mutex);
avcodec_get_frame_defaults(&p->frame);
p->got_frame = 0;
p->result = codec->decode(avctx, &p->frame, &p->got_frame, &p->avpkt);
pthread_cond_broadcast(&p->progress_cond);
pthread_cond_signal(&p->output_cond);
pthread_mutex_unlock(&p->progress_mutex);
-
- pthread_mutex_unlock(&p->mutex);
}
+ pthread_mutex_unlock(&p->mutex);
return NULL;
}
int err = 0;
if (dst != src) {
- dst->sub_id = src->sub_id;
dst->time_base = src->time_base;
dst->width = src->width;
dst->height = src->height;
dst->release_buffer = src->release_buffer;
dst->opaque = src->opaque;
- dst->dsp_mask = src->dsp_mask;
dst->debug = src->debug;
dst->debug_mv = src->debug_mv;
* If we're still receiving the initial packets, don't return a frame.
*/
- if (fctx->delaying && avpkt->size) {
+ if (fctx->delaying) {
if (fctx->next_decoding >= (avctx->thread_count-1)) fctx->delaying = 0;
*got_picture_ptr=0;
- return avpkt->size;
+ if (avpkt->size)
+ return avpkt->size;
}
/*
*picture = p->frame;
*got_picture_ptr = p->got_frame;
picture->pkt_dts = p->avpkt.dts;
- picture->sample_aspect_ratio = avctx->sample_aspect_ratio;
- picture->width = avctx->width;
- picture->height = avctx->height;
- picture->format = avctx->pix_fmt;
/*
* A later call with avkpt->size == 0 may loop over all threads,
if (err) goto error;
- p->thread_init= !pthread_create(&p->thread, NULL, frame_worker_thread, p);
+ err = AVERROR(pthread_create(&p->thread, NULL, frame_worker_thread, p));
+ p->thread_init= !err;
if(!p->thread_init)
goto error;
}
void ff_thread_flush(AVCodecContext *avctx)
{
FrameThreadContext *fctx = avctx->thread_opaque;
+ int i;
if (!avctx->thread_opaque) return;
fctx->next_decoding = fctx->next_finished = 0;
fctx->delaying = 1;
fctx->prev_thread = NULL;
+ for (i = 0; i < avctx->thread_count; i++) {
+ PerThreadContext *p = &fctx->threads[i];
+ // Make sure decode flush calls with size=0 won't return old frames
+ p->got_frame = 0;
+
+ release_delayed_buffers(p);
+ }
}
static int *allocate_progress(PerThreadContext *p)
return p->progress[i];
}
+int ff_thread_can_start_frame(AVCodecContext *avctx)
+{
+ PerThreadContext *p = avctx->thread_opaque;
+ if ((avctx->active_thread_type&FF_THREAD_FRAME) && p->state != STATE_SETTING_UP &&
+ (avctx->codec->update_thread_context || (!avctx->thread_safe_callbacks &&
+ avctx->get_buffer != avcodec_default_get_buffer))) {
+ return 0;
+ }
+ return 1;
+}
+
int ff_thread_get_buffer(AVCodecContext *avctx, AVFrame *f)
{
PerThreadContext *p = avctx->thread_opaque;
ff_thread_finish_setup(avctx);
}
+ if (err) {
+ free_progress(f);
+ f->thread_opaque = NULL;
+ }
pthread_mutex_unlock(&p->parent->buffer_mutex);
return err;
avctx->thread_count = 1;
avctx->active_thread_type = 0;
}
+
+ if (avctx->thread_count > MAX_AUTO_THREADS)
+ av_log(avctx, AV_LOG_WARNING,
+ "Application has requested %d threads. Using a thread count greater than %d is not recommended.\n",
+ avctx->thread_count, MAX_AUTO_THREADS);
}
int ff_thread_init(AVCodecContext *avctx)