Esempio n. 1
0
void dsputil_h264_init_ppc(DSPContext* c, AVCodecContext *avctx) {

    if (has_altivec()) {
        c->put_h264_chroma_pixels_tab[0] = put_h264_chroma_mc8_altivec;
        c->put_no_rnd_h264_chroma_pixels_tab[0] = put_no_rnd_h264_chroma_mc8_altivec;
        c->avg_h264_chroma_pixels_tab[0] = avg_h264_chroma_mc8_altivec;
        c->h264_idct_add = ff_h264_idct_add_altivec;
        c->h264_idct8_add = ff_h264_idct8_add_altivec;
        c->h264_v_loop_filter_luma= h264_v_loop_filter_luma_altivec;
        c->h264_h_loop_filter_luma= h264_h_loop_filter_luma_altivec;

#define dspfunc(PFX, IDX, NUM) \
        c->PFX ## _pixels_tab[IDX][ 0] = PFX ## NUM ## _mc00_altivec; \
        c->PFX ## _pixels_tab[IDX][ 1] = PFX ## NUM ## _mc10_altivec; \
        c->PFX ## _pixels_tab[IDX][ 2] = PFX ## NUM ## _mc20_altivec; \
        c->PFX ## _pixels_tab[IDX][ 3] = PFX ## NUM ## _mc30_altivec; \
        c->PFX ## _pixels_tab[IDX][ 4] = PFX ## NUM ## _mc01_altivec; \
        c->PFX ## _pixels_tab[IDX][ 5] = PFX ## NUM ## _mc11_altivec; \
        c->PFX ## _pixels_tab[IDX][ 6] = PFX ## NUM ## _mc21_altivec; \
        c->PFX ## _pixels_tab[IDX][ 7] = PFX ## NUM ## _mc31_altivec; \
        c->PFX ## _pixels_tab[IDX][ 8] = PFX ## NUM ## _mc02_altivec; \
        c->PFX ## _pixels_tab[IDX][ 9] = PFX ## NUM ## _mc12_altivec; \
        c->PFX ## _pixels_tab[IDX][10] = PFX ## NUM ## _mc22_altivec; \
        c->PFX ## _pixels_tab[IDX][11] = PFX ## NUM ## _mc32_altivec; \
        c->PFX ## _pixels_tab[IDX][12] = PFX ## NUM ## _mc03_altivec; \
        c->PFX ## _pixels_tab[IDX][13] = PFX ## NUM ## _mc13_altivec; \
        c->PFX ## _pixels_tab[IDX][14] = PFX ## NUM ## _mc23_altivec; \
        c->PFX ## _pixels_tab[IDX][15] = PFX ## NUM ## _mc33_altivec

        dspfunc(put_h264_qpel, 0, 16);
        dspfunc(avg_h264_qpel, 0, 16);
#undef dspfunc
    }
}
Esempio n. 2
0
av_cold void ff_vp8dsp_init_altivec(VP8DSPContext *c)
{
    if (!has_altivec())
        return;

    c->put_vp8_epel_pixels_tab[0][0][0] = put_vp8_pixels16_altivec;
    c->put_vp8_epel_pixels_tab[0][0][2] = put_vp8_epel16_h6_altivec;
    c->put_vp8_epel_pixels_tab[0][2][0] = put_vp8_epel16_v6_altivec;
    c->put_vp8_epel_pixels_tab[0][2][2] = put_vp8_epel16_h6v6_altivec;

    c->put_vp8_epel_pixels_tab[1][0][2] = put_vp8_epel8_h6_altivec;
    c->put_vp8_epel_pixels_tab[1][2][0] = put_vp8_epel8_v6_altivec;
    c->put_vp8_epel_pixels_tab[1][0][1] = put_vp8_epel8_h4_altivec;
    c->put_vp8_epel_pixels_tab[1][1][0] = put_vp8_epel8_v4_altivec;

    c->put_vp8_epel_pixels_tab[1][2][2] = put_vp8_epel8_h6v6_altivec;
    c->put_vp8_epel_pixels_tab[1][1][1] = put_vp8_epel8_h4v4_altivec;
    c->put_vp8_epel_pixels_tab[1][1][2] = put_vp8_epel8_h6v4_altivec;
    c->put_vp8_epel_pixels_tab[1][2][1] = put_vp8_epel8_h4v6_altivec;

    c->put_vp8_epel_pixels_tab[2][0][2] = put_vp8_epel4_h6_altivec;
    c->put_vp8_epel_pixels_tab[2][2][0] = put_vp8_epel4_v6_altivec;
    c->put_vp8_epel_pixels_tab[2][0][1] = put_vp8_epel4_h4_altivec;
    c->put_vp8_epel_pixels_tab[2][1][0] = put_vp8_epel4_v4_altivec;

    c->put_vp8_epel_pixels_tab[2][2][2] = put_vp8_epel4_h6v6_altivec;
    c->put_vp8_epel_pixels_tab[2][1][1] = put_vp8_epel4_h4v4_altivec;
    c->put_vp8_epel_pixels_tab[2][1][2] = put_vp8_epel4_h6v4_altivec;
    c->put_vp8_epel_pixels_tab[2][2][1] = put_vp8_epel4_h4v6_altivec;
}
int mm_support(void)
{
    int result = 0;
#ifdef HAVE_ALTIVEC
    if (has_altivec()) {
        result |= MM_ALTIVEC;
    }
#endif /* result */
    return result;
}
void MPV_common_init_ppc(MpegEncContext *s)
{
#ifdef HAVE_ALTIVEC
    if (has_altivec())
    {
      if (s->avctx->lowres==0)
      {
        if ((s->avctx->idct_algo == FF_IDCT_AUTO) ||
                (s->avctx->idct_algo == FF_IDCT_ALTIVEC))
        {
            s->dsp.idct_put = idct_put_altivec;
            s->dsp.idct_add = idct_add_altivec;
#ifndef ALTIVEC_USE_REFERENCE_C_CODE
            s->dsp.idct_permutation_type = FF_TRANSPOSE_IDCT_PERM;
#else /* ALTIVEC_USE_REFERENCE_C_CODE */
            s->dsp.idct_permutation_type = FF_NO_IDCT_PERM;
#endif /* ALTIVEC_USE_REFERENCE_C_CODE */
        }
      }

        // Test to make sure that the dct required alignments are met.
        if ((((long)(s->q_intra_matrix) & 0x0f) != 0) ||
                (((long)(s->q_inter_matrix) & 0x0f) != 0))
        {
            av_log(s->avctx, AV_LOG_INFO, "Internal Error: q-matrix blocks must be 16-byte aligned "
                    "to use Altivec DCT. Reverting to non-altivec version.\n");
            return;
        }

        if (((long)(s->intra_scantable.inverse) & 0x0f) != 0)
        {
            av_log(s->avctx, AV_LOG_INFO, "Internal Error: scan table blocks must be 16-byte aligned "
                    "to use Altivec DCT. Reverting to non-altivec version.\n");
            return;
        }


        if ((s->avctx->dct_algo == FF_DCT_AUTO) ||
                (s->avctx->dct_algo == FF_DCT_ALTIVEC))
        {
#if 0 /* seems to cause trouble under some circumstances */
            s->dct_quantize = dct_quantize_altivec;
#endif
            s->dct_unquantize_h263_intra = dct_unquantize_h263_altivec;
            s->dct_unquantize_h263_inter = dct_unquantize_h263_altivec;
        }
    } else
#endif
    {
        /* Non-AltiVec PPC optimisations here */
    }
}
Esempio n. 5
0
void dsputil_h264_init_ppc(DSPContext* c, AVCodecContext *avctx) {

#ifdef HAVE_ALTIVEC
  if (has_altivec()) {
    c->put_h264_chroma_pixels_tab[0] = put_h264_chroma_mc8_altivec;
    c->put_no_rnd_h264_chroma_pixels_tab[0] = put_no_rnd_h264_chroma_mc8_altivec;
    c->avg_h264_chroma_pixels_tab[0] = avg_h264_chroma_mc8_altivec;
    c->h264_idct8_add = ff_h264_idct8_add_altivec;

#define dspfunc(PFX, IDX, NUM) \
    c->PFX ## _pixels_tab[IDX][ 0] = PFX ## NUM ## _mc00_altivec; \
    c->PFX ## _pixels_tab[IDX][ 1] = PFX ## NUM ## _mc10_altivec; \
    c->PFX ## _pixels_tab[IDX][ 2] = PFX ## NUM ## _mc20_altivec; \
    c->PFX ## _pixels_tab[IDX][ 3] = PFX ## NUM ## _mc30_altivec; \
    c->PFX ## _pixels_tab[IDX][ 4] = PFX ## NUM ## _mc01_altivec; \
    c->PFX ## _pixels_tab[IDX][ 5] = PFX ## NUM ## _mc11_altivec; \
    c->PFX ## _pixels_tab[IDX][ 6] = PFX ## NUM ## _mc21_altivec; \
    c->PFX ## _pixels_tab[IDX][ 7] = PFX ## NUM ## _mc31_altivec; \
    c->PFX ## _pixels_tab[IDX][ 8] = PFX ## NUM ## _mc02_altivec; \
    c->PFX ## _pixels_tab[IDX][ 9] = PFX ## NUM ## _mc12_altivec; \
    c->PFX ## _pixels_tab[IDX][10] = PFX ## NUM ## _mc22_altivec; \
    c->PFX ## _pixels_tab[IDX][11] = PFX ## NUM ## _mc32_altivec; \
    c->PFX ## _pixels_tab[IDX][12] = PFX ## NUM ## _mc03_altivec; \
    c->PFX ## _pixels_tab[IDX][13] = PFX ## NUM ## _mc13_altivec; \
    c->PFX ## _pixels_tab[IDX][14] = PFX ## NUM ## _mc23_altivec; \
    c->PFX ## _pixels_tab[IDX][15] = PFX ## NUM ## _mc33_altivec

    dspfunc(put_h264_qpel, 0, 16);
    dspfunc(avg_h264_qpel, 0, 16);
#undef dspfunc

  } else
#endif /* HAVE_ALTIVEC */
  {
    // Non-AltiVec PPC optimisations

    // ... pending ...
  }
}
void dsputil_init_ppc(DSPContext* c, AVCodecContext *avctx)
{
    // Common optimizations whether Altivec is available or not

  switch (check_dcbzl_effect()) {
  case 32:
    c->clear_blocks = clear_blocks_dcbz32_ppc;
    break;
  case 128:
    c->clear_blocks = clear_blocks_dcbz128_ppc;
    break;
  default:
    break;
  }

#ifdef HAVE_ALTIVEC
  dsputil_h264_init_ppc(c, avctx);

    if (has_altivec()) {
        mm_flags |= MM_ALTIVEC;

        // Altivec specific optimisations
        c->pix_abs[0][1] = sad16_x2_altivec;
        c->pix_abs[0][2] = sad16_y2_altivec;
        c->pix_abs[0][3] = sad16_xy2_altivec;
        c->pix_abs[0][0] = sad16_altivec;
        c->pix_abs[1][0] = sad8_altivec;
        c->sad[0]= sad16_altivec;
        c->sad[1]= sad8_altivec;
        c->pix_norm1 = pix_norm1_altivec;
        c->sse[1]= sse8_altivec;
        c->sse[0]= sse16_altivec;
        c->pix_sum = pix_sum_altivec;
        c->diff_pixels = diff_pixels_altivec;
        c->get_pixels = get_pixels_altivec;
// next one disabled as it's untested.
#if 0
        c->add_bytes= add_bytes_altivec;
#endif /* 0 */
        c->put_pixels_tab[0][0] = put_pixels16_altivec;
        /* the two functions do the same thing, so use the same code */
        c->put_no_rnd_pixels_tab[0][0] = put_pixels16_altivec;
        c->avg_pixels_tab[0][0] = avg_pixels16_altivec;
        c->avg_pixels_tab[1][0] = avg_pixels8_altivec;
        c->avg_pixels_tab[1][3] = avg_pixels8_xy2_altivec;
        c->put_pixels_tab[1][3] = put_pixels8_xy2_altivec;
        c->put_no_rnd_pixels_tab[1][3] = put_no_rnd_pixels8_xy2_altivec;
        c->put_pixels_tab[0][3] = put_pixels16_xy2_altivec;
        c->put_no_rnd_pixels_tab[0][3] = put_no_rnd_pixels16_xy2_altivec;

        c->gmc1 = gmc1_altivec;

        c->hadamard8_diff[0] = hadamard8_diff16_altivec;
        c->hadamard8_diff[1] = hadamard8_diff8x8_altivec;


        c->horizontal_compose97i = ff_snow_horizontal_compose97i_altivec;
        c->vertical_compose97i = ff_snow_vertical_compose97i_altivec;
        c->inner_add_yblock = ff_snow_inner_add_yblock_altivec;

#ifdef CONFIG_ENCODERS
        if (avctx->dct_algo == FF_DCT_AUTO ||
            avctx->dct_algo == FF_DCT_ALTIVEC)
        {
            c->fdct = fdct_altivec;
        }
#endif //CONFIG_ENCODERS

      if (avctx->lowres==0)
      {
        if ((avctx->idct_algo == FF_IDCT_AUTO) ||
                (avctx->idct_algo == FF_IDCT_ALTIVEC))
        {
            c->idct_put = idct_put_altivec;
            c->idct_add = idct_add_altivec;
#ifndef ALTIVEC_USE_REFERENCE_C_CODE
            c->idct_permutation_type = FF_TRANSPOSE_IDCT_PERM;
#else /* ALTIVEC_USE_REFERENCE_C_CODE */
            c->idct_permutation_type = FF_NO_IDCT_PERM;
#endif /* ALTIVEC_USE_REFERENCE_C_CODE */
        }
      }

#ifdef POWERPC_PERFORMANCE_REPORT
        {
          int i, j;
          for (i = 0 ; i < powerpc_perf_total ; i++)
          {
            for (j = 0; j < POWERPC_NUM_PMC_ENABLED ; j++)
              {
                perfdata[j][i][powerpc_data_min] = 0xFFFFFFFFFFFFFFFFULL;
                perfdata[j][i][powerpc_data_max] = 0x0000000000000000ULL;
                perfdata[j][i][powerpc_data_sum] = 0x0000000000000000ULL;
                perfdata[j][i][powerpc_data_num] = 0x0000000000000000ULL;
              }
          }
        }
#endif /* POWERPC_PERFORMANCE_REPORT */
    } else
#endif /* HAVE_ALTIVEC */
    {
        // Non-AltiVec PPC optimisations

        // ... pending ...
    }
}
Esempio n. 7
0
/**
 * Create the private context for the encoder.
 * All buffers are allocated, settings are loaded from the user,
 * and the encoder context created.
 *
 * @param avctx AVCodecContext pointer to context
 * @return Returns 0 on success, -1 on failure
 */
static av_cold int xvid_encode_init(AVCodecContext *avctx)  {
    int xerr, i;
    int xvid_flags = avctx->flags;
    struct xvid_context *x = avctx->priv_data;
    uint16_t *intra, *inter;
    int fd;

    xvid_plugin_single_t single;
    struct xvid_ff_pass1 rc2pass1;
    xvid_plugin_2pass2_t rc2pass2;
    xvid_gbl_init_t xvid_gbl_init;
    xvid_enc_create_t xvid_enc_create;
    xvid_enc_plugin_t plugins[7];

    /* Bring in VOP flags from ffmpeg command-line */
    x->vop_flags = XVID_VOP_HALFPEL; /* Bare minimum quality */
    if( xvid_flags & CODEC_FLAG_4MV )
        x->vop_flags |= XVID_VOP_INTER4V; /* Level 3 */
    if( avctx->trellis
        )
        x->vop_flags |= XVID_VOP_TRELLISQUANT; /* Level 5 */
    if( xvid_flags & CODEC_FLAG_AC_PRED )
        x->vop_flags |= XVID_VOP_HQACPRED; /* Level 6 */
    if( xvid_flags & CODEC_FLAG_GRAY )
        x->vop_flags |= XVID_VOP_GREYSCALE;

    /* Decide which ME quality setting to use */
    x->me_flags = 0;
    switch( avctx->me_method ) {
       case ME_FULL:   /* Quality 6 */
           x->me_flags |=  XVID_ME_EXTSEARCH16
                       |   XVID_ME_EXTSEARCH8;

       case ME_EPZS:   /* Quality 4 */
           x->me_flags |=  XVID_ME_ADVANCEDDIAMOND8
                       |   XVID_ME_HALFPELREFINE8
                       |   XVID_ME_CHROMA_PVOP
                       |   XVID_ME_CHROMA_BVOP;

       case ME_LOG:    /* Quality 2 */
       case ME_PHODS:
       case ME_X1:
           x->me_flags |=  XVID_ME_ADVANCEDDIAMOND16
                       |   XVID_ME_HALFPELREFINE16;

       case ME_ZERO:   /* Quality 0 */
       default:
           break;
    }

    /* Decide how we should decide blocks */
    switch( avctx->mb_decision ) {
       case 2:
           x->vop_flags |= XVID_VOP_MODEDECISION_RD;
           x->me_flags |=  XVID_ME_HALFPELREFINE8_RD
                       |   XVID_ME_QUARTERPELREFINE8_RD
                       |   XVID_ME_EXTSEARCH_RD
                       |   XVID_ME_CHECKPREDICTION_RD;
       case 1:
           if( !(x->vop_flags & XVID_VOP_MODEDECISION_RD) )
               x->vop_flags |= XVID_VOP_FAST_MODEDECISION_RD;
           x->me_flags |=  XVID_ME_HALFPELREFINE16_RD
                       |   XVID_ME_QUARTERPELREFINE16_RD;

       default:
           break;
    }

    /* Bring in VOL flags from ffmpeg command-line */
    x->vol_flags = 0;
    if( xvid_flags & CODEC_FLAG_GMC ) {
        x->vol_flags |= XVID_VOL_GMC;
        x->me_flags |= XVID_ME_GME_REFINE;
    }
    if( xvid_flags & CODEC_FLAG_QPEL ) {
        x->vol_flags |= XVID_VOL_QUARTERPEL;
        x->me_flags |= XVID_ME_QUARTERPELREFINE16;
        if( x->vop_flags & XVID_VOP_INTER4V )
            x->me_flags |= XVID_ME_QUARTERPELREFINE8;
    }

    memset(&xvid_gbl_init, 0, sizeof(xvid_gbl_init));
    xvid_gbl_init.version = XVID_VERSION;
    xvid_gbl_init.debug = 0;

#if ARCH_PPC
    /* Xvid's PPC support is borked, use libavcodec to detect */
#if HAVE_ALTIVEC
    if( has_altivec() ) {
        xvid_gbl_init.cpu_flags = XVID_CPU_FORCE | XVID_CPU_ALTIVEC;
    } else
#endif
        xvid_gbl_init.cpu_flags = XVID_CPU_FORCE;
#else
    /* Xvid can detect on x86 */
    xvid_gbl_init.cpu_flags = 0;
#endif

    /* Initialize */
    xvid_global(NULL, XVID_GBL_INIT, &xvid_gbl_init, NULL);

    /* Create the encoder reference */
    memset(&xvid_enc_create, 0, sizeof(xvid_enc_create));
    xvid_enc_create.version = XVID_VERSION;

    /* Store the desired frame size */
    xvid_enc_create.width = x->xsize = avctx->width;
    xvid_enc_create.height = x->ysize = avctx->height;

    /* Xvid can determine the proper profile to use */
    /* xvid_enc_create.profile = XVID_PROFILE_S_L3; */

    /* We don't use zones */
    xvid_enc_create.zones = NULL;
    xvid_enc_create.num_zones = 0;

    xvid_enc_create.num_threads = avctx->thread_count;

    xvid_enc_create.plugins = plugins;
    xvid_enc_create.num_plugins = 0;

    /* Initialize Buffers */
    x->twopassbuffer = NULL;
    x->old_twopassbuffer = NULL;
    x->twopassfile = NULL;

    if( xvid_flags & CODEC_FLAG_PASS1 ) {
        memset(&rc2pass1, 0, sizeof(struct xvid_ff_pass1));
        rc2pass1.version = XVID_VERSION;
        rc2pass1.context = x;
        x->twopassbuffer = av_malloc(BUFFER_SIZE);
        x->old_twopassbuffer = av_malloc(BUFFER_SIZE);
        if( x->twopassbuffer == NULL || x->old_twopassbuffer == NULL ) {
            av_log(avctx, AV_LOG_ERROR,
                "Xvid: Cannot allocate 2-pass log buffers\n");
            return -1;
        }
        x->twopassbuffer[0] = x->old_twopassbuffer[0] = 0;

        plugins[xvid_enc_create.num_plugins].func = xvid_ff_2pass;
        plugins[xvid_enc_create.num_plugins].param = &rc2pass1;
        xvid_enc_create.num_plugins++;
    } else if( xvid_flags & CODEC_FLAG_PASS2 ) {
        memset(&rc2pass2, 0, sizeof(xvid_plugin_2pass2_t));
        rc2pass2.version = XVID_VERSION;
        rc2pass2.bitrate = avctx->bit_rate;

        fd = ff_tempfile("xvidff.", &(x->twopassfile));
        if( fd == -1 ) {
            av_log(avctx, AV_LOG_ERROR,
                "Xvid: Cannot write 2-pass pipe\n");
            return -1;
        }

        if( avctx->stats_in == NULL ) {
            av_log(avctx, AV_LOG_ERROR,
                "Xvid: No 2-pass information loaded for second pass\n");
            return -1;
        }

        if( strlen(avctx->stats_in) >
              write(fd, avctx->stats_in, strlen(avctx->stats_in)) ) {
            close(fd);
            av_log(avctx, AV_LOG_ERROR,
                "Xvid: Cannot write to 2-pass pipe\n");
            return -1;
        }

        close(fd);
        rc2pass2.filename = x->twopassfile;
        plugins[xvid_enc_create.num_plugins].func = xvid_plugin_2pass2;
        plugins[xvid_enc_create.num_plugins].param = &rc2pass2;
        xvid_enc_create.num_plugins++;
    } else if( !(xvid_flags & CODEC_FLAG_QSCALE) ) {
        /* Single Pass Bitrate Control! */
        memset(&single, 0, sizeof(xvid_plugin_single_t));
        single.version = XVID_VERSION;
        single.bitrate = avctx->bit_rate;

        plugins[xvid_enc_create.num_plugins].func = xvid_plugin_single;
        plugins[xvid_enc_create.num_plugins].param = &single;
        xvid_enc_create.num_plugins++;
    }

    /* Luminance Masking */
    if( 0.0 != avctx->lumi_masking ) {
        plugins[xvid_enc_create.num_plugins].func = xvid_plugin_lumimasking;
        plugins[xvid_enc_create.num_plugins].param = NULL;
        xvid_enc_create.num_plugins++;
    }

    /* Frame Rate and Key Frames */
    xvid_correct_framerate(avctx);
    xvid_enc_create.fincr = avctx->time_base.num;
    xvid_enc_create.fbase = avctx->time_base.den;
    if( avctx->gop_size > 0 )
        xvid_enc_create.max_key_interval = avctx->gop_size;
    else
        xvid_enc_create.max_key_interval = 240; /* Xvid's best default */

    /* Quants */
    if( xvid_flags & CODEC_FLAG_QSCALE ) x->qscale = 1;
    else x->qscale = 0;

    xvid_enc_create.min_quant[0] = avctx->qmin;
    xvid_enc_create.min_quant[1] = avctx->qmin;
    xvid_enc_create.min_quant[2] = avctx->qmin;
    xvid_enc_create.max_quant[0] = avctx->qmax;
    xvid_enc_create.max_quant[1] = avctx->qmax;
    xvid_enc_create.max_quant[2] = avctx->qmax;

    /* Quant Matrices */
    x->intra_matrix = x->inter_matrix = NULL;
    if( avctx->mpeg_quant )
       x->vol_flags |= XVID_VOL_MPEGQUANT;
    if( (avctx->intra_matrix || avctx->inter_matrix) ) {
       x->vol_flags |= XVID_VOL_MPEGQUANT;

       if( avctx->intra_matrix ) {
           intra = avctx->intra_matrix;
           x->intra_matrix = av_malloc(sizeof(unsigned char) * 64);
       } else
           intra = NULL;
       if( avctx->inter_matrix ) {
           inter = avctx->inter_matrix;
           x->inter_matrix = av_malloc(sizeof(unsigned char) * 64);
       } else
           inter = NULL;

       for( i = 0; i < 64; i++ ) {
           if( intra )
               x->intra_matrix[i] = (unsigned char)intra[i];
           if( inter )
               x->inter_matrix[i] = (unsigned char)inter[i];
       }
    }

    /* Misc Settings */
    xvid_enc_create.frame_drop_ratio = 0;
    xvid_enc_create.global = 0;
    if( xvid_flags & CODEC_FLAG_CLOSED_GOP )
        xvid_enc_create.global |= XVID_GLOBAL_CLOSED_GOP;

    /* Determines which codec mode we are operating in */
    avctx->extradata = NULL;
    avctx->extradata_size = 0;
    if( xvid_flags & CODEC_FLAG_GLOBAL_HEADER ) {
        /* In this case, we are claiming to be MPEG4 */
        x->quicktime_format = 1;
        avctx->codec_id = CODEC_ID_MPEG4;
    } else {
        /* We are claiming to be Xvid */
        x->quicktime_format = 0;
        if(!avctx->codec_tag)
            avctx->codec_tag = AV_RL32("xvid");
    }

    /* Bframes */
    xvid_enc_create.max_bframes = avctx->max_b_frames;
    xvid_enc_create.bquant_offset = 100 * avctx->b_quant_offset;
    xvid_enc_create.bquant_ratio = 100 * avctx->b_quant_factor;
    if( avctx->max_b_frames > 0  && !x->quicktime_format ) xvid_enc_create.global |= XVID_GLOBAL_PACKED;

    /* Create encoder context */
    xerr = xvid_encore(NULL, XVID_ENC_CREATE, &xvid_enc_create, NULL);
    if( xerr ) {
        av_log(avctx, AV_LOG_ERROR, "Xvid: Could not create encoder reference\n");
        return -1;
    }

    x->encoder_handle = xvid_enc_create.handle;
    avctx->coded_frame = &x->encoded_picture;

    return 0;
}