static int dv_encode_video_segment(AVCodecContext *avctx, DVwork_chunk *work_chunk)
{
    DVVideoContext *s = avctx->priv_data;
    int mb_index, i, j;
    int mb_x, mb_y, c_offset, linesize, y_stride;
    uint8_t*  y_ptr;
    uint8_t*  dif;
    uint8_t   scratch[64];
    EncBlockInfo  enc_blks[5*DV_MAX_BPM];
    PutBitContext pbs[5*DV_MAX_BPM];
    PutBitContext* pb;
    EncBlockInfo* enc_blk;
    int       vs_bit_size = 0;
    int       qnos[5] = {15, 15, 15, 15, 15}; /* No quantization */
    int*      qnosp = &qnos[0];

    dif = &s->buf[work_chunk->buf_offset*80];
    enc_blk = &enc_blks[0];
    for (mb_index = 0; mb_index < 5; mb_index++) {
        dv_calculate_mb_xy(s, work_chunk, mb_index, &mb_x, &mb_y);

        /* initializing luminance blocks */
        if ((s->sys->pix_fmt == PIX_FMT_YUV420P) ||
            (s->sys->pix_fmt == PIX_FMT_YUV411P && mb_x >= (704 / 8)) ||
            (s->sys->height >= 720 && mb_y != 134)) {
            y_stride = s->picture.linesize[0] << 3;
        } else {
            y_stride = 16;
        }
        y_ptr    = s->picture.data[0] + ((mb_y * s->picture.linesize[0] + mb_x) << 3);
        linesize = s->picture.linesize[0];

        if (s->sys->video_stype == 4) { /* SD 422 */
            vs_bit_size +=
            dv_init_enc_block(enc_blk+0, y_ptr               , linesize, s, 0) +
            dv_init_enc_block(enc_blk+1, NULL                , linesize, s, 0) +
            dv_init_enc_block(enc_blk+2, y_ptr + 8           , linesize, s, 0) +
            dv_init_enc_block(enc_blk+3, NULL                , linesize, s, 0);
        } else {
            vs_bit_size +=
            dv_init_enc_block(enc_blk+0, y_ptr               , linesize, s, 0) +
            dv_init_enc_block(enc_blk+1, y_ptr + 8           , linesize, s, 0) +
            dv_init_enc_block(enc_blk+2, y_ptr     + y_stride, linesize, s, 0) +
            dv_init_enc_block(enc_blk+3, y_ptr + 8 + y_stride, linesize, s, 0);
        }
        enc_blk += 4;

        /* initializing chrominance blocks */
        c_offset = (((mb_y >>  (s->sys->pix_fmt == PIX_FMT_YUV420P)) * s->picture.linesize[1] +
                     (mb_x >> ((s->sys->pix_fmt == PIX_FMT_YUV411P) ? 2 : 1))) << 3);
        for (j = 2; j; j--) {
            uint8_t *c_ptr = s->picture.data[j] + c_offset;
            linesize = s->picture.linesize[j];
            y_stride = (mb_y == 134) ? 8 : (s->picture.linesize[j] << 3);
                    if (s->sys->pix_fmt == PIX_FMT_YUV411P && mb_x >= (704 / 8)) {
                        uint8_t* d;
                        uint8_t* b = scratch;
                        for (i = 0; i < 8; i++) {
                            d = c_ptr + (linesize << 3);
                            b[0] = c_ptr[0]; b[1] = c_ptr[1]; b[2] = c_ptr[2]; b[3] = c_ptr[3];
                            b[4] =    d[0]; b[5] =    d[1]; b[6] =    d[2]; b[7] =    d[3];
                            c_ptr += linesize;
                            b += 8;
                        }
                        c_ptr = scratch;
                        linesize = 8;
                    }

            vs_bit_size += dv_init_enc_block(    enc_blk++, c_ptr           , linesize, s, 1);
            if (s->sys->bpm == 8) {
                vs_bit_size += dv_init_enc_block(enc_blk++, c_ptr + y_stride, linesize, s, 1);
            }
        }
    }

    if (vs_total_ac_bits < vs_bit_size)
        dv_guess_qnos(&enc_blks[0], qnosp);

    /* DIF encoding process */
    for (j=0; j<5*s->sys->bpm;) {
        int start_mb = j;

        dif[3] = *qnosp++;
        dif += 4;

        /* First pass over individual cells only */
        for (i=0; i<s->sys->bpm; i++, j++) {
            int sz = s->sys->block_sizes[i]>>3;

            init_put_bits(&pbs[j], dif, sz);
            put_bits(&pbs[j], 9, (uint16_t)(((enc_blks[j].mb[0] >> 3) - 1024 + 2) >> 2));
            put_bits(&pbs[j], 1, enc_blks[j].dct_mode);
            put_bits(&pbs[j], 2, enc_blks[j].cno);

            dv_encode_ac(&enc_blks[j], &pbs[j], &pbs[j+1]);
            dif += sz;
        }

        /* Second pass over each MB space */
        pb = &pbs[start_mb];
        for (i=0; i<s->sys->bpm; i++) {
            if (enc_blks[start_mb+i].partial_bit_count)
                pb = dv_encode_ac(&enc_blks[start_mb+i], pb, &pbs[start_mb+s->sys->bpm]);
        }
    }

    /* Third and final pass over the whole video segment space */
    pb = &pbs[0];
    for (j=0; j<5*s->sys->bpm; j++) {
       if (enc_blks[j].partial_bit_count)
           pb = dv_encode_ac(&enc_blks[j], pb, &pbs[s->sys->bpm*5]);
       if (enc_blks[j].partial_bit_count)
            av_log(NULL, AV_LOG_ERROR, "ac bitstream overflow\n");
    }

    for (j=0; j<5*s->sys->bpm; j++)
       flush_put_bits(&pbs[j]);

    return 0;
}