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

📄 mfc_instance.c

📁 6410BSP3
💻 C
📖 第 1 页 / 共 4 页
字号:
        else if (pPARAM_DEC_PIC_RUN->RET_DEC_PIC_IDX == 0xFFFFFFFD) {    // RET_DEC_PIC_IDX == -3
            LOG_MSG(LOG_TRACE, "Decode", "No picture to be displayed.\r\n");
        }
        else {
            LOG_MSG(LOG_ERROR, "Decode", "Decoding Fail, ret = %d\r\n", pPARAM_DEC_PIC_RUN->RET_DEC_PIC_IDX);
            return MFCINST_ERR_DEC_DECODE_FAIL_ETC;
        }
    }

    ctx->run_index = pPARAM_DEC_PIC_RUN->RET_DEC_PIC_IDX;
#if (defined(DIVX_ENABLE) && (DIVX_ENABLE == 1))
    ctx->RET_DEC_PIC_RUN_BAK_BYTE_CONSUMED          = pPARAM_DEC_PIC_RUN->RET_DEC_PIC_BCNT;
    ctx->RET_DEC_PIC_RUN_BAK_MP4ASP_FCODE           = pPARAM_DEC_PIC_RUN->RET_DEC_PIC_FCODE_FWD;
    ctx->RET_DEC_PIC_RUN_BAK_MP4ASP_TIME_BASE_LAST  = pPARAM_DEC_PIC_RUN->RET_DEC_PIC_TIME_BASE_LAST;
    ctx->RET_DEC_PIC_RUN_BAK_MP4ASP_NONB_TIME_LAST  = pPARAM_DEC_PIC_RUN->RET_DEC_PIC_NONB_TIME_LAST;
    ctx->RET_DEC_PIC_RUN_BAK_MP4ASP_MP4ASP_TRD      = pPARAM_DEC_PIC_RUN->RET_DEC_PIC_TRD;
#endif

    if( pPARAM_DEC_PIC_RUN->RET_DEC_PIC_ERR_MB_NUM > 0 )
        RETAILMSG( 1, (_T("Report MB Error num=%d\r\n"), pPARAM_DEC_PIC_RUN->RET_DEC_PIC_ERR_MB_NUM ) );

    ////////////////////////////
    ///    STATE changing    ///
    ////////////////////////////
    // state change to MFCINST_STATE_DEC_PIC_RUN_LINE_BUF
    MFCINST_STATE_TRANSITION(ctx, MFCINST_STATE_DEC_PIC_RUN_LINE_BUF);

    return MFCINST_RET_OK;
}


int MFCInst_Encode(MFCInstCtx *ctx, int *enc_data_size, int *header_size)
{
    volatile S3C6410_MFC_PARAM_REG_ENC_PIC_RUN    *pPARAM_ENC_PIC_RUN;
    S3C6410_MFC_SFR                        *mfc_sfr;

    int                                 hdr_size, hdr_size2,hdr_size3;
    unsigned char                       *hdr_buf_tmp=NULL;

    ////////////////////////////
    ///    STATE checking    ///
    ////////////////////////////
    if (!MFCINST_STATE_CHECK(ctx, MFCINST_STATE_ENC_INITIALIZED) && !MFCINST_STATE_CHECK(ctx, MFCINST_STATE_ENC_PIC_RUN_LINE_BUF)) {

        LOG_MSG(LOG_ERROR, "MFCInst_Encode", "MFC Encoder instance is not initialized or not using the line buffer.\r\n");
        return MFCINST_ERR_STATE_CHK;
    }

    mfc_sfr = (S3C6410_MFC_SFR *) GetMfcSfrVirAddr();


    // The 1st call of this function (MFCInst_Encode) will generate the stream header (mpeg4: VOL, h264: SPS/PPS).
    //
    if (MFCINST_STATE_CHECK(ctx, MFCINST_STATE_ENC_INITIALIZED)) {

        if (ctx->codec_mode == MP4_ENC) {
            //  ENC_HEADER command  //
            MFCInst_EncHeader(ctx, 1, 0, ctx->phyadrStrmBuf, ctx->nStrmBufSize, &hdr_size);	// VOS
            MFCInst_EncHeader(ctx, 2, 0, ctx->phyadrStrmBuf + (hdr_size + 3), ctx->nStrmBufSize-(hdr_size+3), &hdr_size2);    // VO		
            MFCInst_EncHeader(ctx, 0, 0, ctx->phyadrStrmBuf + (hdr_size + 3) + (hdr_size2 + 3), ctx->nStrmBufSize-(hdr_size+3)-(hdr_size2 + 3), &hdr_size3);    // VOL				
            LOG_MSG(LOG_TRACE, "Encode", "MPEG4 Header Size : VOS=%d, VO=%d, VOL=%d \r\n", hdr_size, hdr_size2, hdr_size3);

            hdr_buf_tmp = Mem_Alloc(hdr_size + 3 + hdr_size2 + 3 + hdr_size3);

                Mem_Cpy(hdr_buf_tmp, ctx->pStrmBuf, hdr_size);
            InvalidateCacheRange((PBYTE )ctx->pStrmBuf, (PBYTE )(ctx->pStrmBuf + (hdr_size+3) ) );

            Mem_Cpy(hdr_buf_tmp + hdr_size, (void *)((unsigned int)(ctx->pStrmBuf + (hdr_size + 3)) & 0xFFFFFFFC), hdr_size2);
            InvalidateCacheRange((PBYTE )(ctx->pStrmBuf), (PBYTE )((ctx->pStrmBuf+(hdr_size+3) + (hdr_size2+3))) );

	     Mem_Cpy(hdr_buf_tmp + hdr_size + hdr_size2, (void *)((unsigned int)(ctx->pStrmBuf + (hdr_size+3) + (hdr_size2+3)) & 0xFFFFFFFC), hdr_size3);
            InvalidateCacheRange((PBYTE )(ctx->pStrmBuf), (PBYTE )(ctx->pStrmBuf+(hdr_size+3)+(hdr_size2+3)+hdr_size3) );
			
	     hdr_size = hdr_size+hdr_size2+hdr_size3;

        }
        else if (ctx->codec_mode == AVC_ENC) {

            //  ENC_HEADER command  //
            MFCInst_EncHeader(ctx, 0, 0, ctx->phyadrStrmBuf, ctx->nStrmBufSize, &hdr_size);    // SPS
            MFCInst_EncHeader(ctx, 1, 0, ctx->phyadrStrmBuf + (hdr_size + 3), ctx->nStrmBufSize-(hdr_size+3), &hdr_size2);    // PPS
            LOG_MSG(LOG_TRACE, "Encode", "MPEG4 Header Size : SPS=%d, PPS=%d \r\n", hdr_size, hdr_size2);

            // Backup the stream header in the temporary header buffer.
            hdr_buf_tmp = (unsigned char *) Mem_Alloc(hdr_size + 3 + hdr_size2);
            if (hdr_buf_tmp)
            {
                Mem_Cpy(hdr_buf_tmp, ctx->pStrmBuf, hdr_size);
                InvalidateCacheRange((PBYTE )ctx->pStrmBuf, (PBYTE )(ctx->pStrmBuf + hdr_size) );
                Mem_Cpy(hdr_buf_tmp + hdr_size, (void *)((unsigned int)(ctx->pStrmBuf + (hdr_size + 3)) & 0xFFFFFFFC), hdr_size2);
                hdr_size = hdr_size + hdr_size2;
                InvalidateCacheRange((PBYTE )ctx->pStrmBuf, (PBYTE )(ctx->pStrmBuf + hdr_size) );
            }
            else
            {
                return MFCINST_ERR_MEMORY_ALLOCATION_FAIL;
            }
        }
    }


    // SEI message with recovery point
    if ((ctx->enc_pic_option & 0x0F000000) && (ctx->codec_mode == AVC_ENC))
    {
        // Free hdr_seze
        if(hdr_buf_tmp)
                Mem_Free(hdr_buf_tmp);   
        
        //  ENC_HEADER command  //
        MFCInst_EncHeader(ctx, 4, ((ctx->enc_pic_option & 0x0F000000) >> 24), ctx->phyadrStrmBuf, ctx->nStrmBufSize, &hdr_size);    // SEI
        // Backup the stream header in the temporary header buffer.
        hdr_buf_tmp = (unsigned char *) Mem_Alloc(hdr_size);
        if (hdr_buf_tmp)
        {
            Mem_Cpy(hdr_buf_tmp, ctx->pStrmBuf, hdr_size);
            InvalidateCacheRange((PBYTE )ctx->pStrmBuf, (PBYTE )(ctx->pStrmBuf + hdr_size) );
        }
        else
        {
            return MFCINST_ERR_MEMORY_ALLOCATION_FAIL;
        }
    }

    /*
     * Set the address of each component of YUV420
     */
    pPARAM_ENC_PIC_RUN = (S3C6410_MFC_PARAM_REG_ENC_PIC_RUN *) MfcGetCmdParamRegion();
    pPARAM_ENC_PIC_RUN->ENC_PIC_SRC_ADDR_Y  = ctx->phyadrFramBuf;
    pPARAM_ENC_PIC_RUN->ENC_PIC_SRC_ADDR_CB = ctx->phyadrFramBuf  +   ctx->buf_width * ctx->height;
    pPARAM_ENC_PIC_RUN->ENC_PIC_SRC_ADDR_CR = ctx->phyadrFramBuf  + ((ctx->buf_width * ctx->height * 5) >> 2);
    pPARAM_ENC_PIC_RUN->ENC_PIC_ROT_MODE    = 0;
    pPARAM_ENC_PIC_RUN->ENC_PIC_OPTION      = (ctx->enc_pic_option & 0x0000FFFF);
    pPARAM_ENC_PIC_RUN->ENC_PIC_BB_START    = ctx->phyadrStrmBuf;
    pPARAM_ENC_PIC_RUN->ENC_PIC_BB_SIZE     = ctx->nStrmBufSize;


    if (!MfcIssueCmd(ctx->inst_no, ctx->codec_mode, PIC_RUN)) {
        return MFCINST_ERR_ENC_PIC_RUN_CMD_FAIL;
    }

    ctx->enc_pic_option = 0;    // Reset the encoding picture option at every picture
    ctx->run_index = 0;
    ctx->RET_ENC_PIC_RUN_BAK_PIC_TYPE      = pPARAM_ENC_PIC_RUN->RET_ENC_PIC_TYPE;

    *enc_data_size = mfc_sfr->BIT_STR_BUF_RW_ADDR[ctx->inst_no].BITS_WR_PTR - ctx->phyadrStrmBuf;    // calculte encoded data size
    *header_size   = 0;

    if (hdr_buf_tmp) {
        memmove(ctx->pStrmBuf + hdr_size, ctx->pStrmBuf, *enc_data_size);
        CleanInvalidateCacheRange((PBYTE )ctx->pStrmBuf, (PBYTE )(ctx->pStrmBuf + *enc_data_size) );
        Mem_Cpy(ctx->pStrmBuf, hdr_buf_tmp, hdr_size);
        CleanInvalidateCacheRange((PBYTE )ctx->pStrmBuf, (PBYTE )(ctx->pStrmBuf + *enc_data_size) );
        Mem_Free(hdr_buf_tmp);

        *enc_data_size += hdr_size;
        *header_size    = hdr_size;
    }

    ////////////////////////////
    ///    STATE changing    ///
    ////////////////////////////
    // state change to MFCINST_STATE_ENC_PIC_RUN_LINE_BUF
    MFCINST_STATE_TRANSITION(ctx, MFCINST_STATE_ENC_PIC_RUN_LINE_BUF);


    return MFCINST_RET_OK;
}

// hdr_code == 0: SPS
// hdr_code == 1: PPS
// hdr_code == 4: SEI
int MFCInst_EncHeader(MFCInstCtx *ctx, int hdr_code, int hdr_num, unsigned int outbuf_physical_addr, int outbuf_size, int *hdr_size)
{
    volatile S3C6410_MFC_PARAM_REG_ENC_HEADER    *pPARAM_ENC_HEADER;
    S3C6410_MFC_SFR                        *mfc_sfr;

    unsigned int uiEncodeLevel;

    if (!MFCINST_STATE_CHECK(ctx, MFCINST_STATE_ENC_INITIALIZED) && !MFCINST_STATE_CHECK(ctx, MFCINST_STATE_ENC_PIC_RUN_LINE_BUF)) {

        LOG_MSG(LOG_ERROR, "MFCInst_EncHeader", "MFC Encoder instance is not initialized or not using the line buffer.\r\n");
        return MFCINST_ERR_STATE_CHK;
    }

    if ((ctx->codec_mode != MP4_ENC) && (ctx->codec_mode != AVC_ENC)) {
        return MFCINST_ERR_WRONG_CODEC_MODE;
    }

// VOS Level in MP4
    if((ctx->codec_mode == MP4_ENC) && (hdr_code == 1))
    {
        uiEncodeLevel = ((ctx->level<<8) | hdr_code);
    }
    else
    {
        uiEncodeLevel = hdr_code;
    }
//	

    /*
     * Set the address of each component of YUV420
     */
    pPARAM_ENC_HEADER = (S3C6410_MFC_PARAM_REG_ENC_HEADER *) MfcGetCmdParamRegion();
    pPARAM_ENC_HEADER->ENC_HEADER_CODE      = uiEncodeLevel;
    pPARAM_ENC_HEADER->ENC_HEADER_BB_START  = outbuf_physical_addr & 0xFFFFFFFC;
    pPARAM_ENC_HEADER->ENC_HEADER_BB_SIZE   = outbuf_size; //ctx->nStrmBufSize;
    if (hdr_code == 4)    // SEI recovery point
        pPARAM_ENC_HEADER->ENC_HEADER_NUM   = hdr_num; // recovery point value

    mfc_sfr = (S3C6410_MFC_SFR *) GetMfcSfrVirAddr();


    if (!MfcIssueCmd(ctx->inst_no, ctx->codec_mode, ENC_HEADER)) {
        return MFCINST_ERR_ENC_HEADER_CMD_FAIL;
    }


    *hdr_size = mfc_sfr->BIT_STR_BUF_RW_ADDR[ctx->inst_no].BITS_WR_PTR - pPARAM_ENC_HEADER->ENC_HEADER_BB_START;

    return MFCINST_RET_OK;
}


int MFCInst_EncParamChange(MFCInstCtx *ctx, unsigned int param_change_enable, unsigned int param_change_val)
{
    volatile S3C6410_MFC_PARAM_REG_ENC_PARAM_CHANGE    *pPARAM_ENC_PARAM_CHANGE;


    int              num_mbs;        // Number of MBs
    int              slices_mb;        // MB number of slice (only if SLICE_MODE_MULTIPLE is selected.)


    pPARAM_ENC_PARAM_CHANGE = (S3C6410_MFC_PARAM_REG_ENC_PARAM_CHANGE *) MfcGetCmdParamRegion();

    memset((void *)pPARAM_ENC_PARAM_CHANGE, 0, sizeof(S3C6410_MFC_PARAM_REG_ENC_PARAM_CHANGE));


    pPARAM_ENC_PARAM_CHANGE->ENC_PARAM_CHANGE_ENABLE      = param_change_enable;

    // GOP_NUM
    if (param_change_enable == (1 << 0)) {
        if (param_change_val > 60) {
            LOG_MSG(LOG_ERROR, "MFCInst_EncParamChange", "MFC Encoder Parameter change value is invalid.\r\n");
            return MFCINST_ERR_ENC_PARAM_CHANGE_INVALID_VALUE;
        }
        pPARAM_ENC_PARAM_CHANGE->ENC_PARAM_CHANGE_GOP_NUM        = param_change_val;
    }
    // INTRA_QP
    else if (param_change_enable == (1 << 1)) {
        if (((ctx->codec_mode == MP4_DEC || ctx->codec_mode == H263_DEC) && (param_change_val == 0 || param_change_val > 31))
                || (ctx->codec_mode == AVC_DEC && param_change_val > 51)) {
            LOG_MSG(LOG_ERROR, "MFCInst_EncParamChange", "MFC Encoder Parameter change value is invalid.\r\n");
            return MFCINST_ERR_ENC_PARAM_CHANGE_INVALID_VALUE;
        }
        pPARAM_ENC_PARAM_CHANGE->ENC_PARAM_CHANGE_INTRA_QP       = param_change_val;
    }
    // BITRATE
    else if (param_change_enable == (1 << 2)) {
        if (param_change_val > 0x07FFF) {
            LOG_MSG(LOG_ERROR, "MFCInst_EncParamChange", "MFC Encoder Parameter change value is invalid.\r\n");
            return MFCINST_ERR_ENC_PARAM_CHANGE_INVALID_VALUE;
        }
        pPARAM_ENC_PARAM_CHANGE->ENC_PARAM_CHANGE_BITRATE        = param_change_val;
    }
    // F_RATE
    else if (param_change_enable == (1 << 3)) {
        pPARAM_ENC_PARAM_CHANGE->ENC_PARAM_CHANGE_F_RATE         = param_change_val;
    }
    // INTRA_REFRESH
    else if (param_change_enable == (1 << 4)) {
        if ((int)param_change_val > ((ctx->width * ctx->height) >> 8)) {
            LOG_MSG(LOG_ERROR, "MFCInst_EncParamChange", "MFC Encoder Parameter change value is invalid.\r\n");
            return MFCINST_ERR_ENC_PARAM_CHANGE_INVALID_VALUE;
        }
        pPARAM_ENC_PARAM_CHANGE->ENC_PARAM_CHANGE_INTRA_REFRESH  = param_change_val;
    }
    // SLICE_MODE
    else if (param_change_enable == (1 << 5)) {

        // MB size is 16x16. -> width & height are divided by 16 to get number of MBs. (Division by 16 == shift right by 4-bit)
        num_mbs   = (ctx->width >> 4) * (ctx->height >> 4);

        if ((int)param_change_val > 256 || (int)param_change_val > num_mbs) {
            LOG_MSG(LOG_ERROR, "MFCInst_EncParamChange", "MFC Encoder Parameter change value is invalid.\r\n");
            return MFCINST_ERR_ENC_PARAM_CHANGE_INVALID_VALUE;
        }

        if (param_change_val == 0) {
            pPARAM_ENC_PARAM_CHANGE->ENC_PARAM_CHANGE_SLICE_MODE   = SLICE_MODE_ONE;
        }
        else {

            slices_mb = (num_mbs / param_change_val);
            ctx->enc_num_slices = param_change_val;

            pPARAM_ENC_PARAM_CHANGE->ENC_PARAM_CHANGE_SLICE_MODE   = SLICE_MODE_MULTIPLE | (1 << 1) | (slices_mb<< 2);;
        }
    }

    if (!MfcIssueCmd(ctx->inst_no, ctx->codec_mode, ENC_PARAM_CHANGE)) {
        return MFCINST_ERR_ENC_HEADER_CMD_FAIL;
    }

    return MFCINST_RET_OK;
}

⌨️ 快捷键说明

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