int ff_thread_video_encode_frame(AVCodecContext *avctx, AVPacket *pkt, const AVFrame *frame, int *got_packet_ptr){

    ThreadContext *c = avctx->internal->frame_thread_encoder;

    Task task;

    int ret;



    av_assert1(!*got_packet_ptr);



    if(frame){

        if(!(avctx->flags & CODEC_FLAG_INPUT_PRESERVED)){

            AVFrame *new = avcodec_alloc_frame();

            if(!new)

                return AVERROR(ENOMEM);

            pthread_mutex_lock(&c->buffer_mutex);

            ret = c->parent_avctx->get_buffer(c->parent_avctx, new);

            pthread_mutex_unlock(&c->buffer_mutex);

            if(ret<0)

                return ret;

            new->pts = frame->pts;

            new->quality = frame->quality;

            new->pict_type = frame->pict_type;

            av_image_copy(new->data, new->linesize, (const uint8_t **)frame->data, frame->linesize,

                          avctx->pix_fmt, avctx->width, avctx->height);

            frame = new;

        }



        task.index = c->task_index;

        task.indata = (void*)frame;

        pthread_mutex_lock(&c->task_fifo_mutex);

        av_fifo_generic_write(c->task_fifo, &task, sizeof(task), NULL);

        pthread_cond_signal(&c->task_fifo_cond);

        pthread_mutex_unlock(&c->task_fifo_mutex);



        c->task_index = (c->task_index+1) % BUFFER_SIZE;



        if(!c->finished_tasks[c->finished_task_index].outdata && (c->task_index - c->finished_task_index) % BUFFER_SIZE <= avctx->thread_count)

            return 0;

    }



    if(c->task_index == c->finished_task_index)

        return 0;



    pthread_mutex_lock(&c->finished_task_mutex);

    while (!c->finished_tasks[c->finished_task_index].outdata) {

        pthread_cond_wait(&c->finished_task_cond, &c->finished_task_mutex);

    }

    task = c->finished_tasks[c->finished_task_index];

    *pkt = *(AVPacket*)(task.outdata);

    av_freep(&c->finished_tasks[c->finished_task_index].outdata);

    c->finished_task_index = (c->finished_task_index+1) % BUFFER_SIZE;

    pthread_mutex_unlock(&c->finished_task_mutex);



    *got_packet_ptr = 1;



    return task.return_code;

}

int ff_thread_video_encode_frame(AVCodecContext *avctx, AVPacket *pkt, const AVFrame *frame, int *got_packet_ptr){

    ThreadContext *c = avctx->internal->frame_thread_encoder;

    Task task;

    int ret;



    av_assert1(!*got_packet_ptr);



    if(frame){

        if(!(avctx->flags & CODEC_FLAG_INPUT_PRESERVED)){

            AVFrame *new = avcodec_alloc_frame();

            if(!new)

                return AVERROR(ENOMEM);

            pthread_mutex_lock(&c->buffer_mutex);

            ret = c->parent_avctx->get_buffer(c->parent_avctx, new);

            pthread_mutex_unlock(&c->buffer_mutex);

            if(ret<0)

                return ret;

            new->pts = frame->pts;

            new->quality = frame->quality;

            new->pict_type = frame->pict_type;

            av_image_copy(new->data, new->linesize, (const uint8_t **)frame->data, frame->linesize,

                          avctx->pix_fmt, avctx->width, avctx->height);

            frame = new;

        }



        task.index = c->task_index;

        task.indata = (void*)frame;

        pthread_mutex_lock(&c->task_fifo_mutex);

        av_fifo_generic_write(c->task_fifo, &task, sizeof(task), NULL);

        pthread_cond_signal(&c->task_fifo_cond);

        pthread_mutex_unlock(&c->task_fifo_mutex);



        c->task_index = (c->task_index+1) % BUFFER_SIZE;



        if(!c->finished_tasks[c->finished_task_index].outdata && (c->task_index - c->finished_task_index) % BUFFER_SIZE <= avctx->thread_count)

            return 0;

    }



    if(c->task_index == c->finished_task_index)

        return 0;



    pthread_mutex_lock(&c->finished_task_mutex);

    while (!c->finished_tasks[c->finished_task_index].outdata) {

        pthread_cond_wait(&c->finished_task_cond, &c->finished_task_mutex);

    }

    task = c->finished_tasks[c->finished_task_index];

    *pkt = *(AVPacket*)(task.outdata);

    av_freep(&c->finished_tasks[c->finished_task_index].outdata);

    c->finished_task_index = (c->finished_task_index+1) % BUFFER_SIZE;

    pthread_mutex_unlock(&c->finished_task_mutex);



    *got_packet_ptr = 1;



    return task.return_code;

}

    *got_packet_ptr = 1;
int FUNC_0(AVCodecContext *VAR_0, AVPacket *VAR_1, const AVFrame *VAR_2, int *VAR_3){

    ThreadContext *c = VAR_0->internal->frame_thread_encoder;

    Task task;

    int VAR_4;



    av_assert1(!*VAR_3);



    if(VAR_2){

        if(!(VAR_0->flags & CODEC_FLAG_INPUT_PRESERVED)){

            AVFrame *new = avcodec_alloc_frame();

            if(!new)

                return AVERROR(ENOMEM);

            pthread_mutex_lock(&c->buffer_mutex);

            VAR_4 = c->parent_avctx->get_buffer(c->parent_avctx, new);

            pthread_mutex_unlock(&c->buffer_mutex);

            if(VAR_4<0)

                return VAR_4;

            new->pts = VAR_2->pts;

            new->quality = VAR_2->quality;

            new->pict_type = VAR_2->pict_type;

            av_image_copy(new->data, new->linesize, (const uint8_t **)VAR_2->data, VAR_2->linesize,

                          VAR_0->pix_fmt, VAR_0->width, VAR_0->height);

            VAR_2 = new;

        }



        task.index = c->task_index;

        task.indata = (void*)VAR_2;

        pthread_mutex_lock(&c->task_fifo_mutex);

        av_fifo_generic_write(c->task_fifo, &task, sizeof(task), NULL);

        pthread_cond_signal(&c->task_fifo_cond);

        pthread_mutex_unlock(&c->task_fifo_mutex);



        c->task_index = (c->task_index+1) % BUFFER_SIZE;



        if(!c->finished_tasks[c->finished_task_index].outdata && (c->task_index - c->finished_task_index) % BUFFER_SIZE <= VAR_0->thread_count)

            return 0;

    }



    if(c->task_index == c->finished_task_index)

        return 0;



    pthread_mutex_lock(&c->finished_task_mutex);

    while (!c->finished_tasks[c->finished_task_index].outdata) {

        pthread_cond_wait(&c->finished_task_cond, &c->finished_task_mutex);

    }

    task = c->finished_tasks[c->finished_task_index];

    *VAR_1 = *(AVPacket*)(task.outdata);

    av_freep(&c->finished_tasks[c->finished_task_index].outdata);

    c->finished_task_index = (c->finished_task_index+1) % BUFFER_SIZE;

    pthread_mutex_unlock(&c->finished_task_mutex);



    *VAR_3 = 1;



    return task.return_code;

}

int FUNC_0(AVCodecContext *VAR_0, AVPacket *VAR_1, const AVFrame *VAR_2, int *VAR_3){ ThreadContext *c = VAR_0->internal->frame_thread_encoder; Task task; int VAR_4; av_assert1(!*VAR_3); if(VAR_2){ if(!(VAR_0->flags & CODEC_FLAG_INPUT_PRESERVED)){ AVFrame *new = avcodec_alloc_frame(); if(!new)
return AVERROR(ENOMEM); pthread_mutex_lock(&c->buffer_mutex); VAR_4 = c->parent_avctx->get_buffer(c->parent_avctx, new); pthread_mutex_unlock(&c->buffer_mutex); if(VAR_4<0)
return VAR_4; new->pts = VAR_2->pts; new->quality = VAR_2->quality; new->pict_type = VAR_2->pict_type; av_image_copy(new->data, new->linesize, (const uint8_t **)VAR_2->data, VAR_2->linesize,
VAR_0->pix_fmt, VAR_0->width, VAR_0->height); VAR_2 = new; } task.index = c->task_index; task.indata = (void*)VAR_2; pthread_mutex_lock(&c->task_fifo_mutex); av_fifo_generic_write(c->task_fifo, &task, sizeof(task), NULL); pthread_cond_signal(&c->task_fifo_cond); pthread_mutex_unlock(&c->task_fifo_mutex); c->task_index = (c->task_index+1) % BUFFER_SIZE; if(!c->finished_tasks[c->finished_task_index].outdata && (c->task_index - c->finished_task_index) % BUFFER_SIZE <= VAR_0->thread_count)
return 0; } if(c->task_index == c->finished_task_index)
return 0; pthread_mutex_lock(&c->finished_task_mutex); while (!c->finished_tasks[c->finished_task_index].outdata) { pthread_cond_wait(&c->finished_task_cond, &c->finished_task_mutex); } task = c->finished_tasks[c->finished_task_index]; *VAR_1 = *(AVPacket*)(task.outdata); av_freep(&c->finished_tasks[c->finished_task_index].outdata); c->finished_task_index = (c->finished_task_index+1) % BUFFER_SIZE; pthread_mutex_unlock(&c->finished_task_mutex); *VAR_3 = 1; return task.return_code; }