⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mfc_instance.c

📁 SAMSUNG S3C6410 CPU BSP for winmobile6
💻 C
📖 第 1 页 / 共 4 页
字号:

    if (post_rotmode & 0x0010) {
        ctx->PostRotMode = post_rotmode;
    }
    else
        ctx->PostRotMode = 0;


    return old_post_rotmode;
}


MFCInstCtx *MFCInst_Create(void)
{
    MFCInstCtx *ctx;
    int        inst_no;

    // Occupy the 'inst_no'.
    // If it fails, it returns NULL.
    inst_no = MfcInstPool_Occupy();
    if (inst_no == -1)
        return NULL;


    ctx = &(_mfcinst_ctx[inst_no]);

    Mem_Set(ctx, 0, sizeof(MFCInstCtx));

    ctx->inst_no     = inst_no;
    ctx->inbuf_type  = DEC_INBUF_NOT_SPECIFIED;
    MFCINST_STATE_TRANSITION(ctx, MFCINST_STATE_CREATED);

    // At first, since it is not known whether it is LINE_BUF or RING_BUF,
    // it assumes to be LINE_BUF.
    // Later, if it turns out to be RING_BUF, correction will be made.
    Get_MfcStrmBufAddr(ctx, 1);

    LOG_MSG(LOG_TRACE, "s3c_mfc_open", "state : %d\n", ctx->state_var);


    return ctx;
}


//
// Function Name: MFCInst_Delete
// Description
//      It deletes the 6410 MFC instance.
// Parameters
//      ctx[IN]: MFCInstCtx
//
void MFCInst_Delete(MFCInstCtx *ctx)
{
    ////////////////////////////
    ///    STATE checking    ///
    ////////////////////////////
    if (MFCINST_STATE_CHECK(ctx, MFCINST_STATE_DELETED)) {
        LOG_MSG(LOG_ERROR, "MFCInst_Delete", "MFC instance is already deleted.\r\n");
        return;
    }

    MfcInstPool_Release(ctx->inst_no);
    FramBufMgrFree(ctx->inst_no);
    FramBufMgrFree(ctx->inst_no + MFC_NUM_INSTANCES_MAX);

    MFCINST_STATE_TRANSITION(ctx, MFCINST_STATE_DELETED);
}


//
// Function Name: MFCInst_PowerOffState
// Description
//      It turns on the flag indicating 6410 MFC's power-off.
// Parameters
//      ctx[IN]: MFCInstCtx
//
void MFCInst_PowerOffState(MFCInstCtx *ctx)
{
    MFCINST_STATE_PWR_OFF_FLAG_SET(ctx);
}

//
// Function Name: MFCInst_PowerOnState
// Description
//      It turns on the flag indicating 6410 MFC's power-off.
// Parameters
//      ctx[IN]: MFCInstCtx
//
void MFCInst_PowerOnState(MFCInstCtx *ctx)
{
    MFCINST_STATE_PWR_OFF_FLAG_CLEAR(ctx);
}


//
// Function Name: MFCInst_Init
// Description
//      It initializes the 6410 MFC instance with the appropriate config stream.
//      The config stream must be copied into STRM_BUF before this function.
// Parameters
//      ctx[IN]: MFCInstCtx
//      codec_mode[IN]: codec mode specifying H.264/MPEG4/H.263.
//      strm_leng[IN]: stream size (especially it should be the config stream.)
//
int MFCInst_Init(MFCInstCtx *ctx, MFC_CODECMODE codec_mode, unsigned long strm_leng)
{
    unsigned int    i;

    S3C6410_MFC_SFR    *mfc_sfr;        // MFC SFR pointer

    unsigned char    *pPARAM_BUF;    // PARAM_BUF in BITPROC_BUF
    int              nFramBufSize;    // Required size in FRAM_BUF
    int              frame_size;    // width * height

    static S3C6410_MFC_PARAM_REG_DEC_SEQ_INIT    *pPARAM_SEQ_INIT;        // Parameter of SEQ_INIT command
    static S3C6410_MFC_PARAM_REG_SET_FRAME_BUF   *pPARAM_SET_FRAME_BUF;    // Parameter of SET_FRAME_BUF command

    int                last_unit = 0;
    int                garbage_size = 0;


    ////////////////////////////
    ///    STATE checking    ///
    ////////////////////////////
    if (!MFCINST_STATE_CHECK(ctx, MFCINST_STATE_CREATED)) {
        LOG_MSG(LOG_ERROR, "MFCInst_Init", "Init function was called at an incorrect point.\r\n");
        return MFCINST_ERR_STATE_CHK;
    }


    // codec_mode
    ctx->codec_mode = codec_mode;

    // inbuf_type checking
    if (ctx->inbuf_type == DEC_INBUF_NOT_SPECIFIED) {
        LOG_MSG(LOG_ERROR, "MFCInst_Init", "Input buffer type is not specified.\r\n");
        return MFCINST_ERR_ETC;
    }


    //////////////////////////////////////////////
    //                                          //
    // 2. Copy the Config Stream into STRM_BUF. //
    //                                          //
    //////////////////////////////////////////////
    // config stream needs to be in the STRM_BUF a priori.
    // RD_PTR & WR_PTR is set to point the start and end address of STRM_BUF.
    // If WR_PTR is set to [start + config_leng] instead of [end address of STR_BUF],
    // then MFC is not initialized when MPEG4 decoding.

    LOG_MSG(LOG_TRACE, "MFCInst_Init", "strm_leng : %d\n",  strm_leng);

    mfc_sfr = (S3C6410_MFC_SFR *) GetMfcSfrVirAddr();
    mfc_sfr->BIT_STR_BUF_RW_ADDR[ctx->inst_no].BITS_RD_PTR = ctx->phyadrStrmBuf;
    if (ctx->inbuf_type == DEC_INBUF_LINE_BUF)    // In 'fileplay' mode, set the WR_PTR to the end of STRM_BUF
        strm_leng = MFC_LINE_BUF_SIZE_PER_INSTANCE;
    else if (ctx->inbuf_type == DEC_INBUF_RING_BUF) {
        if (strm_leng < (MFC_RING_BUF_PARTUNIT_SIZE << 1)) {
            if (strm_leng & 0x1FF) {
                garbage_size = strm_leng;
                strm_leng = (strm_leng + 512) & 0xFFFFFE00;
                garbage_size = strm_leng - garbage_size;
                Mem_Set((char *)(ctx->pStrmBuf + strm_leng - garbage_size), 0, garbage_size);
            }
            last_unit = 1;
        }

        // In the SEQ_INIT phase, the stream length should be more than 5
        // since it must contain the CONFIG stream at the least.
        if (strm_leng < 5) {
            LOG_MSG(LOG_ERROR, "MFCInst_Init", "Size of buffer fill is too small.\r\n");
            return MFCINST_ERR_DEC_BUF_FILL_SIZE_WRONG;
        }

        MFCINST_STATE_BUF_FILL_REQ_CLEAR(ctx);
    }
    mfc_sfr->BIT_STR_BUF_RW_ADDR[ctx->inst_no].BITS_WR_PTR = ctx->phyadrStrmBuf  +  strm_leng;//MFC_LINE_BUF_SIZE_PER_INSTANCE;

    LOG_MSG(LOG_TRACE, "MFCInst_Init", "  ctx->phyadrStrmBuf   = 0x%X\n", ctx->phyadrStrmBuf);
    LOG_MSG(LOG_TRACE, "MFCInst_Init", "  ctx->phyadrStrmBuf + = 0x%X\n", ctx->phyadrStrmBuf + strm_leng);


    ///////////////////////////////////////////////////////////////////
    //                                                               //
    // 3. Issue the SEQ_INIT command                                 //
    //     (width/height of frame will be obtained)                  //
    //                                                               //
    ///////////////////////////////////////////////////////////////////
    // Set the Parameters for SEQ_INIT command.
    pPARAM_SEQ_INIT = (S3C6410_MFC_PARAM_REG_DEC_SEQ_INIT *)  MfcGetCmdParamRegion();
    pPARAM_SEQ_INIT->DEC_SEQ_BIT_BUF_ADDR   = ctx->phyadrStrmBuf;
    if (ctx->inbuf_type == DEC_INBUF_LINE_BUF) {    // Other than VC-1 decode
        pPARAM_SEQ_INIT->DEC_SEQ_BIT_BUF_SIZE   = MFC_LINE_BUF_SIZE_PER_INSTANCE / 1024;
//        pPARAM_SEQ_INIT->DEC_SEQ_OPTION         = FILEPLAY_ENABLE | DYNBUFALLOC_ENABLE | REORDER_ENABLE;
        pPARAM_SEQ_INIT->DEC_SEQ_OPTION         = FILEPLAY_ENABLE | DYNBUFALLOC_ENABLE;
        pPARAM_SEQ_INIT->DEC_SEQ_START_BYTE     = 0;
    }
    else if (ctx->inbuf_type == DEC_INBUF_RING_BUF) {        // VC-1 decode case
        pPARAM_SEQ_INIT->DEC_SEQ_BIT_BUF_SIZE   = MFC_RING_BUF_SIZE / 1024;
        pPARAM_SEQ_INIT->DEC_SEQ_OPTION         = MP4_DBK_ENABLE;//(0<<6);//REORDER_ENABLE;
        pPARAM_SEQ_INIT->DEC_SEQ_START_BYTE     = 0;
    }
    else {
        LOG_MSG(LOG_ERROR, "MFCInst_Init", "Input buffer type is not specified.\r\n");
        return MFCINST_ERR_ETC;
    }

    LOG_MSG(LOG_TRACE, "MFCInst_Init", "  ctx->inst_no     = %d\n", ctx->inst_no);
    LOG_MSG(LOG_TRACE, "MFCInst_Init", "  ctx->codec_mode  = %d\n", ctx->codec_mode);
    LOG_MSG(LOG_TRACE, "MFCInst_Init", "  SEQ_BIT_BUF_SIZE = %d (KB)\n", pPARAM_SEQ_INIT->DEC_SEQ_BIT_BUF_SIZE);


    // SEQ_INIT command
    MfcIssueCmd(ctx->inst_no, ctx->codec_mode, SEQ_INIT);

    if (pPARAM_SEQ_INIT->RET_SEQ_SUCCESS == TRUE) {

        LOG_MSG(LOG_TRACE, "MFCInst_Init", "\tRET_DEC_SEQ_SRC_SIZE         = %d\n", pPARAM_SEQ_INIT->RET_DEC_SEQ_SRC_SIZE);
        LOG_MSG(LOG_TRACE, "MFCInst_Init", "\tRET_DEC_SEQ_SRC_FRAME_RATE   = %d\n", pPARAM_SEQ_INIT->RET_DEC_SEQ_SRC_FRAME_RATE);
        LOG_MSG(LOG_TRACE, "MFCInst_Init", "\tRET_DEC_SEQ_FRAME_NEED_COUNT = %d\n", pPARAM_SEQ_INIT->RET_DEC_SEQ_FRAME_NEED_COUNT);
        LOG_MSG(LOG_TRACE, "MFCInst_Init", "\tRET_DEC_SEQ_FRAME_DELAY      = %d\n", pPARAM_SEQ_INIT->RET_DEC_SEQ_FRAME_DELAY);
    }
    else {
        LOG_MSG(LOG_ERROR, "MFCInst_Init", "SEQ_INIT failed. [%d]\n", pPARAM_SEQ_INIT->RET_SEQ_SUCCESS);
        return MFCINST_ERR_DEC_INIT_CMD_FAIL;
    }

    // width & height are obtained from return value of SEQ_INIT command
    // stride value is multiple of 16.
    ctx->height = (pPARAM_SEQ_INIT->RET_DEC_SEQ_SRC_SIZE      ) & 0x03FF;
    ctx->width  = (pPARAM_SEQ_INIT->RET_DEC_SEQ_SRC_SIZE >> 10) & 0x03FF;
    if ((ctx->width & 0x0F) == 0)    // 16 aligned (ctx->width%16 == 0)
        ctx->buf_width  = ctx->width;
    else
        ctx->buf_width  = (ctx->width  & 0xFFFFFFF0) + 16;
    if ((ctx->height & 0x0F) == 0)    // 16 aligned (ctx->height%16 == 0)
        ctx->buf_height = ctx->height;
    else
        ctx->buf_height = (ctx->height & 0xFFFFFFF0) + 16;


    // If codec mode is VC1_DEC,
    // width & height value are not from return value of SEQ_INIT command
    // but extracting from config stream.
    if (ctx->codec_mode == VC1_DEC) {
        Mem_Cpy(&(ctx->height), ctx->pStrmBuf + 12, 4);
        Mem_Cpy(&(ctx->width), ctx->pStrmBuf + 16, 4);
        ctx->buf_width = ctx->width;
    }

    LOG_MSG(LOG_TRACE, "MFCInst_Init", "SEQ_SRC_SIZE, (width=%d) (height=%d) (stride=%d)\r\n",     \
            ctx->width, ctx->height, ctx->buf_width);


    ////////////////////////////////////////////////
    //                                            //
    // 4. Getting FRAME_BUF for this instance     //
    //                                            //
    ////////////////////////////////////////////////
    // nFramBufSize is (YUV420 frame size) * (required frame buffer count)
#if (MFC_ROTATE_ENABLE == 1)
    // If rotation is enabled, one more YUV buffer is required.
    nFramBufSize = ((ctx->buf_width * ctx->buf_height * 3) >> 1)  *  (pPARAM_SEQ_INIT->RET_DEC_SEQ_FRAME_NEED_COUNT + 1);
#else
    nFramBufSize = ((ctx->buf_width * ctx->buf_height * 3) >> 1)  *  pPARAM_SEQ_INIT->RET_DEC_SEQ_FRAME_NEED_COUNT;
#endif
    if ( Get_MfcFramBufAddr(ctx, nFramBufSize) == FALSE ) {
        LOG_MSG(LOG_ERROR, "MFCInst_Init", "MFC Instance init failed! (required frame buffer size = %d)\r\n", nFramBufSize);
        return MFCINST_ERR_ETC;
    }
    ctx->framBufAllocated = 1;
    ctx->frambufCnt       = pPARAM_SEQ_INIT->RET_DEC_SEQ_FRAME_NEED_COUNT;


    //////////////////////////////////////////////////////////////////////
    //                                                                  //
    // 5. Set the Parameters in the PARA_BUF for SET_FRAME_BUF command. //
    //                                                                  //
    //////////////////////////////////////////////////////////////////////
    // Buffer address of Y, Cb, Cr will be set in PARAM_BUF before issuing SET_FRAME_BUF command.
    pPARAM_BUF = (unsigned char *)GetParamBufVirAddr();
    frame_size = ctx->buf_width * ctx->buf_height;
    for (i=0; i<pPARAM_SEQ_INIT->RET_DEC_SEQ_FRAME_NEED_COUNT; i++)
    {
        *((int *) (pPARAM_BUF + i*3*4))      = ctx->phyadrFramBuf + i * ((frame_size * 3) >> 1);
        *((int *) (pPARAM_BUF + i*3*4 + 4))  = ctx->phyadrFramBuf + i * ((frame_size * 3) >> 1) + frame_size;
        *((int *) (pPARAM_BUF + i*3*4 + 8))  = ctx->phyadrFramBuf + i * ((frame_size * 3) >> 1) + frame_size + (frame_size >> 2);
    }


    ////////////////////////////////////////
    //                                    //
    // 6. Issue the SET_FRAME_BUF command //
    //                                    //
    ////////////////////////////////////////
    // 'SET_FRAME_BUF_NUM' must be greater than or equal to RET_DEC_SEQ_FRAME_NEED_COUNT.
    pPARAM_SET_FRAME_BUF = (S3C6410_MFC_PARAM_REG_SET_FRAME_BUF *)  MfcGetCmdParamRegion();
    pPARAM_SET_FRAME_BUF->SET_FRAME_BUF_NUM    = pPARAM_SEQ_INIT->RET_DEC_SEQ_FRAME_NEED_COUNT;
    pPARAM_SET_FRAME_BUF->SET_FRAME_BUF_STRIDE = ctx->buf_width;
    MfcIssueCmd(ctx->inst_no, ctx->codec_mode, SET_FRAME_BUF);


    ////////////////////////////
    ///    STATE changing    ///
    ////////////////////////////
    // Change the state to MFCINST_STATE_DEC_INITIALIZED
    // If the input stream data is less than the 2 PARTUNITs size,
    // then the state is changed to MFCINST_STATE_DEC_PIC_RUN_RING_BUF_LAST_UNITS.
    MFCINST_STATE_TRANSITION(ctx, MFCINST_STATE_DEC_INITIALIZED);
    if (last_unit) {
        MFCINST_STATE_TRANSITION(ctx, MFCINST_STATE_DEC_PIC_RUN_RING_BUF_LAST_UNITS);
        MfcSetEos(0);
    }

    LOG_MSG(LOG_TRACE, "MFCInst_Init", "After init state : %d\n", ctx->state_var);


    return MFCINST_RET_OK;
}


int MFCInst_Enc_Init(MFCInstCtx *ctx, MFC_CODECMODE codec_mode, enc_info_t *enc_info)
{
    int              i;

    S3C6410_MFC_SFR    *mfc_sfr;        // MFC SFR pointer

    unsigned char    *pPARAM_BUF;    // PARAM_BUF in BITPROC_BUF
    int              nFramBufSize;    // Required size in FRAM_BUF
    int              frame_size;    // width * height
    int              num_mbs;        // Number of MBs
    int              slices_mb;        // MB number of slice (only if SLICE_MODE_MULTIPLE is selected.)

    static S3C6410_MFC_PARAM_REG_ENC_SEQ_INIT    *pPARAM_SEQ_INIT;        // Parameter of SEQ_INIT command
    static S3C6410_MFC_PARAM_REG_SET_FRAME_BUF   *pPARAM_SET_FRAME_BUF;    // Parameter of SET_FRAME_BUF command


    // check parameters from user application
    if ( (enc_info->width & 0x0F) || (enc_info->height & 0x0F) ) {
        LOG_MSG(LOG_ERROR, "MFCInst_Enc_Init", "Source picture width and height must be a multiple of 16. width : %d, height : %d\n", \
            enc_info->width, enc_info->height);

        return MFCINST_ERR_INVALID_PARAM;
    }


    if (enc_info->gopNum > 60) {
        LOG_MSG(LOG_ERROR, "MFCInst_Enc_Init", "Maximum GOP number is 60.  GOP number = %d\n", enc_info->gopNum);

        return MFCINST_ERR_INVALID_PARAM;
    }

    ctx->width            = enc_info->width;
    ctx->height            = enc_info->height;
    ctx->frameRateRes    = enc_info->frameRateRes;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -