예제 #1
0
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;
}
예제 #2
0
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;
}
예제 #3
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);
    }
}