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

📄 mfc_instance.c

📁 SAMSUNG S3C6410 CPU BSP for winmobile6
💻 C
📖 第 1 页 / 共 4 页
字号:
/*
 * Project Name MFC DRIVER
 * Copyright  2007 Samsung Electronics Co, Ltd. All Rights Reserved.
 *
 * This software is the confidential and proprietary information
 * of Samsung Electronics  ("Confidential Information").
 * you shall not disclose such Confidential Information and shall use
 * it only in accordance with the terms of the license agreement
 * you entered into with Samsung Electronics
 *
 * This source file is for initializing the MFC instance.
 *
 * @name MFC DRIVER MODULE Module (MFC_Inst_Init.c)
 * @author name(email address)
 * @date 03-28-07
 */

#include "Mfc.h"
#include "MFC_Instance.h"
#include "MfcMemory.h"
#include "DataBuf.h"
#include "FramBufMgr.h"
#include "LogMsg.h"
#include "MfcConfig.h"
#include "MfcSfr.h"
#include "BitProcBuf.h"
#include "MFC_Inst_Pool.h"

#ifdef LINUX
#include <asm/io.h>
#include <linux/slab.h>
#include <linux/string.h>
#include <asm/uaccess.h>
#endif


static MFCInstCtx _mfcinst_ctx[MFC_NUM_INSTANCES_MAX];


MFCInstCtx *MFCInst_GetCtx(int inst_no)
{
    if ((inst_no < 0) || (inst_no >= MFC_NUM_INSTANCES_MAX))
        return NULL;

    if (MFCINST_STATE(&(_mfcinst_ctx[inst_no])) >= MFCINST_STATE_CREATED)
        return &(_mfcinst_ctx[inst_no]);
    else
        return NULL;
}



// Filling the pStrmBuf and phyadrStrmBuf variables of the MfcInstCtx structure
// (pStrmBuf and phyadrStrmBuf are the virtual and physical address of STRM_BUF(stream buffer) respectively.)
static void Get_MfcStrmBufAddr(MFCInstCtx *ctx, int isLineBuf)
{
    // LINE BUF
    if (isLineBuf) {
        ctx->pStrmBuf        = (unsigned char *) ( GetDataBufVirAddr() + (ctx->inst_no * MFC_LINE_BUF_SIZE_PER_INSTANCE) );
        ctx->phyadrStrmBuf    = (PHYADDR_VAL) ( GetDataBufPhyAddr() + (ctx->inst_no * MFC_LINE_BUF_SIZE_PER_INSTANCE) );
        ctx->nStrmBufSize   = MFC_LINE_BUF_SIZE_PER_INSTANCE;
    }
    // RING BUF
    else {
#if (MFC_LINE_RING_SHARE == 1)
        ctx->pStrmBuf        = (unsigned char *) GetDataBufVirAddr();
        ctx->phyadrStrmBuf    = (PHYADDR_VAL) GetDataBufPhyAddr();
#elif (MFC_LINE_RING_SHARE == 0)
        ctx->pStrmBuf        = (unsigned char *) ( GetDataBufVirAddr() + MFC_LINE_BUF_SIZE);
        ctx->phyadrStrmBuf    = (PHYADDR_VAL) ( GetDataBufPhyAddr() + MFC_LINE_BUF_SIZE);
#endif
        ctx->nStrmBufSize   = MFC_RING_BUF_SIZE;
    }

    LOG_MSG(LOG_TRACE, "Get_MfcStrmBufAddr", "ctx->pStrmBuf address 0x%08X\n", ctx->pStrmBuf);
    LOG_MSG(LOG_TRACE, "Get_MfcStrmBufAddr", "ctx->phyadrStrmBuf address 0x%08X\n", ctx->phyadrStrmBuf);
}

// Filling the pFramBuf and phyadrFramBuf variables of the MfcInstCtx structure
// (pFramBuf and phyadrFramBuf are the virtual and physical address of FRAM_BUF(frame buffer) respectively.)
static BOOL Get_MfcFramBufAddr(MFCInstCtx *ctx, int buf_size)
{
    unsigned char    *pInstFramBuf;

    pInstFramBuf    = FramBufMgrCommit(ctx->inst_no, buf_size);
    if (pInstFramBuf == NULL) {
        LOG_MSG(LOG_ERROR, "Get_MfcFramBufAddr", "Frame buffer allocation was failed!\r\n");
        return FALSE;
    }

    FramBufMgrPrintCommitInfo();

    ctx->pFramBuf       = pInstFramBuf;    // virtual address of frame buffer
    ctx->phyadrFramBuf  = S3C6410_BASEADDR_MFC_DATA_BUF + ( (int)pInstFramBuf - (int)GetDataBufVirAddr() );
    ctx->nFramBufSize   = buf_size;

    LOG_MSG(LOG_TRACE, "Get_MfcFramBufAddr", "ctx->inst_no : %d\r\n", ctx->inst_no);
    LOG_MSG(LOG_TRACE, "Get_MfcFramBufAddr", "ctx->pFramBuf : 0x%X\r\n", ctx->pFramBuf);
    LOG_MSG(LOG_TRACE, "Get_MfcFramBufAddr", "ctx->phyadrFramBuf : 0x%X\r\n", ctx->phyadrFramBuf);

    return TRUE;
}


void MFCInst_RingBufAddrCorrection(MFCInstCtx *ctx)
{
    Get_MfcStrmBufAddr(ctx, 0);
}



int MFCInst_GetLineBuf(MFCInstCtx *ctx, unsigned char **ppBuf, int *size)
{
    ////////////////////////////
    ///    STATE checking    ///
    ////////////////////////////
    if (MFCINST_STATE_CHECK(ctx, MFCINST_STATE_DELETED)) {
        LOG_MSG(LOG_ERROR, "MFCInst_GetRingBuf", "MFC instance is deleted.\r\n");
        return MFCINST_ERR_STATE_DELETED;
    }

    if (ctx->inbuf_type == DEC_INBUF_NOT_SPECIFIED)
        ctx->inbuf_type = DEC_INBUF_LINE_BUF;
    else if (ctx->inbuf_type == DEC_INBUF_RING_BUF)
        return MFCINST_ERR_ETC;

    *ppBuf = ctx->pStrmBuf;
    *size  = MFC_LINE_BUF_SIZE_PER_INSTANCE;

    return MFCINST_RET_OK;
}

int MFCInst_GetRingBuf(MFCInstCtx *ctx, unsigned char **ppBuf, int *size)
{
    unsigned char  *pRD_PTR, *pWR_PTR;
    int             num_bytes_strm_buf;    // Number of bytes in STRM_BUF (used in IOCTL_MFC_GET_RING_BUF_ADDR)

    MFCInstCtx     *pMfcInstTmp;
    int             inst_no = 0;


    ////////////////////////////
    ///    STATE checking    ///
    ////////////////////////////
    if (MFCINST_STATE_CHECK(ctx, MFCINST_STATE_DELETED)) {
        LOG_MSG(LOG_ERROR, "MFCInst_GetRingBuf", "MFC instance is deleted.\r\n");
        return MFCINST_ERR_STATE_DELETED;
    }


    if (ctx->inbuf_type == DEC_INBUF_NOT_SPECIFIED)
        ctx->inbuf_type = DEC_INBUF_RING_BUF;
    else if (ctx->inbuf_type == DEC_INBUF_LINE_BUF)
        return MFCINST_ERR_ETC;


    // state variable checking
    if (MFCINST_STATE_CHECK(ctx, MFCINST_STATE_CREATED)) {

#if (MFC_LINE_RING_SHARE == 1)
        // If LINE_BUF and RING_BUF are shared,
        // there must be no instances other than itself.
        if (MfcInstPool_NumAvail() != (MFC_NUM_INSTANCES_MAX-1))
            return MFCINST_ERR_ETC;

        // Occupy all the instances
        // so that the other instances won't be activated
        // until this VC-1 decode instance will be closed.
        MfcInstPool_OccupyAll();

#elif (MFC_LINE_RING_SHARE == 0)
        // If LINE_BUF and RING_BUF are separated.
        // there must be no other instances using the RING_BUF other than itself.
        if (MfcInstPool_NumAvail() < (MFC_NUM_INSTANCES_MAX-1)) {
            for (inst_no=0; inst_no<MFC_NUM_INSTANCES_MAX; inst_no++) {
                if (inst_no == ctx->inst_no)
                    continue;

                pMfcInstTmp = MFCInst_GetCtx(inst_no);
                if (pMfcInstTmp == NULL)
                    continue;
                if (pMfcInstTmp->inbuf_type == DEC_INBUF_RING_BUF) {
                    return MFCINST_ERR_ETC;
                }
            }
        }

        // If LINE_BUF & RING_BUF are not shared,
        // the RING_BUF address must be different from the LINE_BUF.
        // For this reason, the address needs correction at first.
        MFCInst_RingBufAddrCorrection(ctx);
#endif
    }

    // Get the current positions of RD_PTR and WR_PTR
    MFCInst_GetStreamRWPtrs(ctx, &pRD_PTR, &pWR_PTR);

    // When MFC instance is in the state of MFCINST_STATE_CREATED,
    // the size of data to be filled in RING_BUF is double the PARTUNIT size.
    if (MFCINST_STATE_CHECK(ctx, MFCINST_STATE_CREATED)) {
        *ppBuf = pWR_PTR;
        *size  = MFC_RING_BUF_PARTUNIT_SIZE << 1;

        MFCINST_STATE_BUF_FILL_REQ_SET(ctx);

        return MFCINST_RET_OK;
    }


    *ppBuf = pWR_PTR;
    num_bytes_strm_buf = (int)pWR_PTR - (int)pRD_PTR;
    if (num_bytes_strm_buf <= 0)    // if WR_PTR is behind the RD_PTR.
        num_bytes_strm_buf  += MFC_RING_BUF_SIZE;

    // Num of bytes in RING_BUF is less than MFC_RING_BUF_PARTUNIT_SIZE,
    // then load one more MFC_RING_BUF_PARTUNIT_SIZE unit.
    if ((num_bytes_strm_buf < MFC_RING_BUF_PARTUNIT_SIZE)
            && MFCINST_STATE_CHECK(ctx, MFCINST_STATE_DEC_PIC_RUN_RING_BUF)) {
        *size = MFC_RING_BUF_PARTUNIT_SIZE;
        MFCINST_STATE_BUF_FILL_REQ_SET(ctx);
    }
    else
        *size = 0;


    return MFCINST_RET_OK;
}

int MFCInst_GetFramBuf(MFCInstCtx *ctx, unsigned char **ppBuf, int *size)
{
    ////////////////////////////
    ///    STATE checking    ///
    ////////////////////////////
    if (MFCINST_STATE_CHECK(ctx, MFCINST_STATE_DELETED)) {
        LOG_MSG(LOG_ERROR, "MFCInst_GetFramBuf", "MFC instance is deleted.\r\n");
        return MFCINST_ERR_STATE_DELETED;
    }
    if (MFCINST_STATE_CHECK(ctx, MFCINST_STATE_CREATED)) {
        LOG_MSG(LOG_ERROR, "MFCInst_GetFramBuf", "MFC instance is not initialized.\r\n");
        return MFCINST_ERR_STATE_CHK;
    }

    if (ctx->pFramBuf == NULL) {
        LOG_MSG(LOG_ERROR, "MFCInst_GetFramBuf", "MFC Frame buffer is not internally allocated yet.\n");
        return MFCINST_ERR_ETC;
    }


    *size  = (ctx->buf_width * ctx->buf_height * 3) >> 1;    // YUV420 frame size

    if (ctx->idx < 0)    // RET_DEC_PIC_IDX == -3  (No picture to be displayed)
        *ppBuf = NULL;
    else {
        *ppBuf = ctx->pFramBuf + (ctx->idx) * (*size);
#if (MFC_ROTATE_ENABLE == 1)
        if (ctx->PostRotMode & 0x0010)
            *ppBuf = ctx->pFramBuf + (ctx->frambufCnt) * (*size);
#endif
    }


    return MFCINST_RET_OK;
}

int MFCInst_GetFramBufPhysical(MFCInstCtx *ctx, unsigned char **ppBuf, int *size)
{
    ////////////////////////////
    ///    STATE checking    ///
    ////////////////////////////
    if (MFCINST_STATE_CHECK(ctx, MFCINST_STATE_DELETED)) {
        LOG_MSG(LOG_ERROR, "MFCInst_GetFramBuf", "MFC instance is deleted.\r\n");
        return MFCINST_ERR_STATE_DELETED;
    }
    if (MFCINST_STATE_CHECK(ctx, MFCINST_STATE_CREATED)) {
        LOG_MSG(LOG_ERROR, "MFCInst_GetFramBuf", "MFC instance is not initialized.\r\n");
        return MFCINST_ERR_STATE_CHK;
    }

    if (ctx->pFramBuf == NULL) {
        LOG_MSG(LOG_ERROR, "MFCInst_GetFramBuf", "MFC Frame buffer is not internally allocated yet.\n");
        return MFCINST_ERR_ETC;
    }


    *size  = (ctx->width * ctx->height * 3) >> 1;    // YUV420 frame size

    if (ctx->idx < 0)    // RET_DEC_PIC_IDX == -3  (No picture to be displayed)
        *ppBuf = NULL;
    else
        *ppBuf = (unsigned char *) ( ctx->phyadrFramBuf + (ctx->idx) * (*size) );


    return MFCINST_RET_OK;
}

//
// Function Name: MFCInst_GetInstNo
// Description
//      It returns the instance number of the 6410 MFC instance context.
// Parameters
//      ctx[IN]: MFCInstCtx
//
int MFCInst_GetInstNo(MFCInstCtx *ctx)
{
    return ctx->inst_no;
}

//
// Function Name: MFCInst_GetStreamRWPtrs
// Description
//      It returns the virtual address of RD_PTR and WR_PTR.
// Parameters
//      ctx[IN]: MFCInstCtx
//      ppRD_PTR[OUT]: RD_PTR
//      ppWR_PTR[OUT]: WR_PTR
//
BOOL MFCInst_GetStreamRWPtrs(MFCInstCtx *ctx, unsigned char **ppRD_PTR, unsigned char **ppWR_PTR)
{
    S3C6410_MFC_SFR    *mfc_sfr;        // MFC SFR pointer
    int              diff_vir_phy;


    if (MFCINST_STATE(ctx) < MFCINST_STATE_CREATED)
        return FALSE;

    if (MFCINST_STATE_CHECK(ctx, MFCINST_STATE_CREATED)) {
        // If MFCInstCtx is just created and not initialized by MFCInst_Init,
        // then the initial RD_PTR and WR_PTR are the start address of STRM_BUF.
        *ppRD_PTR = ctx->pStrmBuf;
        *ppWR_PTR = ctx->pStrmBuf;
    }
    else {
        // The physical to virtual address conversion of RD_PTR and WR_PTR.
        diff_vir_phy  =  (int) (ctx->pStrmBuf - ctx->phyadrStrmBuf);
        mfc_sfr = (S3C6410_MFC_SFR *) GetMfcSfrVirAddr();
        *ppRD_PTR = (unsigned char *) (diff_vir_phy + mfc_sfr->BIT_STR_BUF_RW_ADDR[ctx->inst_no].BITS_RD_PTR);
        *ppWR_PTR = (unsigned char *) (diff_vir_phy + mfc_sfr->BIT_STR_BUF_RW_ADDR[ctx->inst_no].BITS_WR_PTR);
    }

    return TRUE;
}

BOOL MFCInst_SetInbufType(MFCInstCtx *ctx, MFCINST_DEC_INBUF_TYPE inbuf_type)
{
    ctx->inbuf_type = inbuf_type;

    return TRUE;
}


unsigned int MFCInst_Set_PostRotate(MFCInstCtx *ctx, unsigned int post_rotmode)
{
    unsigned int old_post_rotmode;

    old_post_rotmode = ctx->PostRotMode;

⌨️ 快捷键说明

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