static int encode_frame(AVCodecContext* avc_context, uint8_t *outbuf,

                        int buf_size, void *data)

{

    th_ycbcr_buffer t_yuv_buffer;

    TheoraContext *h = avc_context->priv_data;

    AVFrame *frame = data;

    ogg_packet o_packet;

    int result, i;



    // EOS, finish and get 1st pass stats if applicable

    if (!frame) {

        th_encode_packetout(h->t_state, 1, &o_packet);

        if (avc_context->flags & CODEC_FLAG_PASS1)

            if (get_stats(avc_context, 1))

                return -1;

        return 0;

    }



    /* Copy planes to the theora yuv_buffer */

    for (i = 0; i < 3; i++) {

        t_yuv_buffer[i].width  = FFALIGN(avc_context->width,  16) >> (i && h->uv_hshift);

        t_yuv_buffer[i].height = FFALIGN(avc_context->height, 16) >> (i && h->uv_vshift);

        t_yuv_buffer[i].stride = frame->linesize[i];

        t_yuv_buffer[i].data   = frame->data[i];

    }



    if (avc_context->flags & CODEC_FLAG_PASS2)

        if (submit_stats(avc_context))

            return -1;



    /* Now call into theora_encode_YUVin */

    result = th_encode_ycbcr_in(h->t_state, t_yuv_buffer);

    if (result) {

        const char* message;

        switch (result) {

        case -1:

            message = "differing frame sizes";

            break;

        case TH_EINVAL:

            message = "encoder is not ready or is finished";

            break;

        default:

            message = "unknown reason";

            break;

        }

        av_log(avc_context, AV_LOG_ERROR, "theora_encode_YUVin failed (%s) [%d]\n", message, result);

        return -1;

    }



    if (avc_context->flags & CODEC_FLAG_PASS1)

        if (get_stats(avc_context, 0))

            return -1;



    /* Pick up returned ogg_packet */

    result = th_encode_packetout(h->t_state, 0, &o_packet);

    switch (result) {

    case 0:

        /* No packet is ready */

        return 0;

    case 1:

        /* Success, we have a packet */

        break;

    default:

        av_log(avc_context, AV_LOG_ERROR, "theora_encode_packetout failed [%d]\n", result);

        return -1;

    }



    /* Copy ogg_packet content out to buffer */

    if (buf_size < o_packet.bytes) {

        av_log(avc_context, AV_LOG_ERROR, "encoded frame too large\n");

        return -1;

    }

    memcpy(outbuf, o_packet.packet, o_packet.bytes);



    // HACK: does not take codec delay into account (neither does the decoder though)

    avc_context->coded_frame->pts = frame->pts;

    avc_context->coded_frame->key_frame = !(o_packet.granulepos & h->keyframe_mask);



    return o_packet.bytes;

}

static int encode_frame(AVCodecContext* avc_context, uint8_t *outbuf,

                        int buf_size, void *data)

{

    th_ycbcr_buffer t_yuv_buffer;

    TheoraContext *h = avc_context->priv_data;

    AVFrame *frame = data;

    ogg_packet o_packet;

    int result, i;



    

    if (!frame) {

        th_encode_packetout(h->t_state, 1, &o_packet);

        if (avc_context->flags & CODEC_FLAG_PASS1)

            if (get_stats(avc_context, 1))

                return -1;

        return 0;

    }



    

    for (i = 0; i < 3; i++) {

        t_yuv_buffer[i].width  = FFALIGN(avc_context->width,  16) >> (i && h->uv_hshift);

        t_yuv_buffer[i].height = FFALIGN(avc_context->height, 16) >> (i && h->uv_vshift);

        t_yuv_buffer[i].stride = frame->linesize[i];

        t_yuv_buffer[i].data   = frame->data[i];

    }



    if (avc_context->flags & CODEC_FLAG_PASS2)

        if (submit_stats(avc_context))

            return -1;



    

    result = th_encode_ycbcr_in(h->t_state, t_yuv_buffer);

    if (result) {

        const char* message;

        switch (result) {

        case -1:

            message = "differing frame sizes";

            break;

        case TH_EINVAL:

            message = "encoder is not ready or is finished";

            break;

        default:

            message = "unknown reason";

            break;

        }

        av_log(avc_context, AV_LOG_ERROR, "theora_encode_YUVin failed (%s) [%d]\n", message, result);

        return -1;

    }



    if (avc_context->flags & CODEC_FLAG_PASS1)

        if (get_stats(avc_context, 0))

            return -1;



    

    result = th_encode_packetout(h->t_state, 0, &o_packet);

    switch (result) {

    case 0:

        

        return 0;

    case 1:

        

        break;

    default:

        av_log(avc_context, AV_LOG_ERROR, "theora_encode_packetout failed [%d]\n", result);

        return -1;

    }



    

    if (buf_size < o_packet.bytes) {

        av_log(avc_context, AV_LOG_ERROR, "encoded frame too large\n");

        return -1;

    }

    memcpy(outbuf, o_packet.packet, o_packet.bytes);



    

    avc_context->coded_frame->pts = frame->pts;

    avc_context->coded_frame->key_frame = !(o_packet.granulepos & h->keyframe_mask);



    return o_packet.bytes;

}

static int FUNC_0(AVCodecContext* VAR_0, uint8_t *VAR_1,

                        int VAR_2, void *VAR_3)

{

    th_ycbcr_buffer t_yuv_buffer;

    TheoraContext *h = VAR_0->priv_data;

    AVFrame *frame = VAR_3;

    ogg_packet o_packet;

    int VAR_4, VAR_5;



    

    if (!frame) {

        th_encode_packetout(h->t_state, 1, &o_packet);

        if (VAR_0->flags & CODEC_FLAG_PASS1)

            if (get_stats(VAR_0, 1))

                return -1;

        return 0;

    }



    

    for (VAR_5 = 0; VAR_5 < 3; VAR_5++) {

        t_yuv_buffer[VAR_5].width  = FFALIGN(VAR_0->width,  16) >> (VAR_5 && h->uv_hshift);

        t_yuv_buffer[VAR_5].height = FFALIGN(VAR_0->height, 16) >> (VAR_5 && h->uv_vshift);

        t_yuv_buffer[VAR_5].stride = frame->linesize[VAR_5];

        t_yuv_buffer[VAR_5].VAR_3   = frame->VAR_3[VAR_5];

    }



    if (VAR_0->flags & CODEC_FLAG_PASS2)

        if (submit_stats(VAR_0))

            return -1;



    

    VAR_4 = th_encode_ycbcr_in(h->t_state, t_yuv_buffer);

    if (VAR_4) {

        const char* VAR_6;

        switch (VAR_4) {

        case -1:

            VAR_6 = "differing frame sizes";

            break;

        case TH_EINVAL:

            VAR_6 = "encoder is not ready or is finished";

            break;

        default:

            VAR_6 = "unknown reason";

            break;

        }

        av_log(VAR_0, AV_LOG_ERROR, "theora_encode_YUVin failed (%s) [%d]\n", VAR_6, VAR_4);

        return -1;

    }



    if (VAR_0->flags & CODEC_FLAG_PASS1)

        if (get_stats(VAR_0, 0))

            return -1;



    

    VAR_4 = th_encode_packetout(h->t_state, 0, &o_packet);

    switch (VAR_4) {

    case 0:

        

        return 0;

    case 1:

        

        break;

    default:

        av_log(VAR_0, AV_LOG_ERROR, "theora_encode_packetout failed [%d]\n", VAR_4);

        return -1;

    }



    

    if (VAR_2 < o_packet.bytes) {

        av_log(VAR_0, AV_LOG_ERROR, "encoded frame too large\n");

        return -1;

    }

    memcpy(VAR_1, o_packet.packet, o_packet.bytes);



    

    VAR_0->coded_frame->pts = frame->pts;

    VAR_0->coded_frame->key_frame = !(o_packet.granulepos & h->keyframe_mask);



    return o_packet.bytes;

}

static int FUNC_0(AVCodecContext* VAR_0, uint8_t *VAR_1,
int VAR_2, void *VAR_3)
{ th_ycbcr_buffer t_yuv_buffer; TheoraContext *h = VAR_0->priv_data; AVFrame *frame = VAR_3; ogg_packet o_packet; int VAR_4, VAR_5; if (!frame) { th_encode_packetout(h->t_state, 1, &o_packet); if (VAR_0->flags & CODEC_FLAG_PASS1)
if (get_stats(VAR_0, 1))
return -1; return 0; } for (VAR_5 = 0; VAR_5 < 3; VAR_5++) { t_yuv_buffer[VAR_5].width  = FFALIGN(VAR_0->width,  16) >> (VAR_5 && h->uv_hshift); t_yuv_buffer[VAR_5].height = FFALIGN(VAR_0->height, 16) >> (VAR_5 && h->uv_vshift); t_yuv_buffer[VAR_5].stride = frame->linesize[VAR_5]; t_yuv_buffer[VAR_5].VAR_3   = frame->VAR_3[VAR_5]; } if (VAR_0->flags & CODEC_FLAG_PASS2)
if (submit_stats(VAR_0))
return -1; VAR_4 = th_encode_ycbcr_in(h->t_state, t_yuv_buffer); if (VAR_4) { const char* VAR_6; switch (VAR_4) { case -1:
VAR_6 = "differing frame sizes"; break; case TH_EINVAL:
VAR_6 = "encoder is not ready or is finished"; break; default:
VAR_6 = "unknown reason"; break; } av_log(VAR_0, AV_LOG_ERROR, "theora_encode_YUVin failed (%s) [%d]\n", VAR_6, VAR_4); return -1; } if (VAR_0->flags & CODEC_FLAG_PASS1)
if (get_stats(VAR_0, 0))
return -1; VAR_4 = th_encode_packetout(h->t_state, 0, &o_packet); switch (VAR_4) { case 0:
return 0; case 1:
break; default:
av_log(VAR_0, AV_LOG_ERROR, "theora_encode_packetout failed [%d]\n", VAR_4); return -1; } if (VAR_2 < o_packet.bytes) { av_log(VAR_0, AV_LOG_ERROR, "encoded frame too large\n"); return -1; } memcpy(VAR_1, o_packet.packet, o_packet.bytes); VAR_0->coded_frame->pts = frame->pts; VAR_0->coded_frame->key_frame = !(o_packet.granulepos & h->keyframe_mask); return o_packet.bytes; }