示例#1
0
/* ============================================================================================= */
SCODE VencMaster_LoadConfig(HANDLE hVencMObject)
{
	TMasterInfo *ptMasterInfo = (TMasterInfo *)(hVencMObject);

	if (ptMasterInfo == NULL)
		return S_FAIL;

	DBPRINT1("[VENC_MASTER] XmlWrapper read config %s \n", ptMasterInfo->szConfigFile);
	if (XmlWrapper_ReadFile_UsrDefFunc(ptMasterInfo->szConfigFile, ptMasterInfo->hXMLWrapperObj, ptMasterInfo) != S_OK) {
		fprintf(stderr, "[VENC_MASTER] XmlWrapper reload config fail! \n");
		return S_FAIL;
	}

	if (XmlWrapper_Reset(ptMasterInfo->hXMLWrapperObj) != S_OK)  {
		DBPRINT0("[VENC_MASTER] XmlWrapper read config fail! \n");
		return S_FAIL;
	}

	VencMaster_ResPLReConfig(ptMasterInfo);
	VencMaster_WBReConfig(ptMasterInfo);
	VencMaster_CCReConfig(ptMasterInfo);
	VencMaster_TMReConfig(ptMasterInfo);
	VencMaster_BlackClampReConfig(ptMasterInfo);
	VencMaster_DeImpulseReConfig(ptMasterInfo);
	VencMaster_CEReConfig(ptMasterInfo);
	VencMaster_GammaTableReConfig(ptMasterInfo);
	VencMaster_AEReConfig(ptMasterInfo);
	VencMaster_AFReConfig(ptMasterInfo);
	VencMaster_ImgAdjReConfig(ptMasterInfo);
	VencMaster_WDRReConfig(ptMasterInfo);
	return S_OK;
}
示例#2
0
/* ========================================================================== */
void VencEncoder_Mp4VForceCI(HANDLE hObject, EVideoFormat vFormat)
{
    TEncoderInfo *ptEncoderInfo = (TEncoderInfo *) hObject;
	HANDLE hMp4VEncObj = ptEncoderInfo->hMp4VEncObj;
	DWORD dwSpecConfSize, dwProfileLevel;
	TSharedBuffMgrState tSharedBuffMgrState;
	TUBufferConfMP4V *ptubcMP4V ;//= (TUBufferConfMP4V *)(ptEncoderInfo->pbyBuffer);  
	BYTE* pbyBuffer;
	fd_set               	fdsWrite;
	struct timeval 			timeout;
	int						fdShardBuffer;
	int     				iResult;
	SCODE 	scResult = S_FAIL;
	if (!hMp4VEncObj)
		return;

	ptEncoderInfo->pfnGetOutputBufferFD(ptEncoderInfo->hOutputSrdObj, &fdShardBuffer);

	if (ptEncoderInfo->pfnRequestOutputBuffer(ptEncoderInfo->hOutputSrdObj, &tSharedBuffMgrState) != S_OK)
	{
		timeout.tv_sec = 0;
		timeout.tv_usec = 10000;
		FD_ZERO(&fdsWrite);
		FD_SET(fdShardBuffer, &fdsWrite);

		iResult = select(fdShardBuffer + 1, NULL, &fdsWrite, NULL, &timeout);

		if (iResult <= 0) {
			DBPRINT0("Mp4V select timeout.... \n");
			return;
		}
		if (!FD_ISSET(fdShardBuffer, &fdsWrite))
			return;
		if (ptEncoderInfo->pfnRequestOutputBuffer(ptEncoderInfo->hOutputSrdObj, &tSharedBuffMgrState) != S_OK)
			return;
	}

	ptubcMP4V = (TUBufferConfMP4V *)(tSharedBuffMgrState.pbyHdrAddr);
	pbyBuffer = (BYTE*)tSharedBuffMgrState.pbyHdrAddr;
	memset(ptubcMP4V, 0, sizeof(TUBufferConfMP4V));

	scResult = Mp4VEnc_SpecificConfig(hMp4VEncObj, 
			pbyBuffer + sizeof(TUBufferConfMP4V), 
			&dwSpecConfSize, &dwProfileLevel,
			32 * 1024 - sizeof(TUBufferConfMP4V));
	assert(scResult == S_OK);
	ptubcMP4V->dwSize = sizeof(TUBufferConfMP4V) + dwSpecConfSize;
	ptubcMP4V->dwDataType = FOURCC_CONF;
	ptubcMP4V->dwFollowingDataType = FOURCC_MP4V;    
	ptubcMP4V->dwTrackID = 1;
	ptubcMP4V->dwWidth  = g_avfInfo[vFormat].wEncWidth;            
	ptubcMP4V->dwHeight = g_avfInfo[vFormat].wEncHeight;
	ptubcMP4V->dwProfileLevel = dwProfileLevel;

	ptEncoderInfo->pfnReleaseOutputBuffer(ptEncoderInfo->hOutputSrdObj, &tSharedBuffMgrState);

	printf("header size %u, DecSpec size %u\n", sizeof(TUBufferConfMP4V), dwSpecConfSize);
	printf("spec size %u %u \n", ptubcMP4V->dwWidth, ptubcMP4V->dwHeight);
}
示例#3
0
static void sig_term(int sig)
{
    if (shutdown_pending == 1) {
        /* Um, is this _probably_ not an error, if the user has
         * tried to do a shutdown twice quickly, so we won't
         * worry about reporting it.
         */
        return;
    }
    shutdown_pending = 1;

    DBPRINT0 ("waiting for threads\n");
    while (wait_to_finish) {
        apr_thread_yield();
    }
    DBPRINT0 ("goodbye\n");
}
示例#4
0
/* ============================================================================================= */
SCODE Venc_Stop(HANDLE hVencObject)
{
    TVencInfo *ptVencInfo = (TVencInfo *)(hVencObject);
    DWORD	dwCurId;

	if (ptVencInfo->hMsgReaderObj != NULL) {
	    VencMessage_Stop(ptVencInfo->hMsgReaderObj);
		DBPRINT0("[VENC] Message handler stop\n");
	}
#if defined(_VMA_IBPE)
	if (ptVencInfo->hMotionProcObj != NULL) {
	    VencMotion_Stop(ptVencInfo->hMotionProcObj);
	    DBPRINT0("[VENC] Motion sending process stop\n");
	}
#endif
    for (dwCurId = 0; dwCurId < ptVencInfo->tVencCfgPath.dwEncoderTotalNum; dwCurId++) {
    	if (ptVencInfo->phEncoderProcObj[dwCurId] != NULL) {
	#if 0
		    VencEncoder_Stop(ptVencInfo->hEncoderProcObj[dwCurId]);
	#endif
		VencEncoder_Stop(ptVencInfo->phEncoderProcObj[dwCurId]);	
		    DBPRINT1("[VENC] Encoder process %u stop\n", dwCurId);
    	}
	}

#if defined(_VPL_VOC)
	if (ptVencInfo->hDisplayProcObj != NULL) {
	    VencDisplay_Stop(ptVencInfo->hDisplayProcObj);
	    DBPRINT0("[VENC] Display process stop\n");
	}
#endif

	if (ptVencInfo->hVideoInProcObj != NULL) {
	    VencVideoIn_Stop(ptVencInfo->hVideoInProcObj);
	    DBPRINT0("[VENC] VideoIn process stop\n");
	}

	if (ptVencInfo->hMasterProcObj != NULL) {
		VencMaster_Stop(ptVencInfo->hMasterProcObj);
		DBPRINT0("[VENC] Master process stop\n");
	}

    return S_OK;
}
示例#5
0
/* ============================================================================================= */
SCODE Venc_LoadConfig(HANDLE hVencObject)
{
    TVencInfo *ptVencInfo = (TVencInfo *)(hVencObject);

    // Load configurations and compare with current configurations to see if them are changed
    sem_wait(&(ptVencInfo->smOptions));
	if (XmlWrapper_ReadFile_UsrDefFunc(ptVencInfo->szConfigFile, ptVencInfo->hXMLWrapperObj, ptVencInfo) != S_OK) {
        fprintf(stderr, "[VENC] XmlWrapper reload config fail! \n");
        return S_FAIL;
    }

	if (XmlWrapper_Reset(ptVencInfo->hXMLWrapperObj) != S_OK)  {
		DBPRINT0("[VENC] XmlWrapper read config fail! \n");
		return S_FAIL;
	}
    sem_post(&(ptVencInfo->smOptions));
    return S_OK;
}
示例#6
0
static void perform_idle_server_maintenance(apr_pool_t *p)
{
    int i;
    int idle_count;
    worker_score *ws;
    int free_length;
    int free_slots[MAX_SPAWN_RATE];
    int last_non_dead;
    int total_non_dead;

    /* initialize the free_list */
    free_length = 0;

    idle_count = 0;
    last_non_dead = -1;
    total_non_dead = 0;

    for (i = 0; i < ap_threads_limit; ++i) {
        int status;

        if (i >= ap_max_workers_limit && free_length == idle_spawn_rate)
            break;
        ws = &ap_scoreboard_image->servers[0][i];
        status = ws->status;
        if (status == WORKER_DEAD) {
            /* try to keep children numbers as low as possible */
            if (free_length < idle_spawn_rate) {
                free_slots[free_length] = i;
                ++free_length;
            }
        }
        else if (status == WORKER_IDLE_KILL) {
            /* If it is already marked to die, skip it */
            continue;
        }
        else {
            /* We consider a starting server as idle because we started it
            * at least a cycle ago, and if it still hasn't finished starting
            * then we're just going to swamp things worse by forking more.
            * So we hopefully won't need to fork more if we count it.
            * This depends on the ordering of SERVER_READY and SERVER_STARTING.
            */
            if (status <= WORKER_READY) {
                ++ idle_count;
            }

            ++total_non_dead;
            last_non_dead = i;
        }
    }
    DBPRINT2("Total: %d Idle Count: %d  \r", total_non_dead, idle_count);
    ap_max_workers_limit = last_non_dead + 1;
    if (idle_count > ap_threads_max_free) {
        /* kill off one child... we use the pod because that'll cause it to
        * shut down gracefully, in case it happened to pick up a request
        * while we were counting
        */
        idle_spawn_rate = 1;
        ap_update_child_status_from_indexes(0, last_non_dead, WORKER_IDLE_KILL,
                                            (request_rec *) NULL);
        DBPRINT1("\nKilling idle thread: %d\n", last_non_dead);
    }
    else if (idle_count < ap_threads_min_free) {
        /* terminate the free list */
        if (free_length == 0) {
            /* only report this condition once */
            static int reported = 0;

            if (!reported) {
                ap_log_error(APLOG_MARK, APLOG_ERR, 0, ap_server_conf, APLOGNO(00220)
                    "server reached MaxRequestWorkers setting, consider"
                    " raising the MaxRequestWorkers setting");
                reported = 1;
            }
            idle_spawn_rate = 1;
        }
        else {
            if (idle_spawn_rate >= 8) {
                ap_log_error(APLOG_MARK, APLOG_INFO, 0, ap_server_conf, APLOGNO(00221)
                    "server seems busy, (you may need "
                    "to increase StartServers, or Min/MaxSpareServers), "
                    "spawning %d children, there are %d idle, and "
                    "%d total children", idle_spawn_rate,
                    idle_count, total_non_dead);
            }
            DBPRINT0("\n");
            for (i = 0; i < free_length; ++i) {
                DBPRINT1("Spawning additional thread slot: %d\n", free_slots[i]);
                make_child(ap_server_conf, free_slots[i]);
            }
            /* the next time around we want to spawn twice as many if this
            * wasn't good enough, but not if we've just done a graceful
            */
            if (hold_off_on_exponential_spawning) {
                --hold_off_on_exponential_spawning;
            }
            else if (idle_spawn_rate < MAX_SPAWN_RATE) {
                idle_spawn_rate *= 2;
            }
        }
    }
    else {
        idle_spawn_rate = 1;
    }
}
示例#7
0
/* ============================================================================================= */
SCODE Venc_Initial(HANDLE *phVencObject, TVencInitOpt tVencInitOpt)
{	
    TVencInfo *ptVencInfo = (TVencInfo *)malloc(sizeof(TVencInfo));
	TMasterInitOpt	tMasterInitOpt;
    TVideoInInitOpt tVideoInInitOpt;
    TEncoderInitOpt tEncoderInitOpt;
#if 0    
    TFRCtrlOptions tFRCtrlOptions;
#endif
#ifdef	_VMA_IBPE
	TMotionInitOpt	tMotionInitOpt;
#endif
#ifdef _VPL_VOC
	TDisplayInitOpt tDisplayInitOpt;
#endif	
	DWORD	dwBitStreamSize;
    DWORD	dwCurId;

    if (ptVencInfo == NULL) {
        return ERR_OUT_OF_MEMORY;
    }
    memset(ptVencInfo, 0, sizeof(TVencInfo));
    *phVencObject = (HANDLE)(ptVencInfo);

    if (tVencInitOpt.dwDevNum >= MAX_HW_CHANNELNUM) {
        DBPRINT1("[VENC] Error device number %u !!\n", tVencInitOpt.dwDevNum);
        DBPRINT1("[VENC] The Mozart only supports device 0~%d !!\n", (MAX_HW_CHANNELNUM-1));
        return S_FAIL;
    }
    DBPRINT1("[VENC] Device number %u !!\n", tVencInitOpt.dwDevNum);

    if (!tVencInitOpt.szConfigFile) {
        ptVencInfo->szConfigFile = DEFAULT_CONFIG_FILE;
    }
    else {
        ptVencInfo->szConfigFile = tVencInitOpt.szConfigFile;
    }

    if (access(ptVencInfo->szConfigFile, F_OK) != 0) {
        DBPRINT1("[VENC] Configuration file %s not exist!!\n", ptVencInfo->szConfigFile);
        return S_FAIL;
    }
    DBPRINT1("[VENC] Configuration file %s\n", ptVencInfo->szConfigFile);

    // Create semaphore for thread communicate with critical section variables
    if (sem_init(&(ptVencInfo->smOptions), 0, 1) != 0) {
    	return S_FAIL;
    }

	g_bTerminate = FALSE;

    // Initial memmgr
    if (VencApp_InitMemMgr(&(ptVencInfo->hMemMgrObj)) != S_OK) {
        fprintf(stderr, "[VENC] Initial MemMgr object fail !!\n");
        return S_FAIL;
    }

    // Initial XmlWrapper Instance 
    if (VencApp_InitXmlWrapper(&(ptVencInfo->hXMLWrapperObj)) != S_OK) {
        fprintf(stderr, "[VENC] Initial XMLWrapper object fail !!\n");
        return S_FAIL;
    }

	// read all process config setting about thread create
	if (VencApp_ParseVencConfig(ptVencInfo) != S_OK) {
        DBPRINT0("[VENC] parse venc config fail !!\n");
		return S_FAIL;
	}

	// parse all needed information like MaxFrameSize, CaptureSize ...
	if (VencApp_GetInitNeedInfo(ptVencInfo) != S_OK) {
        DBPRINT0("[VENC] get init need info fail !!\n");
		return S_FAIL;
	}
#if 0	
	#if defined(_MT9P031) ||  defined( _OV5653) || defined(_AR0331)
		//printf("[venc_app](%d)Hello!!\n",__LINE__);
		ptVencInfo->tCapabilityRec.dwVideoMaxWidth = ptVencInfo->tCapabilityRec.dwVideoCapWidth;
		ptVencInfo->tCapabilityRec.dwVideoMaxHeight = ptVencInfo->tCapabilityRec.dwVideoCapHeight;
	#endif
		
	#if defined(_5M2MSWITCH)
	   ptVencInfo->tCapabilityRec.dwVideoMaxWidth = 2560;
	   ptVencInfo->tCapabilityRec.dwVideoMaxHeight = 1920;
	#elif defined(_3M2MSWITCH)
	   ptVencInfo->tCapabilityRec.dwVideoMaxWidth = 2048;
	   ptVencInfo->tCapabilityRec.dwVideoMaxHeight = 1536;
	#endif		
#endif
#if !defined(_5M2MSWITCH) && !defined(_3M2MSWITCH)	   
	if (ptVencInfo->tCapabilityRec.dwVideoMaxWidth > ptVencInfo->tCapabilityRec.dwVideoCapWidth)
	{
		ptVencInfo->tCapabilityRec.dwVideoMaxWidth = ptVencInfo->tCapabilityRec.dwVideoCapWidth; 
	}
	
	if (ptVencInfo->tCapabilityRec.dwVideoMaxHeight > ptVencInfo->tCapabilityRec.dwVideoCapHeight)
	{
		ptVencInfo->tCapabilityRec.dwVideoMaxHeight = ptVencInfo->tCapabilityRec.dwVideoCapHeight;
	}
#endif
	
#if 1
	printf("[VENC] Capability - dwBufNum = %u\n", ptVencInfo->tCapabilityRec.dwBufNum);
	printf("[VENC] Capability - dwVideoMaxWidth = %u\n", ptVencInfo->tCapabilityRec.dwVideoMaxWidth);
	printf("[VENC] Capability - dwVideoMaxHeight = %u\n", ptVencInfo->tCapabilityRec.dwVideoMaxHeight);
	printf("[VENC] Capability - capture resolution W x H: %u x %u\n", ptVencInfo->tCapabilityRec.dwVideoCapWidth, ptVencInfo->tCapabilityRec.dwVideoCapHeight);
	printf("[VENC] Capability - sensor in resolution W x H: %u x %u\n", ptVencInfo->tCapabilityRec.dwVideoInWidth, ptVencInfo->tCapabilityRec.dwVideoInHeight);
	printf("[VENC] Capability - Interlace or Progressive? %s\n", (ptVencInfo->tCapabilityRec.bInterlaceScan)? "Interlace": "Progressive");
#endif


	// decide bitstream size here, match the past defined case
	if (ptVencInfo->tCapabilityRec.dwVideoMaxWidth >= 1280) {
		dwBitStreamSize = 1024 * 1024;
	} else {
		dwBitStreamSize = 720 * 480;
	}
    // Initial Video Master process
    if (ptVencInfo->tVencCfgPath.bMasterEnable == TRUE) {
	    tMasterInitOpt.dwDevNum = tVencInitOpt.dwDevNum;
	    tMasterInitOpt.dwCallbackInstance = (DWORD)ptVencInfo;
	    tMasterInitOpt.szConfigFile = ptVencInfo->tVencCfgPath.szMasterConfigFile;
	    tMasterInitOpt.hMemMgrObj = ptVencInfo->hMemMgrObj;
	    tMasterInitOpt.tInitNeedInfo.dwVideoMaxWidth = ptVencInfo->tCapabilityRec.dwVideoMaxWidth;
	    tMasterInitOpt.tInitNeedInfo.dwVideoMaxHeight = ptVencInfo->tCapabilityRec.dwVideoMaxHeight;
	    tMasterInitOpt.tInitNeedInfo.dwVideoCapWidth = ptVencInfo->tCapabilityRec.dwVideoCapWidth;
	    tMasterInitOpt.tInitNeedInfo.dwVideoCapHeight = ptVencInfo->tCapabilityRec.dwVideoCapHeight;
	    tMasterInitOpt.tInitNeedInfo.dwVideoInWidth = ptVencInfo->tCapabilityRec.dwVideoInWidth;
	    tMasterInitOpt.tInitNeedInfo.dwVideoInHeight = ptVencInfo->tCapabilityRec.dwVideoInHeight;
	    tMasterInitOpt.tInitNeedInfo.dwBufNum = ptVencInfo->tCapabilityRec.dwBufNum;
	    tMasterInitOpt.tInitNeedInfo.szSensorConfigFile = ptVencInfo->tVencCfgPath.szSensorConfigFile;
	    tMasterInitOpt.tInitNeedInfo.dwVICOutputDRAMLoc = ptVencInfo->tVencCfgPath.tDRAMParam.dwVICOutputDRAMLoc;
	    if (VencMaster_Initial(&(ptVencInfo->hMasterProcObj), tMasterInitOpt) != S_OK) {
	    	printf("[VENC] VencMaster_Initial fail !!\n");
	    	exit(0);
	    }
	   	printf("[VENC] VencMaster_Initial successful !!\n");
    }

	// Initial Video Input process
    if (ptVencInfo->tVencCfgPath.bVideoInEnable == TRUE) {
	    tVideoInInitOpt.dwDevNum = tVencInitOpt.dwDevNum;
	    tVideoInInitOpt.dwCallbackInstance = (DWORD)ptVencInfo;
	    tVideoInInitOpt.szConfigFile = ptVencInfo->tVencCfgPath.szVideoInConfigFile;
	    tVideoInInitOpt.hMemMgrObj = ptVencInfo->hMemMgrObj;
	    VencMaster_GetVideoCapHandle(ptVencInfo->hMasterProcObj, &tVideoInInitOpt.hVideoCapObj);
	    VencMaster_GetUARTIRCutFD(ptVencInfo->hMasterProcObj, &tVideoInInitOpt.fdIRCutUART);
	    VencMaster_GetIRCutFD(ptVencInfo->hMasterProcObj, &tVideoInInitOpt.fdIRCut);
	    tVideoInInitOpt.dwSharedBufferMinorNum = ptVencInfo->tVencCfgPath.dwSharedBufferMinorNum;
	    tVideoInInitOpt.tInitNeedInfo.dwVideoMaxWidth = ptVencInfo->tCapabilityRec.dwVideoMaxWidth;
	    tVideoInInitOpt.tInitNeedInfo.dwVideoMaxHeight = ptVencInfo->tCapabilityRec.dwVideoMaxHeight;
	    tVideoInInitOpt.tInitNeedInfo.dwVideoCapWidth = ptVencInfo->tCapabilityRec.dwVideoCapWidth;
	    tVideoInInitOpt.tInitNeedInfo.dwVideoCapHeight = ptVencInfo->tCapabilityRec.dwVideoCapHeight;
	    tVideoInInitOpt.tInitNeedInfo.dwVideoInWidth = ptVencInfo->tCapabilityRec.dwVideoInWidth;
	    tVideoInInitOpt.tInitNeedInfo.dwVideoInHeight = ptVencInfo->tCapabilityRec.dwVideoInHeight;
	    tVideoInInitOpt.tInitNeedInfo.dwLDCRefFrameDRAMLoc = ptVencInfo->tVencCfgPath.tDRAMParam.dwLDCRefFrameDRAMLoc;
	    tVideoInInitOpt.tInitNeedInfo.dwDMACOutputDRAMLoc = ptVencInfo->tVencCfgPath.tDRAMParam.dwDMACOutputDRAMLoc;
		tVideoInInitOpt.tInitNeedInfo.dwVICOutputDRAMLoc = ptVencInfo->tVencCfgPath.tDRAMParam.dwVICOutputDRAMLoc;
		if (ptVencInfo->tVencCfgPath.bDisplayEnable == TRUE)
		{
			tVideoInInitOpt.dwOutputSharedBufferNum = 9;
		}
		else
		{
			tVideoInInitOpt.dwOutputSharedBufferNum = 4;
		}
		if (VencVideoIn_Initial(&(ptVencInfo->hVideoInProcObj), tVideoInInitOpt) != S_OK) {
	    	printf("[VENC] VencVideoIn_Initial fail !!\n");
	    	exit(0);
	    }
	  
	    printf("[VENC] VencVideoIn_Initial successful !!\n");
	}

    ptVencInfo->phEncoderProcObj = (HANDLE *)malloc(sizeof(HANDLE)*ptVencInfo->tVencCfgPath.dwEncoderTotalNum);
    for (dwCurId = 0; dwCurId < ptVencInfo->tVencCfgPath.dwEncoderTotalNum ; dwCurId++)
    {
		ptVencInfo->phEncoderProcObj[dwCurId]=NULL;
    }
    // Initial Video Encoder process
    for (dwCurId = 0; dwCurId < ptVencInfo->tVencCfgPath.dwEncoderTotalNum; dwCurId++) {
	    tEncoderInitOpt.hMemMgrObj = ptVencInfo->hMemMgrObj;
	    tEncoderInitOpt.dwCallbackInstance = (DWORD)ptVencInfo;
	    tEncoderInitOpt.dwSharedBufferMinorNum = ptVencInfo->tVencCfgPath.dwSharedBufferMinorNum;
	    tEncoderInitOpt.szConfigFile = ptVencInfo->tVencCfgPath.pszEncoderConfigFile[dwCurId];
	    tEncoderInitOpt.dwCurId = dwCurId;
		tEncoderInitOpt.dwVideoResolutionFormatIndex = vfUserDef1 + dwCurId;
		if (tEncoderInitOpt.dwVideoResolutionFormatIndex == vfNum)
		{
			tEncoderInitOpt.dwVideoResolutionFormatIndex = vfUserDef1;
			printf("[VENC][Warnning][encoder %d] The video resolution format index is upper bound!! Reset as %d\n", dwCurId, vfUserDef1);
		}
	    tEncoderInitOpt.tInitNeedInfo.dwVideoMaxWidth = ptVencInfo->tCapabilityRec.dwVideoMaxWidth;
	    tEncoderInitOpt.tInitNeedInfo.dwVideoMaxHeight = ptVencInfo->tCapabilityRec.dwVideoMaxHeight;
	 
	    tEncoderInitOpt.tInitNeedInfo.dwVideoCapWidth = ptVencInfo->tCapabilityRec.dwVideoCapWidth;
	    tEncoderInitOpt.tInitNeedInfo.dwVideoCapHeight = ptVencInfo->tCapabilityRec.dwVideoCapHeight;
	    tEncoderInitOpt.tInitNeedInfo.dwBitStreamSize = dwBitStreamSize;
	    tEncoderInitOpt.tInitNeedInfo.dwIREOutput0DRAMLoc = ptVencInfo->tVencCfgPath.tDRAMParam.dwIREOutput0DRAMLoc;
	    tEncoderInitOpt.tInitNeedInfo.dwIREOutput1DRAMLoc = ptVencInfo->tVencCfgPath.tDRAMParam.dwIREOutput1DRAMLoc;
	    tEncoderInitOpt.tInitNeedInfo.dwBitStreamOutputDRAMLoc = ptVencInfo->tVencCfgPath.tDRAMParam.dwBitStreamOutputDRAMLoc;
	    tEncoderInitOpt.tInitNeedInfo.dwMp4VBusNum = ptVencInfo->tVencCfgPath.tDRAMParam.dwMp4VBusNum;
	    tEncoderInitOpt.tInitNeedInfo.dwH264BusNum = ptVencInfo->tVencCfgPath.tDRAMParam.dwH264BusNum;
	    tEncoderInitOpt.tInitNeedInfo.dwSVCBusNum = ptVencInfo->tVencCfgPath.tDRAMParam.dwSVCBusNum;
	    tEncoderInitOpt.tInitNeedInfo.bInterlaceScan = ptVencInfo->tCapabilityRec.bInterlaceScan;
	    tEncoderInitOpt.tInitNeedInfo.dwMaxCapFrameRate = ptVencInfo->tCapabilityRec.dwMaxCapFrameRate;
	    tEncoderInitOpt.tInitNeedInfo.bCMOSSensor = ptVencInfo->tCapabilityRec.bCMOSSensor;
	    tEncoderInitOpt.tInitNeedInfo.dwVideoCodecInitMask = ptVencInfo->tCapabilityRec.dwVideoCodecInitMask;
		#if 0
	    if (VencEncoder_Initial(&(ptVencInfo->hEncoderProcObj[dwCurId]), tEncoderInitOpt) != S_OK) {
	    	printf("[VENC] VencEncoder_Initial fail !!\n");
	    	exit(0);
	    }
		#endif	
		if (VencEncoder_Initial(&(ptVencInfo->phEncoderProcObj[dwCurId]), tEncoderInitOpt) != S_OK) {
	    	printf("[VENC] VencEncoder_Initial fail !!\n");
	    	exit(0);
	    }
		//printf("[VENC_APP](%d)ptVencInfo->phEncoderProcObj[%d]=%p\n",__LINE__,dwCurId,ptVencInfo->phEncoderProcObj[dwCurId]);
		
	   	printf("[VENC] VencEncoder_Initial successful !!\n");
		
    }
    #if 0
	for (dwCurId = 0; dwCurId < ptVencInfo->tVencCfgPath.dwEncoderTotalNum; dwCurId++) {
		printf("[VENC_APP](%d) ptVencInfo->phEncoderProcObj[%d]=%p\n",__LINE__,dwCurId,ptVencInfo->phEncoderProcObj[dwCurId]);
	}
#endif


#if defined(_VMA_IBPE)
	// Initial Motion Sending process
    if (ptVencInfo->tVencCfgPath.bMotionEnable == TRUE) {
	    tMotionInitOpt.dwCallbackInstance = (DWORD)ptVencInfo;
	    tMotionInitOpt.szConfigFile = ptVencInfo->tVencCfgPath.szMotionConfigFile;
	    tMotionInitOpt.hMemMgrObj = ptVencInfo->hMemMgrObj;
	    tMotionInitOpt.dwSharedBufferMinorNum = ptVencInfo->tVencCfgPath.dwSharedBufferMinorNum;
	    tMotionInitOpt.tInitNeedInfo.dwVideoMaxWidth = ptVencInfo->tCapabilityRec.dwVideoMaxWidth;
	    tMotionInitOpt.tInitNeedInfo.dwVideoMaxHeight = ptVencInfo->tCapabilityRec.dwVideoMaxHeight;
	    tMotionInitOpt.tInitNeedInfo.dwVideoCapWidth = ptVencInfo->tCapabilityRec.dwVideoCapWidth;
	    tMotionInitOpt.tInitNeedInfo.dwVideoCapHeight = ptVencInfo->tCapabilityRec.dwVideoCapHeight;
	    tMotionInitOpt.tInitNeedInfo.dwBitStreamSize = dwBitStreamSize;
	    tMotionInitOpt.tInitNeedInfo.dwMotionSnapshotOutputDRAMLoc = ptVencInfo->tVencCfgPath.tDRAMParam.dwMotionSnapshotOutputDRAMLoc;
	    tMotionInitOpt.tInitNeedInfo.dwVideoCodecInitMask = ptVencInfo->tCapabilityRec.dwVideoCodecInitMask;	
		if (VencMotion_Initial(&(ptVencInfo->hMotionProcObj), tMotionInitOpt) != S_OK) {
	    	printf("[VENC] VencMotion_Initial fail !!\n");
	    	exit(0);
	    }
	   	printf("[VENC] VencMotion_Initial successful !!\n");
	}
#endif

#if defined(_VPL_VOC)
	// Initial Video Display process
    if (ptVencInfo->tVencCfgPath.bDisplayEnable == TRUE) {
	    tDisplayInitOpt.dwDevNum = tVencInitOpt.dwDevNum;
	    tDisplayInitOpt.dwCallbackInstance = (DWORD)ptVencInfo;
	    tDisplayInitOpt.dwSharedBufferMinorNum = ptVencInfo->tVencCfgPath.dwSharedBufferMinorNum;
	    tDisplayInitOpt.szConfigFile = ptVencInfo->tVencCfgPath.szDisplayConfigFile;
	    tDisplayInitOpt.hMemMgrObj = ptVencInfo->hMemMgrObj;
	    tDisplayInitOpt.tInitNeedInfo.dwVideoMaxWidth = ptVencInfo->tCapabilityRec.dwVideoMaxWidth;
	    tDisplayInitOpt.tInitNeedInfo.dwVideoMaxHeight = ptVencInfo->tCapabilityRec.dwVideoMaxHeight;
	    tDisplayInitOpt.tInitNeedInfo.dwVideoCapWidth = ptVencInfo->tCapabilityRec.dwVideoCapWidth;
	    tDisplayInitOpt.tInitNeedInfo.dwVideoCapHeight = ptVencInfo->tCapabilityRec.dwVideoCapHeight;
	    tDisplayInitOpt.tInitNeedInfo.dwVideoInWidth = ptVencInfo->tCapabilityRec.dwVideoInWidth;
	    tDisplayInitOpt.tInitNeedInfo.dwVideoInHeight = ptVencInfo->tCapabilityRec.dwVideoInHeight;
	    tDisplayInitOpt.tInitNeedInfo.dwVOCOutputDRAMLoc = ptVencInfo->tVencCfgPath.tDRAMParam.dwVOCOutputDRAMLoc;
	    if (VencDisplay_Initial(&(ptVencInfo->hDisplayProcObj), tDisplayInitOpt) != S_OK) {
	    	printf("[VENC] VencDisplay_Initial fail !!\n");
	    	exit(0);
	    }
	   	printf("[VENC] VencDisplay_Initial successful !!\n");
	}
#endif
	
    Venc_LoadConfig(ptVencInfo);

    if (tVencInitOpt.szCommandFIFO == NULL) {
        tVencInitOpt.szCommandFIFO = DEFAULT_COMMAND_FIFO;
    }
	DBPRINT1("[VENC] CommandFIFO path = %s\n", tVencInitOpt.szCommandFIFO);

	// Initial Message process
    VencMessage_Initial(ptVencInfo, tVencInitOpt.szCommandFIFO);

    return S_OK;
}
示例#8
0
/* ============================================================================================= */
SCODE Venc_Release(HANDLE *phVencObject)
{
    TVencInfo *ptVencInfo = (TVencInfo *)(*phVencObject);
    DWORD	dwCurId;
	
	if (ptVencInfo->hMsgReaderObj != NULL) 
	{
		VencMessage_Release(&ptVencInfo->hMsgReaderObj);
	}
	
	for (dwCurId = 0; dwCurId < ptVencInfo->tVencCfgPath.dwEncoderTotalNum; dwCurId++) 
	{
		if (ptVencInfo->phEncoderProcObj[dwCurId] != NULL) {
		    VencEncoder_Release(&ptVencInfo->phEncoderProcObj[dwCurId]);
		    DBPRINT1("[VENC] Encoder process %u release\n", dwCurId);
		}
	}

	for (dwCurId = 0; dwCurId < ptVencInfo->tVencCfgPath.dwEncoderTotalNum; dwCurId++) 
	{
		if (ptVencInfo->tVencCfgPath.pszEncoderConfigFile[dwCurId] != NULL)
		{
			free(ptVencInfo->tVencCfgPath.pszEncoderConfigFile[dwCurId]);		
			ptVencInfo->tVencCfgPath.pszEncoderConfigFile[dwCurId]=NULL;
		}
	}
	if (ptVencInfo->tVencCfgPath.pszEncoderConfigFile != NULL)
	{
		free(ptVencInfo->tVencCfgPath.pszEncoderConfigFile);
		ptVencInfo->tVencCfgPath.pszEncoderConfigFile = NULL;
	}

	if (ptVencInfo->pdwCurrSwitch != NULL)
	{
		free(ptVencInfo->pdwCurrSwitch);
		ptVencInfo->pdwCurrSwitch = NULL;
	}
	if (ptVencInfo->tVencCfgPath.szCapabilityPath != NULL)
	{
	    free(ptVencInfo->tVencCfgPath.szCapabilityPath);
	    ptVencInfo->tVencCfgPath.szCapabilityPath = NULL;
	}
	if (ptVencInfo->tVencCfgPath.szSensorConfigFile != NULL)
	{
	    free(ptVencInfo->tVencCfgPath.szSensorConfigFile);
	    ptVencInfo->tVencCfgPath.szSensorConfigFile = NULL;
	}
	if (ptVencInfo->tVencCfgPath.szMasterConfigFile != NULL)
	{
	    free(ptVencInfo->tVencCfgPath.szMasterConfigFile);
	    ptVencInfo->tVencCfgPath.szMasterConfigFile = NULL;
	}
	
	if (ptVencInfo->tVencCfgPath.szMotionConfigFile != NULL)
	{
	    free(ptVencInfo->tVencCfgPath.szMotionConfigFile);
	    ptVencInfo->tVencCfgPath.szMotionConfigFile = NULL;
	}
	
	if (ptVencInfo->tVencCfgPath.szDisplayConfigFile != NULL)
	{
		free( ptVencInfo->tVencCfgPath.szDisplayConfigFile);
		ptVencInfo->tVencCfgPath.szDisplayConfigFile = NULL;
	}
	
	if (ptVencInfo->tVencCfgPath.szVideoInConfigFile != NULL)
	{
		free(ptVencInfo->tVencCfgPath.szVideoInConfigFile);
		ptVencInfo->tVencCfgPath.szVideoInConfigFile = NULL;
	}
	
	
#if defined(_VMA_IBPE)
	if (ptVencInfo->hMotionProcObj != NULL) {
    	VencMotion_Release(&ptVencInfo->hMotionProcObj);
    	DBPRINT0("[VENC] Motion sending process release\n");	
	}
#endif
#if defined(_VPL_VOC)
	if (ptVencInfo->hDisplayProcObj != NULL) {
	    VencDisplay_Release(&ptVencInfo->hDisplayProcObj);
	    DBPRINT0("[VENC] Display process release\n");
	}
#endif
	if (ptVencInfo->tCapabilityRec.szSensorName != NULL )
	{
		free(ptVencInfo->tCapabilityRec.szSensorName);
		ptVencInfo->tCapabilityRec.szSensorName = NULL;
		DBPRINT0("[VENC] ptVencInfo->tCapabilityRec.szSensorName release\n");
	}
	if (ptVencInfo->hVideoInProcObj != NULL) {
	    VencVideoIn_Release(&ptVencInfo->hVideoInProcObj);
	    DBPRINT0("[VENC] VideoIn process release\n");
	}

	if (ptVencInfo->hMasterProcObj != NULL) {
		VencMaster_Release(&ptVencInfo->hMasterProcObj);
	    DBPRINT0("[VENC] Master process release\n");
	}
    
	// release Venc initial parts, it should be release last
	if (ptVencInfo->hXMLWrapperObj != NULL)
		XmlWrapper_Release(&(ptVencInfo->hXMLWrapperObj));

	if (ptVencInfo->hMemMgrObj != NULL)
		MemMgr_Release(&ptVencInfo->hMemMgrObj);
	
	sem_destroy(&(ptVencInfo->smOptions));
	
	if (ptVencInfo) free(ptVencInfo);
	
	*phVencObject = NULL;
  
    return S_OK;
}
示例#9
0
/* ============================================================================================= */
void* VencMaster_Loop(HANDLE hInstance)
{
	TMasterInfo *ptMasterInfo = (TMasterInfo *)hInstance;
#if defined(_AUTOSCENE_)
	static BOOL bPreAutoSceneIsRun = (BOOL)(-1);
#endif
	syslog(LOG_INFO, "[VENC_MASTER] venc_master thread pid: %d\n", getpid());

	// or using default (join)? think about it
	pthread_detach(pthread_self());

	while(1) {
		sem_wait(&(ptMasterInfo->smStart));
		if (ptMasterInfo->bTerminateThread == TRUE)     break;

		DBPRINT0("[VENC_MASTER] VideoMaster Loop Start\n");

		while (ptMasterInfo->bRunning == TRUE) {
			// think about it
			//bReConf_flag should set to true when first running

			if (ptMasterInfo->bReMsg_flag == TRUE) {
				sem_wait(&(ptMasterInfo->smMsgOptions));
				VencMaster_MsgApplyOpt(ptMasterInfo);
				ptMasterInfo->bReMsg_flag = FALSE;
				sem_post(&(ptMasterInfo->smMsgOptions));
			}
#if defined(_AUTOSCENE_)
			if (bPreAutoSceneIsRun != ptMasterInfo->bAutoSceneIsRun)
			{
					if (ptMasterInfo->bAutoSceneIsRun == FALSE)
					{
						VencMaster_InitConfigParam(ptMasterInfo);
					}
					
					bPreAutoSceneIsRun = ptMasterInfo->bAutoSceneIsRun;
					
					printf("[venc_master_process](%d)AutoScene is run? %s\n",__LINE__,ptMasterInfo->bAutoSceneIsRun?"TRUE":"FALSE");
			}	
#endif
			
			if (ptMasterInfo->bReConf_flag == TRUE) {
				sem_wait(&(ptMasterInfo->smOptions));
				VencMaster_LoadConfig(hInstance);
				ptMasterInfo->bReConf_flag = FALSE;
				sem_post(&(ptMasterInfo->smOptions));
			}

			if (ptMasterInfo->bResPLReconfig == TRUE) {
				VencMaster_ResPLSetoptions(ptMasterInfo);
				ptMasterInfo->bResPLReconfig = FALSE;
				//printf("[VENC_MASTER] Resolution and Power Line reset\n");
			}
#if 1
			if (ptMasterInfo->bWBReconfig == TRUE) {
				VencMaster_WBSetoptions(ptMasterInfo);
				ptMasterInfo->bWBReconfig = FALSE;
				//printf("[VENC_MASTER] White Balance reset\n");
			}
#endif

			if (ptMasterInfo->bCCReconfig == TRUE) {
				VencMaster_CCSetoptions(ptMasterInfo);
				ptMasterInfo->bCCReconfig = FALSE;
				//printf("[VENC_MASTER] Color correction reset\n");
			}

			if (ptMasterInfo->bTMReconfig == TRUE) {
				VencMaster_TMSetoptions(ptMasterInfo);
				ptMasterInfo->bTMReconfig = FALSE;
				//printf("[VENC_MASTER] Tone Mapping reset\n");
			}

			if (ptMasterInfo->bBlackClampReconfig == TRUE){

				VencMaster_BlackCalmpSetoptions(ptMasterInfo);
				ptMasterInfo->bBlackClampReconfig = FALSE;
				//printf("[VENC_MASTER] Black Clamp reset!!\n");
			}

			if (ptMasterInfo->bDeImpulseReconfig == TRUE){

				VencMaster_DeImpulseSetoptions(ptMasterInfo);
				ptMasterInfo->bDeImpulseReconfig = FALSE;
				//printf("[VENC_MASTER] De-Impulse reset!!\n");
			}
#if defined(_AUTOSCENE_)            
			if (ptMasterInfo->bAutoSceneIsRun == FALSE)
			{
#endif
				if (ptMasterInfo->bCEReconfig == TRUE) {
					VencMaster_CESetoptions(ptMasterInfo);
					ptMasterInfo->bCEReconfig = FALSE;
					//printf("[VENC_MASTER] Contrast Enhancement reset\n");
				}

#if defined(_AUTOSCENE_)  
			}
#endif 
			if (ptMasterInfo->bImgAdjReconfig == TRUE) {
				VencMaster_ImgAdjSetoptions(ptMasterInfo);
				ptMasterInfo->bImgAdjReconfig = FALSE;
				//printf("[VENC_MASTER] Image Adjustment reset\n");
			}
#if 1             
#if defined(_AUTOSCENE_)            
			if (ptMasterInfo->bAutoSceneIsRun == FALSE)
			{
#endif
				if (ptMasterInfo->bGammaTableReconfig == TRUE) {
					VencMaster_GammaTableSetoptions(ptMasterInfo);
					ptMasterInfo->bGammaTableReconfig = FALSE;
					//printf("[VENC_MASTER] Gamma Table reset\n");
				}
#if defined(_AUTOSCENE_)  
			}
#endif
			if (ptMasterInfo->bAEReconfig == TRUE) {
				VencMaster_AESetoptions(ptMasterInfo);
				ptMasterInfo->bAEReconfig = FALSE;
				//printf("[VENC_MASTER] AE reconfig\n");
			}
			
			if (ptMasterInfo->bAFReconfig == TRUE) {
				VencMaster_AFSetoptions(ptMasterInfo);
				ptMasterInfo->bAFReconfig = FALSE;
				//printf("[VENC_MASTER] AF reconfig\n");
			}
			
			if ((ptMasterInfo->tWDRStatus.bModified == TRUE) || (ptMasterInfo->bWDRReconfig == TRUE)) {
				VencMaster_WDRSetoptions(ptMasterInfo);
				if (ptMasterInfo->tWDRStatus.bModified == TRUE) {
					ptMasterInfo->tWDRStatus.bModified = FALSE;
				}
				if (ptMasterInfo->bWDRReconfig == TRUE) {
					ptMasterInfo->bWDRReconfig = FALSE;
				}
				//printf("[VENC_MASTER] WDR reconfig\n");
			}

			if (ptMasterInfo->tAFStatus.bModified == TRUE) {
				//printf("[VENC_MASTER]AF control now is %s .\n",ptMasterInfo->tAFStatus.bEnable ? "enabled" : "diabled");
				ptMasterInfo->tAFStatus.bModified = FALSE;
			}

			if (ptMasterInfo->tAFZoom.bModified || ptMasterInfo->tAFFocus.bModified) {
				//printf("[VENC_MASTER]AF control now from msgctrl.\n");
				VencMaster_AFSetoptionsFromMsgCtrl(ptMasterInfo);
				if (ptMasterInfo->tAFZoom.bModified == TRUE) {
					ptMasterInfo->tAFZoom.bModified = FALSE;
				}

				if (ptMasterInfo->tAFFocus.bModified == TRUE) {
					ptMasterInfo->tAFFocus.bModified = FALSE;
				}
			}
#endif			
			sem_wait(&(ptMasterInfo->smWakeup));
		}

		ptMasterInfo->bExitInnerLoop = TRUE;

		DBPRINT0("[VENC_MASTER] Video Master Exit inner loop\n");
	}

	sem_post(&(ptMasterInfo->smEnd));
	DBPRINT0("[VENC_MASTER] Master Exit thread\n");

	return 0;
}
示例#10
0
/* ========================================================================== */
void VencEncoder_Mp4VApplyOpt(HANDLE hObject)
{
    TEncoderInfo *ptEncoderInfo = (TEncoderInfo *) hObject;
	SCODE scRet;
	TMp4VOptRec *ptMp4VOptRec = &(ptEncoderInfo->tMp4VOptRec);
	TMp4VEncOptions tMp4VEncOpt;    

	if (ptMp4VOptRec->bQualityGroup == TRUE) {
		if (ptMp4VOptRec->dwBitrate > 0)
		{
			tMp4VEncOpt.eOptionFlags = VIDEO_CHANGE_BITRATE;
			tMp4VEncOpt.adwUserData[0] = ptMp4VOptRec->dwBitrate;
			if (ptEncoderInfo->hMp4VEncObj != NULL)
			{
				scRet = Mp4VEnc_SetOptions(ptEncoderInfo->hMp4VEncObj, &tMp4VEncOpt);
				assert(scRet == S_OK);

				DBPRINT1("[VENC_ENCODER] Set MPEG4 Bitrate %u\n", tMp4VEncOpt.adwUserData[0]);
			}

			tMp4VEncOpt.eOptionFlags = VIDEO_SET_RATE_CONTROL; 
			tMp4VEncOpt.adwUserData[0] = ptMp4VOptRec->ercfMPEG4QualityType;
			if (ptEncoderInfo->hMp4VEncObj!=NULL)
			{
				scRet = Mp4VEnc_SetOptions(ptEncoderInfo->hMp4VEncObj, &tMp4VEncOpt);
				assert(scRet == S_OK);

				DBPRINT1("[VENC_ENCODER] Set MPEG4 RateCtrl: %d\n", tMp4VEncOpt.adwUserData[0]);
			}
		}
		ptMp4VOptRec->bBitrate = FALSE;
		ptMp4VOptRec->bSetRateControl = FALSE;

		//	    if (ptMp4VOptRec->bQuant == TRUE) { // Venc_SlaveApp_SetMPEG4Quant
		tMp4VEncOpt.eOptionFlags = VIDEO_CHANGE_QUANT;        
		tMp4VEncOpt.adwUserData[0] = ptMp4VOptRec->dwQuant;
		if (ptEncoderInfo->hMp4VEncObj != NULL) 
		{
			scRet = Mp4VEnc_SetOptions(ptEncoderInfo->hMp4VEncObj, &tMp4VEncOpt);
			assert(scRet == S_OK);

			DBPRINT1("[VENC_ENCODER] Set MPEG4 Quant %u\n",tMp4VEncOpt.adwUserData[0]);
		}
		ptMp4VOptRec->bQuant = FALSE;
		//	    }
		ptMp4VOptRec->bQualityGroup = FALSE;
	}

	if (ptMp4VOptRec->bForceIntra == TRUE) {
		tMp4VEncOpt.eOptionFlags = VIDEO_FORCE_INTRA;
		if (ptEncoderInfo->hMp4VEncObj != NULL)
		{
			scRet = Mp4VEnc_SetOptions(ptEncoderInfo->hMp4VEncObj, &tMp4VEncOpt);
			assert(scRet == S_OK);
			DBPRINT0("[VENC_ENCODER] Set MPEG4 ForceIntra\n");
		}
		ptMp4VOptRec->bForceIntra = FALSE;
	}

	if (ptMp4VOptRec->bIntraInterval == TRUE) {
		// call force intra first
		tMp4VEncOpt.eOptionFlags = VIDEO_FORCE_INTRA;
		if (ptEncoderInfo->hMp4VEncObj != NULL)
		{
			scRet = Mp4VEnc_SetOptions(ptEncoderInfo->hMp4VEncObj, &tMp4VEncOpt);
			assert(scRet == S_OK);
			DBPRINT0("[VENC_ENCODER] Set MPEG4 ForceIntra\n");
		}
		// call change interval
		tMp4VEncOpt.eOptionFlags = VIDEO_CHANGE_INTRA_INTERVAL;        
		tMp4VEncOpt.adwUserData[0] = ptMp4VOptRec->dwIntraInterval;
		if (ptEncoderInfo->hMp4VEncObj != NULL)
		{
			scRet = Mp4VEnc_SetOptions(ptEncoderInfo->hMp4VEncObj, &tMp4VEncOpt);
			assert(scRet == S_OK);
			DBPRINT1("[VENC_ENCODER] Set MPEG4 IntraInterval %u\n",tMp4VEncOpt.adwUserData[0]);
		}
		ptMp4VOptRec->bIntraInterval = FALSE;
	}
}