CODEC_STATE HantroHwEncOmx_encoder_frame_rate_vp8(ENCODER_PROTOTYPE* arg, OMX_U32 xFramerate)
{
    ENCODER_VP8* this = (ENCODER_VP8*)arg;

    this->nEstTimeInc = (OMX_U32) (TIME_RESOLUTION / Q16_FLOAT(xFramerate));

    return CODEC_OK;
}
示例#2
0
CODEC_STATE HantroHwEncOmx_encoder_frame_rate_mpeg4(ENCODER_PROTOTYPE* arg, OMX_U32 xFramerate)
{
    ENCODER_MPEG4* this = (ENCODER_MPEG4*)arg;

    this->nTickIncrement = (OMX_U32) (TIME_RESOLUTION_MPEG4 / Q16_FLOAT(xFramerate));

    return CODEC_OK;
}
// create codec instance and initialize it
ENCODER_PROTOTYPE* HantroHwEncOmx_encoder_create_vp8(const VP8_CONFIG* params)
{
    VP8EncConfig cfg;

    memset(&cfg,0,sizeof(VP8EncConfig));

    cfg.width = params->common_config.nOutputWidth;
    cfg.height = params->common_config.nOutputHeight;
    //cfg.frameRateDenom = 1;
    //cfg.frameRateNum = cfg.frameRateDenom * Q16_FLOAT(params->common_config.nInputFramerate);
    cfg.frameRateNum = TIME_RESOLUTION;
    cfg.frameRateDenom = cfg.frameRateNum / Q16_FLOAT(params->common_config.nInputFramerate);
    cfg.refFrameAmount = REFERENCE_FRAME_AMOUNT;

    ENCODER_VP8* this = OSAL_Malloc(sizeof(ENCODER_VP8));

    this->instance = 0;
    memset( &this->encIn, 0, sizeof(VP8EncIn));
    this->origWidth = params->pp_config.origWidth;
    this->origHeight = params->pp_config.origHeight;
    this->base.stream_start = encoder_stream_start_vp8;
    this->base.stream_end = encoder_stream_end_vp8;
    this->base.encode = encoder_encode_vp8;
    this->base.destroy = encoder_destroy_vp8;

    this->bStabilize = params->pp_config.frameStabilization;
    this->nIFrameCounter = 0;
    this->nEstTimeInc = cfg.frameRateDenom;

    VP8EncRet ret = VP8EncInit(&cfg, &this->instance);

    // Setup coding control
    if (ret == VP8ENC_OK)
    {
        VP8EncCodingCtrl coding_ctrl;
        ret = VP8EncGetCodingCtrl(this->instance, &coding_ctrl);

        if (ret == VP8ENC_OK)
        {
            coding_ctrl.filterLevel = VP8ENC_FILTER_LEVEL_AUTO;
            coding_ctrl.filterSharpness = VP8ENC_FILTER_SHARPNESS_AUTO;
            coding_ctrl.filterType = 0;

            switch (params->vp8_config.eLevel)
            {
                case OMX_VIDEO_VP8Level_Version0:
                    coding_ctrl.interpolationFilter = 0;
                    break;
                case OMX_VIDEO_VP8Level_Version1:
                    coding_ctrl.interpolationFilter = 1;
                    coding_ctrl.filterType = 1;
                    break;
                case OMX_VIDEO_VP8Level_Version2:
                    coding_ctrl.interpolationFilter = 1;
                    coding_ctrl.filterLevel = 0;
                    break;
                case OMX_VIDEO_VP8Level_Version3:
                    coding_ctrl.interpolationFilter = 2;
                    coding_ctrl.filterLevel = 0;
                    break;
                default:
                    printf("Invalid VP8 eLevel\n");
                    coding_ctrl.interpolationFilter = 0;
                    break;
            }

            coding_ctrl.dctPartitions = params->vp8_config.nDCTPartitions;
            coding_ctrl.errorResilient = params->vp8_config.bErrorResilientMode;
            coding_ctrl.quarterPixelMv = 1;

            ret = VP8EncSetCodingCtrl(this->instance, &coding_ctrl);

        }
    }

    // Setup rate control
    if (ret == VP8ENC_OK)
    {
        VP8EncRateCtrl rate_ctrl;
        ret = VP8EncGetRateCtrl(this->instance, &rate_ctrl);
        if (ret == VP8ENC_OK)
        {

            // Optional. Set to -1 to use default.
            if (params->rate_config.nPictureRcEnabled >= 0)
            {
                rate_ctrl.pictureRc = params->rate_config.nPictureRcEnabled;
            }

            // Optional settings. Set to -1 to use default.
            if (params->rate_config.nQpDefault >= 0)
            {
                rate_ctrl.qpHdr = params->rate_config.nQpDefault;
            }

            // Optional settings. Set to -1 to use default.
            if (params->rate_config.nQpMin >= 0)
            {
                rate_ctrl.qpMin = params->rate_config.nQpMin;
                if(rate_ctrl.qpHdr != -1 && rate_ctrl.qpHdr < rate_ctrl.qpMin)
                {
                    rate_ctrl.qpHdr = rate_ctrl.qpMin;
                }
            }

            // Optional settings. Set to -1 to use default.
            if (params->rate_config.nQpMax > 0)
            {
                rate_ctrl.qpMax = params->rate_config.nQpMax;
                if(rate_ctrl.qpHdr > rate_ctrl.qpMax)
                {
                    rate_ctrl.qpHdr = rate_ctrl.qpMax;
                }
            }

            // Optional. Set to -1 to use default.
            if (params->rate_config.nTargetBitrate >= 0)
            {
                rate_ctrl.bitPerSecond = params->rate_config.nTargetBitrate;
            }

            switch (params->rate_config.eRateControl)
            {
                case OMX_Video_ControlRateDisable:
                    rate_ctrl.pictureSkip = 0;
                    break;
                case OMX_Video_ControlRateVariable:
                    rate_ctrl.pictureSkip = 0;
                    break;
                case OMX_Video_ControlRateConstant:
                    rate_ctrl.pictureSkip = 0;
                    break;
                case OMX_Video_ControlRateVariableSkipFrames:
                    rate_ctrl.pictureSkip = 1;
                    break;
                case OMX_Video_ControlRateConstantSkipFrames:
                    rate_ctrl.pictureSkip = 1;
                    break;
                case OMX_Video_ControlRateMax:
                    rate_ctrl.pictureSkip = 0;
                    break;
                default:
                    break;
            }

            ret = VP8EncSetRateCtrl(this->instance, &rate_ctrl);
        }
    }

    // Setup preprocessing
    if (ret == VP8ENC_OK)
    {
        VP8EncPreProcessingCfg pp_config;

        ret = VP8EncGetPreProcessing(this->instance, &pp_config);

        // input image size
        pp_config.origWidth = params->pp_config.origWidth;
        pp_config.origHeight = params->pp_config.origHeight;

        // cropping offset
        pp_config.xOffset = params->pp_config.xOffset;
        pp_config.yOffset = params->pp_config.yOffset;

        switch (params->pp_config.formatType)
        {
            case OMX_COLOR_FormatYUV420PackedPlanar:
            case OMX_COLOR_FormatYUV420Planar:
                pp_config.inputType = VP8ENC_YUV420_PLANAR;
                break;
            case OMX_COLOR_FormatYUV420PackedSemiPlanar:
            case OMX_COLOR_FormatYUV420SemiPlanar:
                pp_config.inputType = VP8ENC_YUV420_SEMIPLANAR;
                break;
            case OMX_COLOR_FormatYCbYCr:
                pp_config.inputType = VP8ENC_YUV422_INTERLEAVED_YUYV;
                break;
            case OMX_COLOR_FormatCbYCrY:
                pp_config.inputType = VP8ENC_YUV422_INTERLEAVED_UYVY;
                break;
            case OMX_COLOR_Format16bitRGB565:
                pp_config.inputType = VP8ENC_RGB565;
                break;
            case OMX_COLOR_Format16bitBGR565:
                pp_config.inputType = VP8ENC_BGR565;
                break;
            case OMX_COLOR_Format12bitRGB444:
                pp_config.inputType = VP8ENC_RGB444;
                break;
            case OMX_COLOR_Format16bitARGB4444:
                pp_config.inputType = VP8ENC_RGB444;
                break;
            case OMX_COLOR_Format16bitARGB1555:
                pp_config.inputType = VP8ENC_RGB555;
                break;
            case OMX_COLOR_Format24bitRGB888:
            case OMX_COLOR_Format25bitARGB1888:
            case OMX_COLOR_Format32bitARGB8888:
                pp_config.inputType = VP8ENC_RGB888;
                break;
            case OMX_COLOR_Format24bitBGR888:
                pp_config.inputType = VP8ENC_BGR888;
                break;
            default:
                ret = VP8ENC_INVALID_ARGUMENT;
                break;
        }

        switch (params->pp_config.angle)
        {
            case 0:
                pp_config.rotation = VP8ENC_ROTATE_0;
                break;
            case 90:
                pp_config.rotation = VP8ENC_ROTATE_90R;
                break;
            case 270:
                pp_config.rotation = VP8ENC_ROTATE_90L;
                break;
            default:
                ret = VP8ENC_INVALID_ARGUMENT;
                break;
        }

        // Enables or disables the video stabilization function. Set to a non-zero value will
        // enable the stabilization. The input image dimensions (origWidth, origHeight)
        // have to be at least 8 pixels bigger than the final encoded image dimensions. Also when
        // enabled the cropping offset (xOffset, yOffset) values are ignored.
        this->bStabilize = params->pp_config.frameStabilization;
        pp_config.videoStabilization = params->pp_config.frameStabilization;

        if (ret == VP8ENC_OK)
        {
            ret = VP8EncSetPreProcessing(this->instance, &pp_config);
        }
    }

    if (ret != VP8ENC_OK)
    {
        OSAL_Free(this);
        return NULL;
    }

    return (ENCODER_PROTOTYPE*) this;
}
示例#4
0
// create codec instance and initialize it
ENCODER_PROTOTYPE* HantroHwEncOmx_encoder_create_mpeg4(const MPEG4_CONFIG* params)
{
    MP4EncCfg cfg;

    cfg.strmType = MPEG4_PLAIN_STRM;

    if (params->mp4_config.bSVH)
    {
        cfg.strmType = MPEG4_SVH_STRM;
    }
    else
    {
        if (params->mp4_config.bReversibleVLC)
        {
            cfg.strmType = MPEG4_VP_DP_RVLC_STRM;
        }
        else if (params->error_ctrl_config.bEnableDataPartitioning)
        {
            cfg.strmType = MPEG4_VP_DP_STRM;
        }
        else if (params->error_ctrl_config.bEnableResync)
        {
            cfg.strmType = MPEG4_VP_STRM;
        }
    }

	LOGV("---> init strmType = %d", cfg.strmType);

    // Find out correct profile and level
    switch (params->mp4_config.eProfile)
    {
        case OMX_VIDEO_MPEG4ProfileSimple:
        {
            switch (params->mp4_config.eLevel)
            {
                case OMX_VIDEO_MPEG4Level0:
                    cfg.profileAndLevel = MPEG4_SIMPLE_PROFILE_LEVEL_0;
                    break;
                case OMX_VIDEO_MPEG4Level0b:
                    cfg.profileAndLevel = MPEG4_SIMPLE_PROFILE_LEVEL_0B;
                    break;
                case OMX_VIDEO_MPEG4Level1:
                    cfg.profileAndLevel = MPEG4_SIMPLE_PROFILE_LEVEL_1;
                    break;
                case OMX_VIDEO_MPEG4Level2:
                    cfg.profileAndLevel = MPEG4_SIMPLE_PROFILE_LEVEL_2;
                    break;
                case OMX_VIDEO_MPEG4Level3:
                    cfg.profileAndLevel = MPEG4_SIMPLE_PROFILE_LEVEL_3;
                    break;
                case OMX_VIDEO_MPEG4Level4a:
                    cfg.profileAndLevel = MPEG4_SIMPLE_PROFILE_LEVEL_4A;
                    break;
                case OMX_VIDEO_MPEG4Level5:
                case OMX_VIDEO_MPEG4LevelMax:
                    cfg.profileAndLevel = MPEG4_SIMPLE_PROFILE_LEVEL_5;
                    break;
                default:
                    return NULL;
                    break;
            }
        }
        break;
        case OMX_VIDEO_MPEG4ProfileAdvancedRealTime:
        {
            switch (params->mp4_config.eLevel)
            {
                case OMX_VIDEO_MPEG4Level3:
                    cfg.profileAndLevel = MPEG4_ADV_SIMPLE_PROFILE_LEVEL_3;
                    break;
                case OMX_VIDEO_MPEG4Level4:
                    cfg.profileAndLevel = MPEG4_ADV_SIMPLE_PROFILE_LEVEL_4;
                    break;
                case OMX_VIDEO_MPEG4Level5:
                case OMX_VIDEO_MPEG4LevelMax:
                    cfg.profileAndLevel = MPEG4_ADV_SIMPLE_PROFILE_LEVEL_5;
                    break;
                default:
                    return NULL;
                    break;
            }
        }
        break;
        case OMX_VIDEO_MPEG4ProfileMain:
        case OMX_VIDEO_MPEG4ProfileMax:
        {
            switch (params->mp4_config.eLevel)
            {
                case OMX_VIDEO_MPEG4Level4:
                case OMX_VIDEO_MPEG4LevelMax:
                    cfg.profileAndLevel = MPEG4_MAIN_PROFILE_LEVEL_4;
                    break;
                default:
                    return NULL;
                    break;
            }
        }
        break;
        default:
            return NULL;
    }

    cfg.width = params->common_config.nOutputWidth;
    cfg.height = params->common_config.nOutputHeight;

    // The numerator part of the input frame rate. The frame rate is defined by the
    // frmRateNum/frmRateDenom ratio. This value is also used as the time resolution or
    // the number of subunits (ticks) within a second.
    // Valid value range: [1, 65535]
    cfg.frmRateNum = params->mp4_config.nTimeIncRes;

    // The denominator part of the input frame rate. This value has to be equal or less
    // than the numerator part frmRateNum.
    // Valid value range: [1, 65535]
    cfg.frmRateDenom = cfg.frmRateNum / Q16_FLOAT(params->common_config.nInputFramerate);

    ENCODER_MPEG4* this = OSAL_Malloc(sizeof(ENCODER_MPEG4));

    this->instance = 0;
    memset( &this->encIn, 0, sizeof(MP4EncIn));
    this->origWidth = params->pp_config.origWidth;
    this->origHeight = params->pp_config.origHeight;
    this->base.stream_start = encoder_stream_start_mpeg4;
    this->base.stream_end = encoder_stream_end_mpeg4;
    this->base.encode = encoder_encode_mpeg4;
    this->base.destroy = encoder_destroy_mpeg4;

    // calculate per frame tick increment
    this->nTickIncrement = cfg.frmRateDenom;

    MP4EncRet ret = MP4EncInit(&cfg, &this->instance);

    // Setup coding control
    if (ret == ENC_OK)
    {
        MP4EncCodingCtrl coding_ctrl;
        ret = MP4EncGetCodingCtrl(this->instance, &coding_ctrl);

        if (ret == ENC_OK)
        {
            // Header extension codes enable/disable
            // Not supported, use defaults.
            if (params->error_ctrl_config.bEnableHEC)
            {
                coding_ctrl.insHEC = 1;
            }
            else if (params->mp4_config.nHeaderExtension > 0)
            {
                coding_ctrl.insHEC = 1;
            }
            else
            {
                coding_ctrl.insHEC = 0;
            }

            // GOV header insertion enable/disable
            if ((params->mp4_config.bGov) && (params->mp4_config.nPFrames > 0))
            {
                coding_ctrl.insGOV = 0;
                this->bGovEnabled = OMX_TRUE;
            }
            else
            {
                coding_ctrl.insGOV = 0;
                this->bGovEnabled = OMX_FALSE;
            }
            this->nFrameCounter = 0;

            if (params->mp4_config.nPFrames > 0)
            {
                this->nPFrames = params->mp4_config.nPFrames;
            }

            // Video package (VP) size
            if (params->error_ctrl_config.nResynchMarkerSpacing > 0)
            {
                coding_ctrl.vpSize = params->error_ctrl_config.nResynchMarkerSpacing;
            }
            else if (params->mp4_config.nMaxPacketSize > 0)
            {
                coding_ctrl.vpSize = params->mp4_config.nMaxPacketSize;
            }
            // else use default value

            ret = MP4EncSetCodingCtrl(this->instance, &coding_ctrl);
        }
    }

    // Setup rate control
    if (ret == ENC_OK)
    {
        MP4EncRateCtrl rate_ctrl;
        ret = MP4EncGetRateCtrl(this->instance, &rate_ctrl);
        if (ret == ENC_OK)
        {
            rate_ctrl.gopLen = params->mp4_config.nPFrames;
            // Optional. Set to -1 to use default.
            if (params->rate_config.nPictureRcEnabled >= 0)
            {
                rate_ctrl.vopRc = params->rate_config.nPictureRcEnabled;
            }

            // Optional. Set to -1 to use default.
            if (params->rate_config.nMbRcEnabled >= 0)
            {
                rate_ctrl.mbRc = params->rate_config.nMbRcEnabled;
            }

            // Optional settings. Set to -1 to use default.
            if (params->rate_config.nQpDefault >= 0)
            {
                rate_ctrl.qpHdr = params->rate_config.nQpDefault;
            }

            // Optional settings. Set to -1 to use default.
            if (params->rate_config.nQpMin >= 0)
            {
                rate_ctrl.qpMin = params->rate_config.nQpMin;
                if(rate_ctrl.qpHdr != -1 && rate_ctrl.qpHdr < rate_ctrl.qpMin)
                {
                    rate_ctrl.qpHdr = rate_ctrl.qpMin;
                }
            }

            // Optional settings. Set to -1 to use default.
            if (params->rate_config.nQpMax > 0)
            {
                rate_ctrl.qpMax = params->rate_config.nQpMax;
                if(rate_ctrl.qpHdr > rate_ctrl.qpMax)
                {
                    rate_ctrl.qpHdr = rate_ctrl.qpMax;
                }
            }

            // Optional. Set to -1 to use default.
            if (params->rate_config.nTargetBitrate >= 0)
            {
                rate_ctrl.bitPerSecond = params->rate_config.nTargetBitrate;
            }

            // Optional. Set to -1 to use default.
            if (params->rate_config.nVbvEnabled >= 0)
            {
                rate_ctrl.vbv = params->rate_config.nVbvEnabled;
            }

            switch (params->rate_config.eRateControl)
            {
                case OMX_Video_ControlRateDisable:
                    rate_ctrl.vopSkip = 0;
                    break;
                case OMX_Video_ControlRateVariable:
                    rate_ctrl.vopSkip = 0;
                    break;
                case OMX_Video_ControlRateConstant:
                    rate_ctrl.vopSkip = 0;
                    break;
                case OMX_Video_ControlRateVariableSkipFrames:
                    rate_ctrl.vopSkip = 1;
                    break;
                case OMX_Video_ControlRateConstantSkipFrames:
                    rate_ctrl.vopSkip = 1;
                    break;
                case OMX_Video_ControlRateMax:
                    rate_ctrl.vopSkip = 0;
                    break;
                default:
                    break;
            }
            ret = MP4EncSetRateCtrl(this->instance, &rate_ctrl);
        }
    }

    // Setup preprocessing
    if (ret == ENC_OK)
    {
        MP4EncPreProcessingCfg pp_config;

        ret = MP4EncGetPreProcessing(this->instance, &pp_config);

        // input image size
        pp_config.origWidth = params->pp_config.origWidth;
        pp_config.origHeight = params->pp_config.origHeight;

        // cropping offset
        pp_config.xOffset = params->pp_config.xOffset;
        pp_config.yOffset = params->pp_config.yOffset;

        switch (params->pp_config.formatType)
        {
            case OMX_COLOR_FormatYUV420PackedPlanar:
            case OMX_COLOR_FormatYUV420Planar:
#ifdef ENC6280
        	pp_config.yuvType = ENC_YUV420_PLANAR;
#endif
#ifdef ENC7280
	        pp_config.inputType = ENC_YUV420_PLANAR;
#endif
                break;
            case OMX_COLOR_FormatYUV420PackedSemiPlanar:
            case OMX_COLOR_FormatYUV420SemiPlanar:
#ifdef ENC6280
            	pp_config.yuvType = ENC_YUV420_SEMIPLANAR;
#endif
#ifdef ENC7280
            	pp_config.inputType = ENC_YUV420_SEMIPLANAR;
#endif
                break;
            case OMX_COLOR_FormatYCbYCr:
#ifdef ENC6280
            	pp_config.yuvType = ENC_YUV422_INTERLEAVED_YUYV;
#endif
#ifdef ENC7280
            	pp_config.inputType = ENC_YUV422_INTERLEAVED_YUYV;
#endif
                break;
            case OMX_COLOR_FormatCbYCrY:
#ifdef ENC6280
            	pp_config.yuvType = ENC_YUV422_INTERLEAVED_UYVY;
#endif
#ifdef ENC7280
            	pp_config.inputType = ENC_YUV422_INTERLEAVED_UYVY;
#endif
                break;
            case OMX_COLOR_Format16bitRGB565:
#ifdef ENC6280
                pp_config.yuvType = ENC_RGB565;
#endif
#ifdef ENC7280
                pp_config.inputType = ENC_RGB565;
#endif
                break;
            case OMX_COLOR_Format16bitBGR565:
#ifdef ENC6280
                pp_config.yuvType = ENC_BGR565;
#endif
#ifdef ENC7280
                pp_config.inputType = ENC_BGR565;
#endif
                break;
            case OMX_COLOR_Format16bitARGB4444:
#ifdef ENC6280
                pp_config.yuvType = ENC_RGB444;
#endif
#ifdef ENC7280
                pp_config.inputType = ENC_RGB444;
#endif
                break;
            case OMX_COLOR_Format16bitARGB1555:
#ifdef ENC6280
                pp_config.yuvType = ENC_RGB555;
#endif
#ifdef ENC7280
                pp_config.inputType = ENC_RGB555;
#endif
                break;     
      
            default:
                ret = ENC_INVALID_ARGUMENT;
                break;
        }

        switch (params->pp_config.angle)
        {
            case 0:
                pp_config.rotation = ENC_ROTATE_0;
                break;
            case 90:
                pp_config.rotation = ENC_ROTATE_90R;
                break;
            case 270:
                pp_config.rotation = ENC_ROTATE_90L;
                break;
            default:
                ret = ENC_INVALID_ARGUMENT;
                break;
        }

        // Enables or disables the video stabilization function. Set to a non-zero value will
        // enable the stabilization. The input image’s dimensions (origWidth, origHeight)
        // have to be at least 8 pixels bigger than the final encoded image’s. Also when
        // enabled the cropping offset (xOffset, yOffset) values are ignored.
        this->bStabilize = params->pp_config.frameStabilization;
        pp_config.videoStabilization = params->pp_config.frameStabilization;

        if (ret == ENC_OK)
        {
            ret = MP4EncSetPreProcessing(this->instance, &pp_config);
        }
    }

    if (ret != ENC_OK)
    {
        OSAL_Free(this);
        return NULL;
    }

    return (ENCODER_PROTOTYPE*) this;
}