int ff_thread_get_buffer(AVCodecContext *avctx, AVFrame *f) { PerThreadContext *p = avctx->thread_opaque; int *progress, err; f->owner = avctx; ff_init_buffer_info(avctx, f); if (!(avctx->active_thread_type&FF_THREAD_FRAME)) { f->thread_opaque = NULL; return avctx->get_buffer(avctx, f); } if (p->state != STATE_SETTING_UP && (avctx->codec->update_thread_context || (!avctx->thread_safe_callbacks && avctx->get_buffer != avcodec_default_get_buffer))) { av_log(avctx, AV_LOG_ERROR, "get_buffer() cannot be called after ff_thread_finish_setup()\n"); return -1; } pthread_mutex_lock(&p->parent->buffer_mutex); f->thread_opaque = progress = allocate_progress(p); if (!progress) { pthread_mutex_unlock(&p->parent->buffer_mutex); return -1; } progress[0] = progress[1] = -1; if (avctx->thread_safe_callbacks || avctx->get_buffer == avcodec_default_get_buffer) { err = avctx->get_buffer(avctx, f); } else { p->requested_frame = f; p->state = STATE_GET_BUFFER; pthread_mutex_lock(&p->progress_mutex); pthread_cond_broadcast(&p->progress_cond); while (p->state != STATE_SETTING_UP) pthread_cond_wait(&p->progress_cond, &p->progress_mutex); err = p->result; pthread_mutex_unlock(&p->progress_mutex); if (!avctx->codec->update_thread_context) ff_thread_finish_setup(avctx); } if (err) { free_progress(f); f->thread_opaque = NULL; } pthread_mutex_unlock(&p->parent->buffer_mutex); return err; }
static gint progress_end_cb(GWEN_GUI *gwen_gui, guint32 id) { GncGWENGui *gui = GETDATA_GUI(gwen_gui); Progress *progress; g_return_val_if_fail(gui, -1); g_return_val_if_fail(id == g_list_length(gui->progresses), -1); ENTER("gui=%p, id=%d", gui, id); if (gui->state != RUNNING) { /* Ignore finishes of progresses we do not track */ LEAVE("not running anymore"); return 0; } /* Hide progress */ progress = (Progress*) gui->progresses->data; hide_progress(gui, progress); /* Remove progress from stack and free memory */ gui->progresses = g_list_delete_link(gui->progresses, gui->progresses); free_progress(progress, NULL); if (!gui->progresses) { /* top-level progress finished */ set_finished(gui); } LEAVE(" "); return 0; }
/// Releases the buffers that this decoding thread was the last user of. static void release_delayed_buffers(PerThreadContext *p) { FrameThreadContext *fctx = p->parent; while (p->num_released_buffers > 0) { AVFrame *f; pthread_mutex_lock(&fctx->buffer_mutex); f = &p->released_buffers[--p->num_released_buffers]; free_progress(f); f->thread_opaque = NULL; f->owner->release_buffer(f->owner, f); pthread_mutex_unlock(&fctx->buffer_mutex); } }