Пример #1
0
/*------------------------------------------------------------------------------
    OSAL_MutexCreate
------------------------------------------------------------------------------*/
OSAL_ERRORTYPE OSAL_MutexCreate(OSAL_PTR *phMutex)
{
    pthread_mutex_t *pMutex = (pthread_mutex_t *)
                                OSAL_Malloc(sizeof(pthread_mutex_t));
    static pthread_mutexattr_t oAttr;
    static pthread_mutexattr_t *pAttr = NULL;

    if (pAttr == NULL &&
        !pthread_mutexattr_init(&oAttr) &&
        !pthread_mutexattr_settype(&oAttr, PTHREAD_MUTEX_RECURSIVE))
    {
        pAttr = &oAttr;
    }

    if (pMutex == NULL)
    {
        LOGE("OSAL_ERROR_INSUFFICIENT_RESOURCES\n");
        return OSAL_ERROR_INSUFFICIENT_RESOURCES;
    }

    if (pthread_mutex_init(pMutex, pAttr)) {
        LOGE("OSAL_ERROR_INSUFFICIENT_RESOURCES\n");
        OSAL_Free(pMutex);
        return OSAL_ERROR_INSUFFICIENT_RESOURCES;
    }

    *phMutex = (void *)pMutex;
    return OSAL_ERRORNONE;
}
Пример #2
0
/*------------------------------------------------------------------------------
    OSAL_EventCreate
------------------------------------------------------------------------------*/
OSAL_ERRORTYPE OSAL_EventCreate(OSAL_PTR *phEvent)
{
    OSAL_THREAD_EVENT *pEvent = OSAL_Malloc(sizeof(OSAL_THREAD_EVENT));

    if (pEvent == NULL)
        return OSAL_ERROR_INSUFFICIENT_RESOURCES;

    pEvent->bSignaled = 0;

    if (pipe(pEvent->fd) == -1)
    {
        OSAL_Free(pEvent);
        return OSAL_ERROR_INSUFFICIENT_RESOURCES;
    }

    if (pthread_mutex_init(&pEvent->mutex, NULL))
    {
        close(pEvent->fd[0]);
        close(pEvent->fd[1]);
        OSAL_Free(pEvent);
        return OSAL_ERROR_INSUFFICIENT_RESOURCES;
    }

    *phEvent = (OSAL_PTR)pEvent;
    return OSAL_ERRORNONE;
}
/* Event Create Method */
OSAL_ERROR OSAL_CreateEvent(void **pEvents)
{
    OSAL_ERROR bRet = OSAL_ErrUnKnown;
    OSAL_ThreadEvent *plEvent = (OSAL_ThreadEvent *) OSAL_Malloc(sizeof(OSAL_ThreadEvent));
    if (NULL == plEvent) {
        bRet = OSAL_ErrAlloc;
        goto EXIT;
    }
    plEvent->bSignaled = OSAL_FALSE;
    plEvent->eFlags = 0;

    if (SUCCESS != pthread_mutex_init(&(plEvent->mutex), NULL)) {
        OSAL_ErrorTrace("Event Create:Mutex Init failed !");
        bRet = OSAL_ErrMutexCreate;
        goto EXIT;
    }

    if (SUCCESS != pthread_cond_init(&(plEvent->condition), NULL)) {
        OSAL_ErrorTrace("Event Create:Conditional Variable  Init failed !");
        pthread_mutex_destroy(&(plEvent->mutex));
        bRet = OSAL_ErrEventCreate;
    } else {
        *pEvents = (void *) plEvent;
        bRet = OSAL_ErrNone;
    }
EXIT:
    if ((OSAL_ErrNone != bRet) && (NULL != plEvent)) {
        OSAL_Free(plEvent);
    }
    return bRet;
}
Пример #4
0
OMX_BOOL HantroOmx_port_allocate_next_buffer(PORT* p, BUFFER** buff)
{
    BUFFER* next = (BUFFER*)OSAL_Malloc(sizeof(BUFFER));
    if (next==NULL)
        return OMX_FALSE;
    
    memset(next, 0, sizeof(BUFFER));
    next->flags |= BUFFER_FLAG_IN_USE;
    // hack for tunneling.
    // The buffer header is always accessed through a pointer. In normal case
    // it just points to the header object within the buffer. But in case
    // of tunneling it can be made to point to a header allocated by the tunneling component.
    next->header = &next->headerdata;
    OMX_BOOL ret = HantroOmx_bufferlist_push_back(&p->buffers, next);
    if (ret == OMX_FALSE)
    {
        OMX_ERRORTYPE err;
        OMX_U32 capacity = HantroOmx_bufferlist_get_capacity(&p->buffers);
        if (capacity == 0) capacity = 5;
        err = HantroOmx_bufferlist_reserve(&p->buffers, capacity * 2);
        if (err != OMX_ErrorNone)
        {
            OSAL_Free(next);
            return OMX_FALSE;
        }
        HantroOmx_bufferlist_push_back(&p->buffers, next);
    }
    *buff = next;
    return OMX_TRUE;

}
Пример #5
0
OMX_ERRORTYPE HantroOmx_bufferlist_init(BUFFERLIST* list, OMX_U32 size)
{ 
    assert(list);
    
    list->list = (BUFFER**)OSAL_Malloc(sizeof(BUFFER*) * size);
    if (!list->list)
        return OMX_ErrorInsufficientResources;
    
    memset(list->list, 0, sizeof(BUFFER*) * size);
    list->size     = 0;
    list->capacity = size;
    return OMX_ErrorNone;
}
Пример #6
0
// create codec instance and initialize it
CODEC_PROTOTYPE *HantroHwDecOmx_decoder_create_h264(OMX_BOOL conceal_errors)
{
    CODEC_H264 *this = OSAL_Malloc(sizeof(CODEC_H264));

    memset(this, 0, sizeof(CODEC_H264));

    CALLSTACK;

    this->base.destroy = decoder_destroy_h264;
    this->base.decode = decoder_decode_h264;
    this->base.getinfo = decoder_getinfo_h264;
    this->base.getframe = decoder_getframe_h264;
    this->base.scanframe = decoder_scanframe_h264;
    this->base.setppargs = decoder_setppargs_h264;
#ifdef DYNAMIC_SCALING
    this->base.setscaling = decoder_setscaling_h264;
#endif
    this->instance = 0;
    this->picId++;

#ifdef IS_G1_DECODER
    H264DecRet ret = H264DecInit(&this->instance, DISABLE_OUTPUT_REORDER,
                        USE_VIDEO_FREEZE_CONCEALMENT, USE_DISPLAY_SMOOTHING,
                        DEC_REF_FRM_RASTER_SCAN);
#ifdef MVC_SUPPORT
    if(ret == H264DEC_OK)
        ret = H264DecSetMvc(this->instance);
#endif
#endif

#ifdef IS_8190
    H264DecRet ret = H264DecInit(&this->instance, DISABLE_OUTPUT_REORDER,
                        USE_VIDEO_FREEZE_CONCEALMENT, USE_DISPLAY_SMOOTHING);
#endif

#if !defined (IS_8190) && !defined (IS_G1_DECODER)
    H264DecRet ret = H264DecInit(&this->instance, DISABLE_OUTPUT_REORDER);
#endif

    if(ret != H264DEC_OK)
    {
        decoder_destroy_h264((CODEC_PROTOTYPE *) this);
        return NULL;
    }

#ifdef H264_DECODE_STATISTICS
    this->stat_file = fopen("/tmp/h264_stat.txt", "w");
#endif

    return (CODEC_PROTOTYPE *) this;
}
Пример #7
0
OMX_ERRORTYPE HantroOmx_msgque_push_back(OMX_IN msgque* q, OMX_IN OMX_PTR ptr)
{ 
    assert(q);
    assert(ptr);
    
    msg_node* tail = (msg_node*)OSAL_Malloc(sizeof(msg_node));
    if(!tail)
        return OMX_ErrorInsufficientResources;
    
    tail->next = q->tail;
    tail->prev = 0;
    tail->data = ptr;
    
    // get mutex now
    OMX_ERRORTYPE err = OMX_ErrorNone;
    err = OSAL_MutexLock(q->mutex);
    if (err != OMX_ErrorNone)
    {
        OSAL_Free(tail);
        return err;
    }

    // first set the signal if needed and once that is allright
    // only then change the queue, cause that cant fail
    
    if (q->size == 0)
    {
        err = OSAL_EventSet(q->event);
        if (err != OMX_ErrorNone)
        {
            OSAL_MutexUnlock(q->mutex);
            return err;
        }
    }
    
    q->size += 1;
    if (q->tail)
        q->tail->prev = tail;
    q->tail  = tail;
    if (!q->head)
        q->head = q->tail;

    err = OSAL_MutexUnlock(q->mutex); 
    assert(err == OMX_ErrorNone);
    return OMX_ErrorNone;
}
Пример #8
0
OMX_ERRORTYPE HantroOmx_bufferlist_reserve(BUFFERLIST* list, OMX_U32 newsize)
{
    assert(list);
    if (newsize < list->capacity)
        return OMX_ErrorBadParameter;
    
    BUFFER** data = (BUFFER**)OSAL_Malloc(sizeof(BUFFER**) * newsize);
    if (!data)
        return OMX_ErrorInsufficientResources;
    
    memset(data, 0, sizeof(BUFFER*) * newsize);
    memcpy(data, list->list, list->size * sizeof(BUFFER*));
    
    swap_ptr(&data, &list->list);

    list->capacity = newsize;
    OSAL_Free(data);
    return OMX_ErrorNone;
}
Пример #9
0
// create codec instance and initialize it
CODEC_PROTOTYPE *HantroHwDecOmx_decoder_create_mpeg2(void)
{
    CALLSTACK;

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

    memset(this, 0, sizeof(CODEC_MPEG2));

    this->base.destroy = decoder_destroy_mpeg2;
    this->base.decode = decoder_decode_mpeg2;
    this->base.getinfo = decoder_getinfo_mpeg2;
    this->base.getframe = decoder_getframe_mpeg2;
    this->base.scanframe = decoder_scanframe_mpeg2;
    this->base.setppargs = decoder_setppargs_mpeg2;
#ifdef DYNAMIC_SCALING
	this->base.setscaling = decoder_setscaling_mpeg2;
#endif
    this->instance = 0;
    this->update_pp_out = OMX_FALSE;
    this->picId = 0;
    //this->extraEosLoopDone = OMX_FALSE;

#ifdef IS_G1_DECODER
    Mpeg2DecRet ret = Mpeg2DecInit(&this->instance, USE_VIDEO_FREEZE_CONCEALMENT,
                        FRAME_BUFFERS, DEC_REF_FRM_RASTER_SCAN);
#else
    Mpeg2DecRet ret = Mpeg2DecInit(&this->instance, USE_VIDEO_FREEZE_CONCEALMENT,
                        FRAME_BUFFERS);
#endif

    if(ret != MPEG2DEC_OK)
    {
        decoder_destroy_mpeg2((CODEC_PROTOTYPE *) this);
        return NULL;
    }

#ifdef MPEG2_DECODE_STATISTICS
    this->stat_file = fopen("/tmp/mpeg2_stat.txt", "w");
#endif

    return (CODEC_PROTOTYPE *) this;
}
Пример #10
0
/*------------------------------------------------------------------------------
    OSAL_ThreadCreate
------------------------------------------------------------------------------*/
OSAL_ERRORTYPE OSAL_ThreadCreate( OSAL_U32 (*pFunc)(OSAL_PTR pParam),
        OSAL_PTR pParam, OSAL_U32 nPriority, OSAL_PTR *phThread )
{
    OSAL_THREADDATATYPE *pThreadData;
    struct sched_param sched;

    pThreadData = (OSAL_THREADDATATYPE*)OSAL_Malloc(sizeof(OSAL_THREADDATATYPE));
    if (pThreadData == NULL)
    {
        LOGE("OSAL_ERROR_INSUFFICIENT_RESOURCES\n");
        return OSAL_ERROR_INSUFFICIENT_RESOURCES;
    }

    pThreadData->pFunc = pFunc;
    pThreadData->pParam = pParam;
    pThreadData->uReturn = 0;

    pthread_attr_init(&pThreadData->oThreadAttr);

    pthread_attr_getschedparam(&pThreadData->oThreadAttr, &sched);
    sched.sched_priority += nPriority;
    pthread_attr_setschedparam(&pThreadData->oThreadAttr, &sched);

    if (pthread_create(&pThreadData->oPosixThread,
                       &pThreadData->oThreadAttr,
                       threadFunc,
                       pThreadData)) {
        LOGE("OSAL_ERROR_INSUFFICIENT_RESOURCES\n");
        OSAL_Free(pThreadData);
        return OSAL_ERROR_INSUFFICIENT_RESOURCES;
    }

    BlockSIGIO();

    *phThread = (OSAL_PTR)pThreadData;
    return OSAL_ERRORNONE;
}
Пример #11
0
// create codec instance and initialize it
CODEC_PROTOTYPE *HantroHwDecOmx_decoder_create_vp8()
{
    CALLSTACK;

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

    memset(this, 0, sizeof(CODEC_VP8));

    this->base.destroy = decoder_destroy_vp8;
    this->base.decode = decoder_decode_vp8;
    this->base.getinfo = decoder_getinfo_vp8;
    this->base.getframe = decoder_getframe_vp8;
    this->base.scanframe = decoder_scanframe_vp8;
    this->base.setppargs = decoder_setppargs_vp8;
#ifdef DYNAMIC_SCALING
	this->base.setscaling = decoder_setscaling_vp8;
#endif
    this->instance = 0;
    this->picId = 0;
    this->headersDecoded = OMX_FALSE;

#ifdef IS_G1_DECODER
    VP8DecRet ret = VP8DecInit(&this->instance, VP8DEC_VP8,
                        USE_VIDEO_FREEZE_CONCEALMENT,
                            FRAME_BUFFERS, DEC_REF_FRM_RASTER_SCAN);
#else
    VP8DecRet ret = VP8DecInit(&this->instance, VP8DEC_VP8,
                        USE_VIDEO_FREEZE_CONCEALMENT, FRAME_BUFFERS);
#endif

    if(ret != VP8DEC_OK)
    {
        decoder_destroy_vp8((CODEC_PROTOTYPE *) this);
        return NULL;
    }
    return (CODEC_PROTOTYPE *) this;
}
Пример #12
0
// 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;
}
Пример #13
0
// Create JPEG codec instance and initialize it.
ENCODER_PROTOTYPE* HantroHwEncOmx_encoder_create_jpeg(const JPEG_CONFIG* params)
{
    assert(params);

    JpegEncCfg cfg;
    JpegEncRet ret;

    cfg.qLevel = params->qLevel; // quantization level.

#if defined (ENC8270) || defined (ENC8290) || defined (ENCH1)
    cfg.qTableLuma = NULL;
    cfg.qTableChroma = NULL;
#endif

    switch (params->pp_config.formatType)
    {
        case OMX_COLOR_FormatYUV420PackedPlanar:
        case OMX_COLOR_FormatYUV420Planar:
            cfg.frameType = JPEGENC_YUV420_PLANAR;
            break;
        case OMX_COLOR_FormatYUV420PackedSemiPlanar:
        case OMX_COLOR_FormatYUV420SemiPlanar:
            cfg.frameType = JPEGENC_YUV420_SEMIPLANAR;
            break;
#if !defined (ENC8270) && !defined (ENC8290) && !defined (ENCH1)
        case OMX_COLOR_FormatYUV422Planar:
            cfg.frameType = JPEGENC_YUV422_PLANAR;
            cfg.codingMode = JPEGENC_422_MODE;
            break;
#endif
        case OMX_COLOR_FormatYCbYCr:
            cfg.frameType = JPEGENC_YUV422_INTERLEAVED_YUYV;
            break;
        case OMX_COLOR_FormatCbYCrY:
            cfg.frameType = JPEGENC_YUV422_INTERLEAVED_UYVY;
            break;
        case OMX_COLOR_Format16bitRGB565:
            cfg.frameType = JPEGENC_RGB565;
            break;
        case OMX_COLOR_Format16bitBGR565:
            cfg.frameType = JPEGENC_BGR565;
            break;
        case OMX_COLOR_Format16bitARGB4444:
            cfg.frameType = JPEGENC_RGB444;
            break;
        case OMX_COLOR_Format16bitARGB1555:
            cfg.frameType = JPEGENC_RGB555;
            break;
#ifdef ENCH1
            case OMX_COLOR_Format12bitRGB444:
                cfg.frameType = JPEGENC_RGB444;
            case OMX_COLOR_Format24bitRGB888:
            case OMX_COLOR_Format25bitARGB1888:
            case OMX_COLOR_Format32bitARGB8888:
                cfg.frameType = JPEGENC_RGB888;
                break;
            case OMX_COLOR_Format24bitBGR888:
                cfg.frameType = JPEGENC_BGR888;
#endif
        default:
            ret = JPEGENC_INVALID_ARGUMENT;
            break;
    }

    switch (params->pp_config.angle)
    {
        case 0:
            cfg.rotation = JPEGENC_ROTATE_0;
            break;
        case 90:
            cfg.rotation = JPEGENC_ROTATE_90R;
            break;
        case 270:
            cfg.rotation = JPEGENC_ROTATE_90L;
            break;
        default:
            ret = JPEGENC_INVALID_ARGUMENT;
            break;
    }

    if (params->bAddHeaders)
    {
        cfg.unitsType = params->unitsType;
        cfg.xDensity = params->xDensity;
        cfg.yDensity = params->yDensity;
        cfg.markerType = params->markerType;
        cfg.comLength = 0;  // no comment header
        cfg.pCom = 0;       // no header data
    }
    else
    {
        cfg.unitsType = JPEGENC_NO_UNITS;
        cfg.markerType = JPEGENC_SINGLE_MARKER;
        cfg.xDensity = 1;
        cfg.yDensity = 1;
        cfg.comLength = 0;  // no comment header
        cfg.pCom = 0;       // no header data
    }
#if !defined (ENC8270) && !defined (ENC8290) && !defined (ENCH1)
    cfg.thumbnail = 0;  // no thumbnails
    cfg.cfgThumb.inputWidth = 0;
    cfg.cfgThumb.inputHeight = 0;
    cfg.cfgThumb.xOffset = 0;
    cfg.cfgThumb.yOffset = 0;
    cfg.cfgThumb.codingWidth = 0;
#endif

    // set encoder mode parameters
    cfg.inputWidth = params->pp_config.origWidth;
    cfg.inputHeight = params->pp_config.origHeight;
    cfg.xOffset = params->pp_config.xOffset;
    cfg.yOffset = params->pp_config.yOffset;

    cfg.codingType = params->codingType;

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

    this->croppedWidth = cfg.codingWidth = params->codingWidth;
    this->croppedHeight = cfg.codingHeight = params->codingHeight;

    // encIn struct init
    this->instance = 0;
    memset( &this->encIn, 0, sizeof(JpegEncIn));
    this->origWidth = params->pp_config.origWidth;
    this->origHeight = params->pp_config.origHeight;
    this->frameHeader = params->bAddHeaders;
    this->sliceNumber = 1;
    this->leftoverCrop = 0;
    this->frameType = params->pp_config.formatType;

    // initialize static methods
    this->base.stream_start = encoder_stream_start_jpeg;
    this->base.stream_end = encoder_stream_end_jpeg;
    this->base.encode = encoder_encode_jpeg;
    this->base.destroy = encoder_destroy_jpeg;

    // slice mode configuration
    if (params->codingType > 0)
    {
        if (params->sliceHeight > 0)
        {
            this->sliceMode = OMX_TRUE;
            if (this->frameType == OMX_COLOR_FormatYUV422Planar)
            {
                cfg.restartInterval = params->sliceHeight / 8;
            }
            else
            {
                cfg.restartInterval = params->sliceHeight / 16;
            }
            this->sliceHeight = params->sliceHeight;
        }
        else
        {
            ret = JPEGENC_INVALID_ARGUMENT;
        }
    }
    else
    {
        this->sliceMode = OMX_FALSE;
        cfg.restartInterval = 0;
        this->sliceHeight = 0;
    }

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

    if (ret == JPEGENC_OK) {
#if defined (ENC8270) || defined (ENC8290) || defined (ENCH1)
        ret = JpegEncSetPictureSize(this->instance, &cfg);
#else
        ret = JpegEncSetFullResolutionMode(this->instance, &cfg);
#endif
    }

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

    return (ENCODER_PROTOTYPE*) this;
}
Пример #14
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;
}