static int rd_frame(CinepakEncContext *s, const AVFrame *frame, int isakeyframe, unsigned char *buf, int buf_size)

{

    int num_strips, strip, i, y, nexty, size, temp_size, best_size;

    AVPicture last_pict, pict, scratch_pict;

    int64_t best_score = 0, score, score_temp;

#ifdef CINEPAK_REPORT_SERR

    int64_t best_serr = 0, serr, serr_temp;

#endif



    int best_nstrips;



    if(s->pix_fmt == AV_PIX_FMT_RGB24) {

        int x;

// build a copy of the given frame in the correct colorspace

        for(y = 0; y < s->h; y += 2) {

            for(x = 0; x < s->w; x += 2) {

                uint8_t *ir[2]; int32_t r, g, b, rr, gg, bb;

                ir[0] = ((AVPicture*)frame)->data[0] + x*3 + y*((AVPicture*)frame)->linesize[0];

                ir[1] = ir[0] + ((AVPicture*)frame)->linesize[0];

                get_sub_picture(s, x, y, (AVPicture*)s->input_frame, &scratch_pict);

                r = g = b = 0;

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

                    int i1, i2;

                    i1 = (i&1); i2 = (i>=2);

                    rr = ir[i2][i1*3+0];

                    gg = ir[i2][i1*3+1];

                    bb = ir[i2][i1*3+2];

                    r += rr; g += gg; b += bb;

// using fixed point arithmetic for portable repeatability, scaling by 2^23

// "Y"

//                    rr = 0.2857*rr + 0.5714*gg + 0.1429*bb;

                    rr = (2396625*rr + 4793251*gg + 1198732*bb) >> 23;

                    if(      rr <   0) rr =   0;

                    else if (rr > 255) rr = 255;

                    scratch_pict.data[0][i1 + i2*scratch_pict.linesize[0]] = rr;

                }

// let us scale down as late as possible

//                r /= 4; g /= 4; b /= 4;

// "U"

//                rr = -0.1429*r - 0.2857*g + 0.4286*b;

                rr = (-299683*r - 599156*g + 898839*b) >> 23;

                if(      rr < -128) rr = -128;

                else if (rr >  127) rr =  127;

                scratch_pict.data[1][0] = rr + 128; // quantize needs unsigned

// "V"

//                rr = 0.3571*r - 0.2857*g - 0.0714*b;

                rr = (748893*r - 599156*g - 149737*b) >> 23;

                if(      rr < -128) rr = -128;

                else if (rr >  127) rr =  127;

                scratch_pict.data[2][0] = rr + 128; // quantize needs unsigned

            }

        }

    }



    //would be nice but quite certainly incompatible with vintage players:

    // support encoding zero strips (meaning skip the whole frame)

    for(num_strips = s->min_strips; num_strips <= s->max_strips && num_strips <= s->h / MB_SIZE; num_strips++) {

        score = 0;

        size = 0;

#ifdef CINEPAK_REPORT_SERR

        serr = 0;

#endif



        for(y = 0, strip = 1; y < s->h; strip++, y = nexty) {

            int strip_height;



            nexty = strip * s->h / num_strips; // <= s->h

            //make nexty the next multiple of 4 if not already there

            if(nexty & 3)

                nexty += 4 - (nexty & 3);



            strip_height = nexty - y;

            if(strip_height <= 0) { // can this ever happen?

                av_log(s->avctx, AV_LOG_INFO, "skipping zero height strip %i of %i\n", strip, num_strips);

                continue;

            }



            if(s->pix_fmt == AV_PIX_FMT_RGB24)

                get_sub_picture(s, 0, y, (AVPicture*)s->input_frame,    &pict);

            else

                get_sub_picture(s, 0, y, (AVPicture*)frame,              &pict);

            get_sub_picture(s, 0, y, (AVPicture*)s->last_frame,    &last_pict);

            get_sub_picture(s, 0, y, (AVPicture*)s->scratch_frame, &scratch_pict);



            if((temp_size = rd_strip(s, y, strip_height, isakeyframe, &last_pict, &pict, &scratch_pict, s->frame_buf + size + CVID_HEADER_SIZE, &score_temp

#ifdef CINEPAK_REPORT_SERR

, &serr_temp

#endif

)) < 0)

                return temp_size;



            score += score_temp;

#ifdef CINEPAK_REPORT_SERR

            serr += serr_temp;

#endif

            size += temp_size;

            //av_log(s->avctx, AV_LOG_INFO, "strip %d, isakeyframe=%d", strip, isakeyframe);

            //av_log(s->avctx, AV_LOG_INFO, "\n");

        }



        if(best_score == 0 || score < best_score) {

            best_score = score;

#ifdef CINEPAK_REPORT_SERR

            best_serr = serr;

#endif

            best_size = size + write_cvid_header(s, s->frame_buf, num_strips, size, isakeyframe);

            //av_log(s->avctx, AV_LOG_INFO, "best number of strips so far: %2i, %12lli, %i B\n", num_strips, (long long int)score, best_size);

#ifdef CINEPAK_REPORT_SERR

            av_log(s->avctx, AV_LOG_INFO, "best number of strips so far: %2i, %12lli, %i B\n", num_strips, (long long int)serr, best_size);

#endif



            FFSWAP(AVFrame *, s->best_frame, s->scratch_frame);

            memcpy(buf, s->frame_buf, best_size);

            best_nstrips = num_strips;

        }

// avoid trying too many strip numbers without a real reason

// (this makes the processing of the very first frame faster)

        if(num_strips - best_nstrips > 4)

            break;

    }



// let the number of strips slowly adapt to the changes in the contents,

// compared to full bruteforcing every time this will occasionally lead

// to some r/d performance loss but makes encoding up to several times faster

    if(!s->strip_number_delta_range) {

        if(best_nstrips == s->max_strips) { // let us try to step up

            s->max_strips = best_nstrips + 1;

            if(s->max_strips >= s->max_max_strips)

                s->max_strips = s->max_max_strips;

        } else { // try to step down

            s->max_strips = best_nstrips;

        }

        s->min_strips = s->max_strips - 1;

        if(s->min_strips < s->min_min_strips)

            s->min_strips = s->min_min_strips;

    } else {

        s->max_strips = best_nstrips + s->strip_number_delta_range;

        if(s->max_strips >= s->max_max_strips)

            s->max_strips = s->max_max_strips;

        s->min_strips = best_nstrips - s->strip_number_delta_range;

        if(s->min_strips < s->min_min_strips)

            s->min_strips = s->min_min_strips;

    }



    return best_size;

}

static int rd_frame(CinepakEncContext *s, const AVFrame *frame, int isakeyframe, unsigned char *buf, int buf_size)

{

    int num_strips, strip, i, y, nexty, size, temp_size, best_size;

    AVPicture last_pict, pict, scratch_pict;

    int64_t best_score = 0, score, score_temp;

#ifdef CINEPAK_REPORT_SERR

    int64_t best_serr = 0, serr, serr_temp;

#endif



    int best_nstrips;



    if(s->pix_fmt == AV_PIX_FMT_RGB24) {

        int x;



        for(y = 0; y < s->h; y += 2) {

            for(x = 0; x < s->w; x += 2) {

                uint8_t *ir[2]; int32_t r, g, b, rr, gg, bb;

                ir[0] = ((AVPicture*)frame)->data[0] + x*3 + y*((AVPicture*)frame)->linesize[0];

                ir[1] = ir[0] + ((AVPicture*)frame)->linesize[0];

                get_sub_picture(s, x, y, (AVPicture*)s->input_frame, &scratch_pict);

                r = g = b = 0;

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

                    int i1, i2;

                    i1 = (i&1); i2 = (i>=2);

                    rr = ir[i2][i1*3+0];

                    gg = ir[i2][i1*3+1];

                    bb = ir[i2][i1*3+2];

                    r += rr; g += gg; b += bb;







                    rr = (2396625*rr + 4793251*gg + 1198732*bb) >> 23;

                    if(      rr <   0) rr =   0;

                    else if (rr > 255) rr = 255;

                    scratch_pict.data[0][i1 + i2*scratch_pict.linesize[0]] = rr;

                }









                rr = (-299683*r - 599156*g + 898839*b) >> 23;

                if(      rr < -128) rr = -128;

                else if (rr >  127) rr =  127;

                scratch_pict.data[1][0] = rr + 128; 





                rr = (748893*r - 599156*g - 149737*b) >> 23;

                if(      rr < -128) rr = -128;

                else if (rr >  127) rr =  127;

                scratch_pict.data[2][0] = rr + 128; 

            }

        }

    }



    

    

    for(num_strips = s->min_strips; num_strips <= s->max_strips && num_strips <= s->h / MB_SIZE; num_strips++) {

        score = 0;

        size = 0;

#ifdef CINEPAK_REPORT_SERR

        serr = 0;

#endif



        for(y = 0, strip = 1; y < s->h; strip++, y = nexty) {

            int strip_height;



            nexty = strip * s->h / num_strips; 

            

            if(nexty & 3)

                nexty += 4 - (nexty & 3);



            strip_height = nexty - y;

            if(strip_height <= 0) { 

                av_log(s->avctx, AV_LOG_INFO, "skipping zero height strip %i of %i\n", strip, num_strips);

                continue;

            }



            if(s->pix_fmt == AV_PIX_FMT_RGB24)

                get_sub_picture(s, 0, y, (AVPicture*)s->input_frame,    &pict);

            else

                get_sub_picture(s, 0, y, (AVPicture*)frame,              &pict);

            get_sub_picture(s, 0, y, (AVPicture*)s->last_frame,    &last_pict);

            get_sub_picture(s, 0, y, (AVPicture*)s->scratch_frame, &scratch_pict);



            if((temp_size = rd_strip(s, y, strip_height, isakeyframe, &last_pict, &pict, &scratch_pict, s->frame_buf + size + CVID_HEADER_SIZE, &score_temp

#ifdef CINEPAK_REPORT_SERR

, &serr_temp

#endif

)) < 0)

                return temp_size;



            score += score_temp;

#ifdef CINEPAK_REPORT_SERR

            serr += serr_temp;

#endif

            size += temp_size;

            

            

        }



        if(best_score == 0 || score < best_score) {

            best_score = score;

#ifdef CINEPAK_REPORT_SERR

            best_serr = serr;

#endif

            best_size = size + write_cvid_header(s, s->frame_buf, num_strips, size, isakeyframe);

            

#ifdef CINEPAK_REPORT_SERR

            av_log(s->avctx, AV_LOG_INFO, "best number of strips so far: %2i, %12lli, %i B\n", num_strips, (long long int)serr, best_size);

#endif



            FFSWAP(AVFrame *, s->best_frame, s->scratch_frame);

            memcpy(buf, s->frame_buf, best_size);

            best_nstrips = num_strips;

        }





        if(num_strips - best_nstrips > 4)

            break;

    }









    if(!s->strip_number_delta_range) {

        if(best_nstrips == s->max_strips) { 

            s->max_strips = best_nstrips + 1;

            if(s->max_strips >= s->max_max_strips)

                s->max_strips = s->max_max_strips;

        } else { 

            s->max_strips = best_nstrips;

        }

        s->min_strips = s->max_strips - 1;

        if(s->min_strips < s->min_min_strips)

            s->min_strips = s->min_min_strips;

    } else {

        s->max_strips = best_nstrips + s->strip_number_delta_range;

        if(s->max_strips >= s->max_max_strips)

            s->max_strips = s->max_max_strips;

        s->min_strips = best_nstrips - s->strip_number_delta_range;

        if(s->min_strips < s->min_min_strips)

            s->min_strips = s->min_min_strips;

    }



    return best_size;

}

    int num_strips, strip, i, y, nexty, size, temp_size, best_size;     int best_nstrips;
static int FUNC_0(CinepakEncContext *VAR_0, const AVFrame *VAR_1, int VAR_2, unsigned char *VAR_3, int VAR_4)

{

    int VAR_5, VAR_6, VAR_7, VAR_8, VAR_9, VAR_10, VAR_11, VAR_12;

    AVPicture last_pict, pict, scratch_pict;

    int64_t best_score = 0, score, score_temp;

#ifdef CINEPAK_REPORT_SERR

    int64_t best_serr = 0, serr, serr_temp;

#endif



    int VAR_13;



    if(VAR_0->pix_fmt == AV_PIX_FMT_RGB24) {

        int VAR_14;



        for(VAR_8 = 0; VAR_8 < VAR_0->h; VAR_8 += 2) {

            for(VAR_14 = 0; VAR_14 < VAR_0->w; VAR_14 += 2) {

                uint8_t *ir[2]; int32_t r, g, b, rr, gg, bb;

                ir[0] = ((AVPicture*)VAR_1)->data[0] + VAR_14*3 + VAR_8*((AVPicture*)VAR_1)->linesize[0];

                ir[1] = ir[0] + ((AVPicture*)VAR_1)->linesize[0];

                get_sub_picture(VAR_0, VAR_14, VAR_8, (AVPicture*)VAR_0->input_frame, &scratch_pict);

                r = g = b = 0;

                for(VAR_7=0; VAR_7<4; ++VAR_7) {

                    int i1, i2;

                    i1 = (VAR_7&1); i2 = (VAR_7>=2);

                    rr = ir[i2][i1*3+0];

                    gg = ir[i2][i1*3+1];

                    bb = ir[i2][i1*3+2];

                    r += rr; g += gg; b += bb;







                    rr = (2396625*rr + 4793251*gg + 1198732*bb) >> 23;

                    if(      rr <   0) rr =   0;

                    else if (rr > 255) rr = 255;

                    scratch_pict.data[0][i1 + i2*scratch_pict.linesize[0]] = rr;

                }









                rr = (-299683*r - 599156*g + 898839*b) >> 23;

                if(      rr < -128) rr = -128;

                else if (rr >  127) rr =  127;

                scratch_pict.data[1][0] = rr + 128; 





                rr = (748893*r - 599156*g - 149737*b) >> 23;

                if(      rr < -128) rr = -128;

                else if (rr >  127) rr =  127;

                scratch_pict.data[2][0] = rr + 128; 

            }

        }

    }



    

    

    for(VAR_5 = VAR_0->min_strips; VAR_5 <= VAR_0->max_strips && VAR_5 <= VAR_0->h / MB_SIZE; VAR_5++) {

        score = 0;

        VAR_10 = 0;

#ifdef CINEPAK_REPORT_SERR

        serr = 0;

#endif



        for(VAR_8 = 0, VAR_6 = 1; VAR_8 < VAR_0->h; VAR_6++, VAR_8 = VAR_9) {

            int strip_height;



            VAR_9 = VAR_6 * VAR_0->h / VAR_5; 

            

            if(VAR_9 & 3)

                VAR_9 += 4 - (VAR_9 & 3);



            strip_height = VAR_9 - VAR_8;

            if(strip_height <= 0) { 

                av_log(VAR_0->avctx, AV_LOG_INFO, "skipping zero height VAR_6 %VAR_7 of %VAR_7\n", VAR_6, VAR_5);

                continue;

            }



            if(VAR_0->pix_fmt == AV_PIX_FMT_RGB24)

                get_sub_picture(VAR_0, 0, VAR_8, (AVPicture*)VAR_0->input_frame,    &pict);

            else

                get_sub_picture(VAR_0, 0, VAR_8, (AVPicture*)VAR_1,              &pict);

            get_sub_picture(VAR_0, 0, VAR_8, (AVPicture*)VAR_0->last_frame,    &last_pict);

            get_sub_picture(VAR_0, 0, VAR_8, (AVPicture*)VAR_0->scratch_frame, &scratch_pict);



            if((VAR_11 = rd_strip(VAR_0, VAR_8, strip_height, VAR_2, &last_pict, &pict, &scratch_pict, VAR_0->frame_buf + VAR_10 + CVID_HEADER_SIZE, &score_temp

#ifdef CINEPAK_REPORT_SERR

, &serr_temp

#endif

)) < 0)

                return VAR_11;



            score += score_temp;

#ifdef CINEPAK_REPORT_SERR

            serr += serr_temp;

#endif

            VAR_10 += VAR_11;

            

            

        }



        if(best_score == 0 || score < best_score) {

            best_score = score;

#ifdef CINEPAK_REPORT_SERR

            best_serr = serr;

#endif

            VAR_12 = VAR_10 + write_cvid_header(VAR_0, VAR_0->frame_buf, VAR_5, VAR_10, VAR_2);

            

#ifdef CINEPAK_REPORT_SERR

            av_log(VAR_0->avctx, AV_LOG_INFO, "best number of strips so far: %2i, %12lli, %VAR_7 B\n", VAR_5, (long long int)serr, VAR_12);

#endif



            FFSWAP(AVFrame *, VAR_0->best_frame, VAR_0->scratch_frame);

            memcpy(VAR_3, VAR_0->frame_buf, VAR_12);

            VAR_13 = VAR_5;

        }





        if(VAR_5 - VAR_13 > 4)

            break;

    }









    if(!VAR_0->strip_number_delta_range) {

        if(VAR_13 == VAR_0->max_strips) { 

            VAR_0->max_strips = VAR_13 + 1;

            if(VAR_0->max_strips >= VAR_0->max_max_strips)

                VAR_0->max_strips = VAR_0->max_max_strips;

        } else { 

            VAR_0->max_strips = VAR_13;

        }

        VAR_0->min_strips = VAR_0->max_strips - 1;

        if(VAR_0->min_strips < VAR_0->min_min_strips)

            VAR_0->min_strips = VAR_0->min_min_strips;

    } else {

        VAR_0->max_strips = VAR_13 + VAR_0->strip_number_delta_range;

        if(VAR_0->max_strips >= VAR_0->max_max_strips)

            VAR_0->max_strips = VAR_0->max_max_strips;

        VAR_0->min_strips = VAR_13 - VAR_0->strip_number_delta_range;

        if(VAR_0->min_strips < VAR_0->min_min_strips)

            VAR_0->min_strips = VAR_0->min_min_strips;

    }



    return VAR_12;

}

static int FUNC_0(CinepakEncContext *VAR_0, const AVFrame *VAR_1, int VAR_2, unsigned char *VAR_3, int VAR_4)
{ int VAR_5, VAR_6, VAR_7, VAR_8, VAR_9, VAR_10, VAR_11, VAR_12; AVPicture last_pict, pict, scratch_pict; int64_t best_score = 0, score, score_temp; #ifdef CINEPAK_REPORT_SERR
int64_t best_serr = 0, serr, serr_temp; #endif
int VAR_13; if(VAR_0->pix_fmt == AV_PIX_FMT_RGB24) { int VAR_14; for(VAR_8 = 0; VAR_8 < VAR_0->h; VAR_8 += 2) { for(VAR_14 = 0; VAR_14 < VAR_0->w; VAR_14 += 2) { uint8_t *ir[2]; int32_t r, g, b, rr, gg, bb; ir[0] = ((AVPicture*)VAR_1)->data[0] + VAR_14*3 + VAR_8*((AVPicture*)VAR_1)->linesize[0]; ir[1] = ir[0] + ((AVPicture*)VAR_1)->linesize[0]; get_sub_picture(VAR_0, VAR_14, VAR_8, (AVPicture*)VAR_0->input_frame, &scratch_pict); r = g = b = 0; for(VAR_7=0; VAR_7<4; ++VAR_7) { int i1, i2; i1 = (VAR_7&1); i2 = (VAR_7>=2); rr = ir[i2][i1*3+0]; gg = ir[i2][i1*3+1]; bb = ir[i2][i1*3+2]; r += rr; g += gg; b += bb; rr = (2396625*rr + 4793251*gg + 1198732*bb) >> 23; if(      rr <   0) rr =   0; else if (rr > 255) rr = 255; scratch_pict.data[0][i1 + i2*scratch_pict.linesize[0]] = rr; } rr = (-299683*r - 599156*g + 898839*b) >> 23; if(      rr < -128) rr = -128; else if (rr >  127) rr =  127; scratch_pict.data[1][0] = rr + 128; rr = (748893*r - 599156*g - 149737*b) >> 23; if(      rr < -128) rr = -128; else if (rr >  127) rr =  127; scratch_pict.data[2][0] = rr + 128; } } } for(VAR_5 = VAR_0->min_strips; VAR_5 <= VAR_0->max_strips && VAR_5 <= VAR_0->h / MB_SIZE; VAR_5++) { score = 0; VAR_10 = 0; #ifdef CINEPAK_REPORT_SERR
serr = 0; #endif
for(VAR_8 = 0, VAR_6 = 1; VAR_8 < VAR_0->h; VAR_6++, VAR_8 = VAR_9) { int strip_height; VAR_9 = VAR_6 * VAR_0->h / VAR_5; if(VAR_9 & 3)
VAR_9 += 4 - (VAR_9 & 3); strip_height = VAR_9 - VAR_8; if(strip_height <= 0) { av_log(VAR_0->avctx, AV_LOG_INFO, "skipping zero height VAR_6 %VAR_7 of %VAR_7\n", VAR_6, VAR_5); continue; } if(VAR_0->pix_fmt == AV_PIX_FMT_RGB24)
get_sub_picture(VAR_0, 0, VAR_8, (AVPicture*)VAR_0->input_frame,    &pict); else
get_sub_picture(VAR_0, 0, VAR_8, (AVPicture*)VAR_1,              &pict); get_sub_picture(VAR_0, 0, VAR_8, (AVPicture*)VAR_0->last_frame,    &last_pict); get_sub_picture(VAR_0, 0, VAR_8, (AVPicture*)VAR_0->scratch_frame, &scratch_pict); if((VAR_11 = rd_strip(VAR_0, VAR_8, strip_height, VAR_2, &last_pict, &pict, &scratch_pict, VAR_0->frame_buf + VAR_10 + CVID_HEADER_SIZE, &score_temp
#ifdef CINEPAK_REPORT_SERR
, &serr_temp
#endif
)) < 0)
return VAR_11; score += score_temp; #ifdef CINEPAK_REPORT_SERR
serr += serr_temp; #endif
VAR_10 += VAR_11; } if(best_score == 0 || score < best_score) { best_score = score; #ifdef CINEPAK_REPORT_SERR
best_serr = serr; #endif
VAR_12 = VAR_10 + write_cvid_header(VAR_0, VAR_0->frame_buf, VAR_5, VAR_10, VAR_2); #ifdef CINEPAK_REPORT_SERR
av_log(VAR_0->avctx, AV_LOG_INFO, "best number of strips so far: %2i, %12lli, %VAR_7 B\n", VAR_5, (long long int)serr, VAR_12); #endif
FFSWAP(AVFrame *, VAR_0->best_frame, VAR_0->scratch_frame); memcpy(VAR_3, VAR_0->frame_buf, VAR_12); VAR_13 = VAR_5; } if(VAR_5 - VAR_13 > 4)
break; } if(!VAR_0->strip_number_delta_range) { if(VAR_13 == VAR_0->max_strips) { VAR_0->max_strips = VAR_13 + 1; if(VAR_0->max_strips >= VAR_0->max_max_strips)
VAR_0->max_strips = VAR_0->max_max_strips; } else { VAR_0->max_strips = VAR_13; } VAR_0->min_strips = VAR_0->max_strips - 1; if(VAR_0->min_strips < VAR_0->min_min_strips)
VAR_0->min_strips = VAR_0->min_min_strips; } else { VAR_0->max_strips = VAR_13 + VAR_0->strip_number_delta_range; if(VAR_0->max_strips >= VAR_0->max_max_strips)
VAR_0->max_strips = VAR_0->max_max_strips; VAR_0->min_strips = VAR_13 - VAR_0->strip_number_delta_range; if(VAR_0->min_strips < VAR_0->min_min_strips)
VAR_0->min_strips = VAR_0->min_min_strips; } return VAR_12; }