diff -r 80975da52420 -r 43d09473c595 khronosfws/openmax_al/src/gst_adaptation/xavideopostprosessingitfadaptation.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/khronosfws/openmax_al/src/gst_adaptation/xavideopostprosessingitfadaptation.c Fri May 14 16:22:35 2010 +0300 @@ -0,0 +1,863 @@ +/* +* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ + +#include +#include +#include "xaadaptationgst.h" +#include "xamediaplayeradaptctx.h" +#include "xamediarecorderadaptctx.h" +#include "xacameraadaptctx.h" +#include "xavideopostprosessingitfadaptation.h" +#include "xastaticcameracapsadaptation.h" + +/* + * XAresult XAVideoPostProcessingItfAdapt_IsArbitraryRotationSupported(XAAdaptationGstCtx *bCtx, + * XAboolean *pSupported) + */ +XAresult XAVideoPostProcessingItfAdapt_IsArbitraryRotationSupported(XAAdaptationGstCtx *bCtx, + XAboolean *pSupported) +{ + XAresult ret = XA_RESULT_SUCCESS; + DEBUG_API("->XAVideoPostProcessingItfAdapt_IsArbitraryRotationSupported"); + + if(!bCtx || (bCtx->baseObj.ctxId != XAMediaPlayerAdaptation && bCtx->baseObj.ctxId != XAMediaRecorderAdaptation + && bCtx->baseObj.ctxId != XACameraAdaptation) || !pSupported) + { + DEBUG_ERR("XA_RESULT_PARAMETER_INVALID"); + DEBUG_API("<-XAVideoPostProcessingItfAdapt_IsArbitraryRotationSupported"); + return XA_RESULT_PARAMETER_INVALID; + } + + /* This feature is not supported, return boolean false */ + *pSupported = XA_BOOLEAN_FALSE; + + DEBUG_API("<-XAVideoPostProcessingItfAdapt_IsArbitraryRotationSupported"); + return ret; +} + +/* + * XAresult XAVideoPostProcessingItfAdapt_Commit(XAAdaptationGstCtx *bCtx) + */ +XAresult XAVideoPostProcessingItfAdapt_Commit(XAAdaptationGstCtx *bCtx, + XAmillidegree rotation, + XAuint32 scaleOptions, + XAuint32 backgroundColor, + XAuint32 renderingHints, + const XARectangle *pSrcRect, + const XARectangle *pDestRect, + XAuint32 mirror, + XAboolean isMirror, + XAboolean isRotate, + XAboolean isDestRect, + XAboolean isSrcRect, + XAboolean isScaleOptions + ) +{ + XAresult ret = XA_RESULT_SUCCESS; + XAmillidegree tempRotation = 0; + XAmillidegree newRotation = 0; + XAuint32 tempMirror = XA_VIDEOMIRROR_NONE; + XAuint32 newMirror = XA_VIDEOMIRROR_NONE; + XADataSource *dataSrc = NULL; + GstElement *cropElement = NULL; + GstElement *rotateElement = NULL; + GstElement *mirrorElement = NULL; + GstElement *boxElement = NULL; +/* + GstElement *balanceElement = NULL; + GstElement *gammaElement = NULL; +*/ + GstElement *sink = NULL; + GstElement *col1 = NULL; + GstElement *scale = NULL; +/* + gdouble alphaValue = 1; + gint videoBackgroundColor = 0; +*/ + gint cropscaleRight = 0, cropscaleBottom = 0, + cropscaleLeft = 0, + cropscaleTop = 0, + videoscaleHeight = 0; + GstStateChangeReturn gstRet = GST_STATE_CHANGE_SUCCESS; + GstState gstOrigState = GST_STATE_PLAYING; + GstState gstTmpState = GST_STATE_PLAYING; + + DEBUG_API("->XAVideoPostProcessingItfAdapt_Commit"); + + if( !bCtx || (bCtx->baseObj.ctxId != XAMediaPlayerAdaptation && bCtx->baseObj.ctxId != XAMediaRecorderAdaptation + && bCtx->baseObj.ctxId != XACameraAdaptation)) + { + DEBUG_ERR("XA_RESULT_PARAMETER_INVALID"); + DEBUG_API("<-XAVideoPostProcessingItfAdapt_Commit"); + return XA_RESULT_PARAMETER_INVALID; + } + + if( bCtx->baseObj.ctxId == XAMediaPlayerAdaptation ) + { + XAMediaPlayerAdaptationCtx* ctx = (XAMediaPlayerAdaptationCtx*) bCtx; + + + /* Get video pp elements */ + GstPad *pad = NULL; + GstCaps *caps = NULL; + col1 = gst_bin_get_by_name( GST_BIN(ctx->baseObj.bin), "pp_colsp1"); + cropElement = gst_bin_get_by_name( GST_BIN(ctx->baseObj.bin), "pp_crop"); + rotateElement = gst_bin_get_by_name( GST_BIN(ctx->baseObj.bin), "pp_rotate"); + mirrorElement = gst_bin_get_by_name( GST_BIN(ctx->baseObj.bin), "pp_mirror"); + boxElement = gst_bin_get_by_name( GST_BIN(ctx->baseObj.bin), "pp_box"); +/* + balanceElement = gst_bin_get_by_name( GST_BIN(ctx->baseObj.bin), "pp_balance"); + gammaElement = gst_bin_get_by_name( GST_BIN(ctx->baseObj.bin), "pp_gamma"); +*/ + sink = gst_bin_get_by_name( GST_BIN(ctx->baseObj.bin), "videosink"); + pad = gst_element_get_static_pad(GST_ELEMENT(sink),"sink"); + caps = gst_caps_new_simple("video/x-raw-yuv", + "width", G_TYPE_INT,0, + "height", G_TYPE_INT,0, + NULL); + gst_pad_set_caps(pad, caps); + + /* get current mirror state and rotate value */ + tempMirror = ctx->curMirror; + tempRotation = ctx->curRotation; + dataSrc = ctx->xaSource; + } + + if( bCtx->baseObj.ctxId == XAMediaRecorderAdaptation ) + { + XAMediaRecorderAdaptationCtx* ctx = (XAMediaRecorderAdaptationCtx*) bCtx; + + /* Get video pp elements */ + GstPad *pad = NULL; + GstCaps *caps = NULL; + scale = gst_bin_get_by_name( GST_BIN(ctx->baseObj.bin), "pp_scale2"); + col1 = gst_bin_get_by_name( GST_BIN(ctx->baseObj.bin), "pp_colsp1"); + cropElement = gst_bin_get_by_name( GST_BIN(ctx->baseObj.bin), "pp_crop"); + rotateElement = gst_bin_get_by_name( GST_BIN(ctx->baseObj.bin), "pp_rotate"); + mirrorElement = gst_bin_get_by_name( GST_BIN(ctx->baseObj.bin), "pp_mirror"); + boxElement = gst_bin_get_by_name( GST_BIN(ctx->baseObj.bin), "pp_box"); +/* balanceElement = gst_bin_get_by_name( GST_BIN(ctx->baseObj.bin), "pp_balance"); + gammaElement = gst_bin_get_by_name( GST_BIN(ctx->baseObj.bin), "pp_gamma");*/ + sink = gst_bin_get_by_name( GST_BIN(ctx->baseObj.bin), "datasink"); + pad = gst_element_get_static_pad(GST_ELEMENT(sink),"sink"); + caps = gst_caps_new_simple("video/x-raw-yuv", + "width", G_TYPE_INT,0, + "height", G_TYPE_INT,0, + NULL); + gst_pad_set_caps(pad, caps); + + /* get current mirror state and rotate value */ + tempMirror = ctx->curMirror; + tempRotation = ctx->curRotation; + } + + if( bCtx->baseObj.ctxId == XACameraAdaptation ) + { + XACameraAdaptationCtx* ctx = (XACameraAdaptationCtx*) bCtx; + + GstElement *videoPP = gst_bin_get_by_name( GST_BIN(ctx->baseObj.bin), "videopp_camera"); + if( !videoPP ) + { + DEBUG_ERR("Could not receive videopp from camerabin!"); + } + else + { + /* Get camera pp elements */ + GstPad *pad = NULL; + GstCaps *caps = NULL; + rotateElement = gst_bin_get_by_name( GST_BIN(videoPP), "pp_rotate"); + col1 = gst_bin_get_by_name( GST_BIN(videoPP), "pp_colsp1"); + cropElement = gst_bin_get_by_name( GST_BIN(videoPP), "pp_crop"); + mirrorElement = gst_bin_get_by_name( GST_BIN(videoPP), "pp_mirror"); + boxElement = gst_bin_get_by_name( GST_BIN(videoPP), "pp_box"); +/* balanceElement = gst_bin_get_by_name( GST_BIN(videoPP), "pp_balance"); + gammaElement = gst_bin_get_by_name( GST_BIN(videoPP), "pp_gamma");*/ + sink = gst_bin_get_by_name( GST_BIN(ctx->baseObj.bin), "pp_crop"); + pad = gst_element_get_static_pad(GST_ELEMENT(sink),"sink"); + caps = gst_caps_new_simple("video/x-raw-yuv", + "width", G_TYPE_INT,0, + "height", G_TYPE_INT,0, + NULL); + gst_pad_set_caps(pad, caps); + + /* get current mirror state and rotate value */ + tempMirror = ctx->curMirror; + tempRotation = ctx->curRotation; + } + } + + /* Cropping */ + if( isSrcRect && pSrcRect && cropElement && col1 ) + { + + gint cropRight = 0; + gint cropBottom = 0; + gint cropLeft = 0; + gint cropTop = 0; + GstPad *videoPad = NULL; + gint videoWidth = 0; + gint videoHeight = 0; + DEBUG_INFO("Start cropping!"); + + DEBUG_INFO_A1("pSrcRect->left:%d",(int)pSrcRect->left); + DEBUG_INFO_A1("pSrcRect->top:%d",(int)pSrcRect->top); + DEBUG_INFO_A1("pSrcRect->width:%d",(int)pSrcRect->width); + DEBUG_INFO_A1("pSrcRect->height:%d", (int)pSrcRect->height); + + if( bCtx->baseObj.ctxId == XACameraAdaptation ) + { + GstCaps *caps = NULL; + XACameraAdaptationCtx* ctx = (XACameraAdaptationCtx*) bCtx; + gint capsCount = 0; + gint iterator = 0; + GstStructure *capsStruct = NULL; + + g_object_get( G_OBJECT(ctx->baseObj.bin), "filter-caps", &caps, NULL ); + + if( !caps ) + { + DEBUG_ERR("Cannot receive caps (filter-caps) from camerabin!"); + DEBUG_API("<-XAVideoPostProcessingItfAdapt_Commit - XA_RESULT_INTERNAL_ERROR"); + return XA_RESULT_INTERNAL_ERROR; + } + + capsCount = gst_caps_get_size( caps ); + + for( iterator= 0; iterator < capsCount; iterator++ ) + { + capsStruct = gst_caps_get_structure( caps, iterator ); + if( capsStruct ) + { + if( !gst_structure_get_int( capsStruct, "width", &videoWidth ) ) + { + DEBUG_ERR("Could not get width from filter-caps"); + videoWidth = TEST_VIDEO_WIDTH; + } + if( !gst_structure_get_int( capsStruct, "height", &videoHeight) ) + { + DEBUG_ERR("Could not get height from filter-caps"); + videoHeight = TEST_VIDEO_HEIGHT; + } + DEBUG_INFO_A2("videoWidth:%d, videoHeight:%d",videoWidth,videoHeight); + } + } + } + else + { + GstCaps* negcapas=NULL; + videoPad = gst_element_get_pad( col1, "src" ); + negcapas = gst_pad_get_negotiated_caps( GST_PAD(videoPad) ); + if ( negcapas ) + { + if( !gst_video_get_size( videoPad, &videoWidth, &videoHeight ) ) + { + DEBUG_ERR("WARN: Cannot receive video size, using defaults"); + videoWidth = TEST_VIDEO_WIDTH; + videoHeight = TEST_VIDEO_HEIGHT; + } + } + else + { + videoWidth = TEST_VIDEO_WIDTH; + videoHeight = TEST_VIDEO_HEIGHT; + } + } + + DEBUG_INFO_A2("Received video frame info, videoWidth:%d, videoHeight:%d",videoWidth,videoHeight); + cropLeft = (gint)pSrcRect->left; + cropTop = (gint)pSrcRect->top; + cropRight = videoWidth - ((gint)pSrcRect->left + (gint)pSrcRect->width); + cropBottom = videoHeight - ((gint)pSrcRect->top + (gint)pSrcRect->height); + DEBUG_INFO_A4("Crop values - cropLeft:%d ,cropTop:%d,cropRight:%d,cropBottom:%d", cropLeft,cropTop,cropRight,cropBottom); + + if( cropBottom >= 0 && cropLeft >=0 && cropRight >= 0 && cropTop >= 0 ) + { + g_object_set(G_OBJECT(cropElement), "bottom",cropBottom, NULL); + g_object_set(G_OBJECT(cropElement), "left", cropLeft, NULL); + g_object_set(G_OBJECT(cropElement), "right", cropRight, NULL); + g_object_set(G_OBJECT(cropElement), "top", cropTop, NULL); + } + else + { + if( cropLeft > videoWidth || cropLeft < 0 || + cropRight > videoWidth || cropRight < 0 || + cropBottom > videoHeight || cropBottom < 0 || + cropTop > videoHeight || cropTop < 0) + { + DEBUG_INFO("Cropped params out of original frame."); + } + } + } + + if(rotateElement && isRotate) + { + DEBUG_INFO("Start rotating!"); + + /* calculate rotation */ + newRotation = tempRotation + rotation; + + if( newRotation > ROTATION_RATIO || newRotation < ROTATION_RATIO_NEG ) + { + newRotation = newRotation % ROTATION_RATIO; + } + + /* Set rotation */ + switch(newRotation) + { + case 0: + { + /* no rotation */ + DEBUG_INFO("Set rotation FLIP_NONE"); + g_object_set(G_OBJECT(rotateElement), "method", FLIP_NONE, NULL); + break; + } + case 90000: + case -270000: + { + /* rotation 90 degree */ + DEBUG_INFO("Set rotation 90 degrees"); + g_object_set(G_OBJECT(rotateElement), "method", FLIP_CLOCKWISE, NULL); + break; + } + case 180000: + case -180000: + { + /* rotation 180 degree */ + DEBUG_INFO("Set rotation 180 degrees"); + g_object_set(G_OBJECT(rotateElement), "method", FLIP_ROTATE_180, NULL); + break; + } + case 270000: + case -90000: + { + /* rotation 270 degree */ + DEBUG_INFO("Set rotation 270 degrees"); + g_object_set(G_OBJECT(rotateElement), "method", FLIP_COUNTERCLOCKWISE, NULL); + break; + } + case 360000: + case -360000: + { + /* rotation 360 degree */ + DEBUG_INFO("Set rotation 360 degrees"); + g_object_set(G_OBJECT(rotateElement), "method", FLIP_NONE, NULL); + break; + } + default: + { + /* no rotation */ + DEBUG_INFO("Set rotation default (FLIP_NONE) degree"); + g_object_set(G_OBJECT(rotateElement), "method", FLIP_NONE, NULL); + break; + } + } + + /* Store current rotate value */ + if( bCtx->baseObj.ctxId == XAMediaPlayerAdaptation ) + { + XAMediaPlayerAdaptationCtx* ctx = (XAMediaPlayerAdaptationCtx*) bCtx; + ctx->curRotation = newRotation; + } + if( bCtx->baseObj.ctxId == XAMediaRecorderAdaptation ) + { + XAMediaRecorderAdaptationCtx* ctx = (XAMediaRecorderAdaptationCtx*) bCtx; + ctx->curRotation = newRotation; + } + if( bCtx->baseObj.ctxId == XACameraAdaptation ) + { + XACameraAdaptationCtx* ctx = (XACameraAdaptationCtx*) bCtx; + ctx->curRotation = newRotation; + } + } + + if(mirrorElement && isMirror) + { + /* solve new mirror state */ + switch(mirror) + { + case XA_VIDEOMIRROR_NONE: + { + newMirror = tempMirror; + break; + } + case XA_VIDEOMIRROR_VERTICAL: + { + if( tempMirror == XA_VIDEOMIRROR_VERTICAL ) + { + newMirror = XA_VIDEOMIRROR_NONE; + } + else if( tempMirror == XA_VIDEOMIRROR_HORIZONTAL ) + { + newMirror = XA_VIDEOMIRROR_BOTH; + } + else if( tempMirror == XA_VIDEOMIRROR_BOTH ) + { + newMirror = XA_VIDEOMIRROR_HORIZONTAL; + } + else + { + newMirror = XA_VIDEOMIRROR_VERTICAL; + } + break; + } + case XA_VIDEOMIRROR_HORIZONTAL: + { + if( tempMirror == XA_VIDEOMIRROR_VERTICAL ) + { + newMirror = XA_VIDEOMIRROR_BOTH; + } + else if( tempMirror == XA_VIDEOMIRROR_HORIZONTAL ) + { + newMirror = XA_VIDEOMIRROR_NONE; + } + else if( tempMirror == XA_VIDEOMIRROR_BOTH ) + { + newMirror = XA_VIDEOMIRROR_VERTICAL; + } + else + { + newMirror = XA_VIDEOMIRROR_HORIZONTAL; + } + break; + } + case XA_VIDEOMIRROR_BOTH: + { + if( tempMirror == XA_VIDEOMIRROR_VERTICAL ) + { + newMirror = XA_VIDEOMIRROR_HORIZONTAL; + } + else if( tempMirror == XA_VIDEOMIRROR_HORIZONTAL ) + { + newMirror = XA_VIDEOMIRROR_VERTICAL; + } + else if( tempMirror == XA_VIDEOMIRROR_BOTH ) + { + newMirror = XA_VIDEOMIRROR_NONE; + } + else + { + newMirror = XA_VIDEOMIRROR_BOTH; + } + break; + } + default: + break; + } + + + DEBUG_INFO("Start mirroring!"); + /* Set mirror */ + switch(newMirror) + { + case XA_VIDEOMIRROR_NONE: + { + /* none */ + DEBUG_INFO("Set mirror none"); + g_object_set(G_OBJECT(mirrorElement), "method", FLIP_NONE, NULL); + break; + } + case XA_VIDEOMIRROR_VERTICAL: + { + /* vertical mirror */ + DEBUG_INFO("Set mirror vertical"); + g_object_set(G_OBJECT(mirrorElement), "method", FLIP_VERTICAL, NULL); + break; + } + case XA_VIDEOMIRROR_HORIZONTAL: + { + /* horizontal mirror */ + DEBUG_INFO("Set mirror horizontal"); + g_object_set(G_OBJECT(mirrorElement), "method", FLIP_HORIZONTAL, NULL); + break; + } + case XA_VIDEOMIRROR_BOTH: + { + /* both mirror */ + DEBUG_INFO("Set mirror vertical and horizontal"); + g_object_set(G_OBJECT(mirrorElement), "method", FLIP_ROTATE_180, NULL); + break; + } + default: + { + /* Default no mirroring */ + g_object_set(G_OBJECT(mirrorElement), "method", FLIP_NONE, NULL); + break; + } + } + + /* Store current mirror state */ + if( bCtx->baseObj.ctxId == XAMediaPlayerAdaptation ) + { + XAMediaPlayerAdaptationCtx* ctx = (XAMediaPlayerAdaptationCtx*) bCtx; + ctx->curMirror = newMirror; + } + if( bCtx->baseObj.ctxId == XAMediaRecorderAdaptation ) + { + XAMediaRecorderAdaptationCtx* ctx = (XAMediaRecorderAdaptationCtx*) bCtx; + ctx->curMirror = newMirror; + } + if( bCtx->baseObj.ctxId == XACameraAdaptation ) + { + XACameraAdaptationCtx* ctx = (XACameraAdaptationCtx*) bCtx; + ctx->curMirror = newMirror; + } + } + + /* Set scale */ + if ( isScaleOptions || isDestRect || isSrcRect ) + { + switch( scaleOptions ) + { + + case XA_VIDEOSCALE_STRETCH: + { + DEBUG_INFO("XA_VIDEOSCALE_STRETCH"); + /* The source and destination rectangle's width and height params are used to calculate + * the scaling factors independently. Aspect ratio is ignored. */ + if (pDestRect) + { + if (bCtx->baseObj.ctxId != XAMediaRecorderAdaptation) + { + GstPad *pad = NULL; + GstCaps* simplecaps = NULL; + g_object_set ( G_OBJECT(sink), "force-aspect-ratio", FALSE, NULL); + simplecaps = gst_caps_new_simple("video/x-raw-rgb", + "width", G_TYPE_INT, pDestRect->width, + "height", G_TYPE_INT, pDestRect->height, + "framerate", GST_TYPE_FRACTION, 0,1, + NULL); + DEBUG_API_A1("caps: %s",gst_caps_to_string(simplecaps)); + pad = gst_element_get_static_pad(GST_ELEMENT(sink),"sink"); + if (!gst_pad_set_caps(pad, simplecaps)) + { + DEBUG_INFO("Stubbed at this point"); + DEBUG_INFO("Cannot set destrect size during XA_VIDEOSCALE_STRETCH!"); + DEBUG_API("<-XAVideoPostProcessingItfAdapt_Commit - XA_VIDEOSCALE_STRETCH"); + return XA_RESULT_SUCCESS; + } + DEBUG_API_A1("ret: %lu",ret); + } + else + { + GstCaps* simplecaps = NULL; + GstPad *pad = NULL; + if ( !scale ) + { + DEBUG_ERR("Could not get scaling element from pipeline!"); + DEBUG_API("<-XAVideoPostProcessingItfAdapt_Commit - XA_RESULT_INTERNAL_ERROR"); + return XA_RESULT_INTERNAL_ERROR; + } + simplecaps = gst_caps_new_simple("video/x-raw-yuv", + "width", G_TYPE_INT, pDestRect->width, + "height", G_TYPE_INT, pDestRect->height, + "framerate", GST_TYPE_FRACTION, 0,1, + NULL); + DEBUG_API_A1("caps: %s",gst_caps_to_string(simplecaps)); + pad = gst_element_get_static_pad(GST_ELEMENT(scale),"src"); + if (!gst_pad_set_caps(pad, simplecaps)) + { + DEBUG_INFO("Stubbed at this point"); + DEBUG_INFO("Cannot set destrect size during XA_VIDEOSCALE_STRETCH!"); + DEBUG_API("<-XAVideoPostProcessingItfAdapt_Commit - XA_VIDEOSCALE_STRETCH"); + return XA_RESULT_SUCCESS; + } + + } + } + DEBUG_INFO("XA_VIDEOSCALE_STRETCH Done"); + + break; + } + case XA_VIDEOSCALE_FIT: + { + DEBUG_INFO("XA_VIDEOSCALE_FIT"); + /* The miminum scale factor between the destination rectangle's width over the + * source rectangle's source rectangle's width and the destination rectangle's height over + * the source rectangle's height is used. Aspect ratio is maintained. Frame is centered */ + if (pDestRect) + { + if (bCtx->baseObj.ctxId != XAMediaRecorderAdaptation) + { + GstPad *pad = NULL; + GstCaps* simplecaps = NULL; + g_object_set ( G_OBJECT(sink), "force-aspect-ratio", TRUE, NULL); + simplecaps = gst_caps_new_simple("video/x-raw-rgb", + "width", G_TYPE_INT, pDestRect->width, + "height", G_TYPE_INT, pDestRect->height, + "framerate", GST_TYPE_FRACTION, 0,1, + NULL); + DEBUG_API_A1("caps: %s",gst_caps_to_string(simplecaps)); + pad = gst_element_get_static_pad(GST_ELEMENT(sink),"sink"); + if (!gst_pad_set_caps(pad, simplecaps)) + { + DEBUG_INFO("Stubbed at this point"); + DEBUG_INFO("Cannot set destrect size during XA_VIDEOSCALE_FIT!"); + DEBUG_API("<-XAVideoPostProcessingItfAdapt_Commit - XA_VIDEOSCALE_FIT"); + return XA_RESULT_SUCCESS; + } + } + else + { + GstPad *videoScalePad = NULL; + GstCaps *negcaps = NULL; + gint videoScalePadHeight = 0, videoScalePadWidth = 0; + gfloat scaleFactorWidth = 0; + gfloat scaleFactorHeight = 0; + gfloat scaleFactor = 0; + videoScalePad = gst_element_get_pad( col1, "src" ); + negcaps = gst_pad_get_negotiated_caps( GST_PAD(videoScalePad) ); + if ( negcaps ) + { + if( !gst_video_get_size( videoScalePad, &videoScalePadWidth, &videoScalePadHeight ) ) + { + DEBUG_ERR("Cannot receive current cropscalevideo size!"); + DEBUG_API("<-XAVideoPostProcessingItfAdapt_Commit - XA_RESULT_INTERNAL_ERROR"); + return XA_RESULT_INTERNAL_ERROR; + } + } + else + { + DEBUG_ERR("No negotiated caps in col1:src!"); + DEBUG_API("<-XAVideoPostProcessingItfAdapt_Commit"); + return XA_RESULT_SUCCESS; + } + if (pSrcRect->width != 0 && pSrcRect->height != 0) + { + scaleFactorWidth = (gfloat)videoScalePadWidth / (gfloat)pSrcRect->width; + scaleFactorHeight = (gfloat)videoScalePadHeight / (gfloat)pSrcRect->height; + if (scaleFactorWidth < scaleFactorHeight) + { + scaleFactor = scaleFactorWidth; + } + else + { + scaleFactor = scaleFactorHeight; + } + + cropscaleBottom = (gint)(pSrcRect->height*scaleFactor - videoScalePadHeight)/2; + cropscaleLeft = (gint)(pSrcRect->width*scaleFactor - videoScalePadWidth)/2; + if (cropscaleLeft > 0){ + cropscaleLeft *= -1; + } + cropscaleRight = cropscaleLeft; + if (cropscaleBottom > 0){ + cropscaleBottom *= -1; + } + cropscaleTop = cropscaleBottom; + g_object_set (G_OBJECT (boxElement), "bottom", cropscaleBottom , NULL); + g_object_set (G_OBJECT (boxElement), "right", cropscaleRight, NULL); + g_object_set (G_OBJECT (boxElement), "left", cropscaleLeft, NULL); + g_object_set (G_OBJECT (boxElement), "top", cropscaleTop, NULL); + } + } + } + DEBUG_INFO("XA_VIDEOSCALE_FIT done"); + + break; + } + case XA_VIDEOSCALE_CROP: + { + DEBUG_INFO("XA_VIDEOSCALE_CROP"); + /* The maximum scale factor between the destination rectangle's width over the source + * rectangle's width and destination rectangle's height over the source rectangle's + * height is used. Aspect ratio is maintained. Frame is centered. */ + if( pDestRect && pSrcRect ) + { + GstPad *videoScalePad = NULL; + GstCaps *negcaps = NULL; + gint videoScalePadHeight = 0, videoScalePadWidth = 0; + videoScalePad = gst_element_get_pad( col1, "src" ); + negcaps = gst_pad_get_negotiated_caps( GST_PAD(videoScalePad) ); + if ( negcaps ) + { + if( !gst_video_get_size( videoScalePad, &videoScalePadWidth, &videoScalePadHeight ) ) + { + DEBUG_ERR("Cannot receive current cropscalevideo size!"); + DEBUG_API("<-XAVideoPostProcessingItfAdapt_Commit - XA_RESULT_INTERNAL_ERROR"); + return XA_RESULT_INTERNAL_ERROR; + } + } + else + { + DEBUG_ERR("No negotiated caps in col1:src!"); + DEBUG_API("<-XAVideoPostProcessingItfAdapt_Commit"); + return XA_RESULT_SUCCESS; + } + + DEBUG_INFO_A2( "Received video scale frame info, videoScalePadWidth:%d, " + "videoScalePadHeight:%d",videoScalePadWidth,videoScalePadHeight); + + if( pSrcRect->height > 0 && pSrcRect->width > 0 ) + { + if( pSrcRect->height > pDestRect->height ) + { + videoscaleHeight = pSrcRect->height; + if( pDestRect->top == 0) + { + cropscaleTop = ((videoscaleHeight - pDestRect->height)/2); + cropscaleBottom = ((videoscaleHeight - pDestRect->height)/2); + } + else + { + cropscaleTop = (pDestRect->top/2); + cropscaleBottom = (pDestRect->top/2); + } + } + else if( pDestRect->height > pSrcRect->height ) + { + videoscaleHeight = pDestRect->height; + if( pDestRect->top == 0) + { + cropscaleTop = -((videoscaleHeight - pSrcRect->height)/2); + cropscaleBottom = -((videoscaleHeight - pSrcRect->height)/2); + } + else + { + cropscaleTop = -(pDestRect->top/2); + cropscaleBottom = -(pDestRect->top/2); + } + } + else if( pDestRect->height == pSrcRect->height ) + { + } + else + { + } + if( pSrcRect->width > pDestRect->width ) + { + if( pDestRect->left == 0 ) + { + cropscaleLeft = ((gint)(pSrcRect->width -pDestRect->width)/2); + cropscaleRight = ((gint)(pSrcRect->width -pDestRect->width)/2); + } + else + { + cropscaleLeft = (pDestRect->left/2); + cropscaleRight = (pDestRect->left/2); + } + } + else if( pDestRect->width > pSrcRect->width ) + { + if( pDestRect->left == 0 ) + { + cropscaleLeft =-((gint)(pDestRect->width -pSrcRect->width)/2); + cropscaleRight =-((gint)(pDestRect->width -pSrcRect->width)/2); + } + else + { + cropscaleLeft = -(pDestRect->left/2); + cropscaleRight = -(pDestRect->left/2); + } + } + else if( pDestRect->width == pSrcRect->width ) + { + } + else + { + } + } + else + { + DEBUG_ERR("Invalid rectangle values in source rectangles"); + DEBUG_API("<-XAVideoPostProcessingItfAdapt_Commit, Exit with invalid source rectangle values"); + return XA_RESULT_PARAMETER_INVALID; + } + if( pDestRect->width != pSrcRect->width && pDestRect->height != pSrcRect->height ) + { + DEBUG_INFO_A4("Crop values - cropscaleLeft:%d " + ",cropscaleTop:%d," + "cropscaleRight:%d," + "cropscaleBottom:%d", + cropscaleLeft, + cropscaleTop, + cropscaleRight, + cropscaleBottom); + g_object_set (G_OBJECT (boxElement), "bottom",cropscaleBottom , NULL); + g_object_set (G_OBJECT (boxElement), "right", cropscaleRight, NULL); + g_object_set (G_OBJECT (boxElement), "left", cropscaleLeft, NULL); + g_object_set (G_OBJECT (boxElement), "top",cropscaleTop, NULL); + } + } + break; + } + default: + DEBUG_INFO("no scale options!"); + break; + } + } + + + /*TODO The Code below does nothing. just set the variable which are never used. + * commenting the code below. */ +/* if(pDestRect && boxElement) + { + is background color black + if((backgroundColor >> 8) & BLACK_BG_COLOR_MASK) + { + videoBackgroundColor = 0; + } + is background color green + else if((backgroundColor >> 8) & GREEN_BG_COLOR_MASK) + { + videoBackgroundColor = 1; + } + is background color blue + else if((backgroundColor >> 8) & BLUE_BG_COLOR_MASK) + { + videoBackgroundColor = 2; + } + else + { + by default black + videoBackgroundColor = 0; + } + + check alpha value. Gst support values 0 to 1 and XA 0 to 255 + { + XAuint32 tempColor = 0; + tempColor = backgroundColor & ALPHA_VALUE_MASK; + + alphaValue = (gdouble)(tempColor/ALPHA_VALUE_MASK); + } + + + }*/ + + if( dataSrc ) + { + XAMediaType mediaType = XA_MEDIATYPE_UNKNOWN; + ret = XACommon_CheckDataSource(dataSrc, &mediaType); + if( ret == XA_RESULT_SUCCESS && mediaType == XA_MEDIATYPE_IMAGE ) + { + gstOrigState = GST_STATE(bCtx->bin); + + DEBUG_INFO_A1("Sending change state request to state %d", GST_STATE_READY); + gstRet = gst_element_set_state( GST_ELEMENT(bCtx->bin), GST_STATE_READY); + gstTmpState = GST_STATE(bCtx->bin); + + if(gstRet == GST_STATE_CHANGE_SUCCESS && gstTmpState == GST_STATE_READY) + { + DEBUG_INFO_A1("Sending change state request to state %d", gstOrigState); + gstRet = gst_element_set_state( GST_ELEMENT(bCtx->bin), gstOrigState); + } + } + } + + DEBUG_API("<-XAVideoPostProcessingItfAdapt_Commit"); + return ret; +} +