Home | History | Annotate | Download | only in src
      1 /* ------------------------------------------------------------------
      2  * Copyright (C) 1998-2009 PacketVideo
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
     13  * express or implied.
     14  * See the License for the specific language governing permissions
     15  * and limitations under the License.
     16  * -------------------------------------------------------------------
     17  */
     18 //class CPVVideoBlend.cpp
     19 #include "pvvideoblend.h"
     20 
     21 // Use default DLL entry point
     22 #include "oscl_dll.h"
     23 OSCL_DLL_ENTRY_POINT_DEFAULT()
     24 
     25 OSCL_EXPORT_REF CPVVideoBlend* CPVVideoBlend :: New()
     26 {
     27     CPVVideoBlend *pobj = OSCL_NEW(CPVVideoBlend, ()) ;
     28 
     29 
     30     return pobj;
     31 }
     32 
     33 CPVVideoBlend :: CPVVideoBlend()
     34 {
     35     int err;
     36 
     37     OSCL_TRY(err,
     38              CameraInput = (CCYUV422toYUV420*) CCYUV422toYUV420::New();
     39              BitmapInput = (CCRGB16toYUV420*) CCRGB16toYUV420::New();
     40              DecoderOutput = (ColorConvert16*) ColorConvert16::NewL();
     41              EncoderInput = (ColorConvert16*) ColorConvert16::NewL();
     42             );
     43 
     44     if (err != OsclErrNone)
     45     {
     46         OSCL_LEAVE(err);
     47     }
     48 }
     49 
     50 
     51 
     52 OSCL_EXPORT_REF CPVVideoBlend :: ~CPVVideoBlend()
     53 {
     54 
     55 }
     56 
     57 
     58 OSCL_EXPORT_REF int32 CPVVideoBlend::InitInputBlend(PVDimension *frameSize, PVRotationCLKWise rotation)
     59 {
     60     uint32 width_src, height_src, pitch_src, width_dst, height_dst, pitch_dst;
     61     int rot = 0;
     62 
     63     mInitInputBlend = false;
     64 
     65     width_src = frameSize->width;
     66     height_src = frameSize->height;
     67     pitch_src = frameSize->width;
     68 
     69     switch (rotation)
     70     {
     71         case Rotation0  :
     72             rot = 0;
     73             break;
     74         case Rotation90 :
     75             rot = 3;
     76             break;
     77         case Rotation180    :
     78             rot = 2;
     79             break;
     80         case Rotation270    :
     81             rot = 1;
     82             break;
     83     }
     84 
     85     if (rotation&1) /* rotation 90 or 270 degree */
     86     {
     87         width_dst = height_src;
     88         height_dst = width_src;
     89         pitch_dst = height_src;
     90     }
     91     else
     92     {
     93         width_dst = width_src;
     94         height_dst = height_src;
     95         pitch_dst = pitch_src;
     96     }
     97 
     98     if (!CameraInput->Init(width_src, height_src, pitch_src, width_dst, height_dst, pitch_dst, rot))
     99     {
    100         return 0;
    101     }
    102 
    103     if (!BitmapInput->Init(width_dst, height_dst, pitch_dst, width_dst, height_dst, pitch_dst, 0))
    104     {
    105         return 0;
    106     }
    107 
    108     mInitInputBlend = true;
    109 
    110     return 1;
    111 }
    112 
    113 // Still need some optimization to save time during the init.
    114 // If the param is the same, we shouldn't call init all the time.
    115 OSCL_EXPORT_REF int32 CPVVideoBlend :: BlendInput(PVBlendFrame *pCameraInput, PVBitmap *pBitmap, PVBlendFrame *pToEncode)
    116 {
    117     uint8 *inputRGB;
    118     uint8 *outYUV;
    119     uint8 *srcBuffer, *dstBuffer;
    120     PVYUVFormat format;
    121     uint32 width_src, height_src, pitch_src, width_dst, height_dst, pitch_dst;
    122     int16 colorkey;
    123 
    124     if (mInitInputBlend == false || (pCameraInput == NULL && pBitmap == NULL) || (pToEncode == NULL))
    125     {
    126         return 0;
    127     }
    128 
    129     /*********** For YUV422 to YUV420 conversion **********/
    130     if (pCameraInput != NULL)
    131     {
    132         srcBuffer = pCameraInput->pBuffer;
    133         width_src = pCameraInput->width;
    134         height_src = pCameraInput->height;
    135         format = pCameraInput->format;
    136         pitch_src = width_src;
    137 
    138         dstBuffer = pToEncode->pBuffer;
    139         Dst_width = pToEncode->width; // 1:1, so equal to source
    140         Dst_height = pToEncode->height; // 1:1, so equal to source
    141         pitch_dst = pToEncode->width; // width of the destination buffer
    142 
    143         if (format == YUV422)
    144         {
    145             /* check the buffer size */
    146             if ((pCameraInput->bufSize < pitch_src*height_src*2) ||
    147                     (pToEncode->bufSize < ((pitch_dst*Dst_height*3) >> 1)))
    148             {
    149                 return 0;
    150             }
    151 
    152             /* perform the conversion */
    153             if (!CameraInput->Convert(srcBuffer, dstBuffer))
    154             {
    155                 return 0;
    156             }
    157 
    158         }
    159         else
    160         {
    161             return 0;
    162         }
    163     }
    164 
    165     /********** For RGB16 to YUV420 conversion **********/
    166     if (pBitmap != NULL)
    167     {
    168         inputRGB = pBitmap->pBuffer;
    169         width_src    = pBitmap->width;
    170         height_src   = pBitmap->height;
    171         colorkey = pBitmap->color_key;
    172         pitch_src = width_src; // equal to the source width
    173 
    174         // to YUV420 output
    175         outYUV = pToEncode->pBuffer;
    176         width_dst = width_src; // 1:1, set it to source
    177         height_dst = height_src; // 1:1, set it to source
    178         pitch_dst = pToEncode->width;
    179         Dst_height = pToEncode->height; // 1:1, so equal to source
    180 
    181         /* check buffer size */
    182         if ((pBitmap->bufSize < (pitch_src*height_src*2)) ||
    183                 (pToEncode->bufSize < ((pitch_dst*Dst_height*3) >> 1)))
    184         {
    185             return 0;
    186         }
    187 
    188         if (pCameraInput != NULL)   // use color key when camera input is present
    189         {
    190             BitmapInput->SetColorkey(colorkey);
    191         }
    192 
    193         if (!BitmapInput->Convert(inputRGB, outYUV))
    194         {
    195             return 0;
    196         }
    197     }
    198 
    199     return 1;
    200 }
    201 
    202 
    203 OSCL_EXPORT_REF int32 CPVVideoBlend :: InitOutputBlend(PVDimension *srcDecodeFrm,
    204         PVDimension *dstDecodeFrm,
    205         PVDimension *srcEncodeFrm,
    206         PVDimension *dstEncodeFrm,
    207         int32 rotateMirrorForEncFrm,
    208         int32 pitch)
    209 {
    210 
    211     mInitOutputBlend = false;
    212 
    213     if (srcDecodeFrm != NULL)
    214     {
    215         Src_width = srcDecodeFrm->width;
    216         Src_height = srcDecodeFrm->height;
    217         Src_pitch = Src_width;
    218 
    219         Dst_width = dstDecodeFrm->width;
    220         Dst_height = dstDecodeFrm->height;
    221         Dst_pitch = pitch;
    222 
    223         Rotation = 0;
    224 
    225         if (!DecoderOutput->Init(Src_width, Src_height, Src_pitch, Dst_width, Dst_height, Dst_pitch, Rotation))
    226         {
    227             return 0;
    228         }
    229 
    230         if (!DecoderOutput->SetMode(1))
    231         {
    232             return 0;
    233         }
    234     }
    235 
    236     if (srcEncodeFrm != NULL)
    237     {
    238         Src_width = srcEncodeFrm->width;
    239         Src_height = srcEncodeFrm->height;
    240         Src_pitch = Src_width;
    241 
    242         Dst_width = dstEncodeFrm->width;
    243         Dst_height = dstEncodeFrm->height;
    244         Dst_pitch = pitch;
    245 
    246         Rotation = rotateMirrorForEncFrm; // for clockwise rotation CC16.lib supports counter clock wise rotation
    247         switch (Rotation)
    248         {
    249             case 0  :
    250                 Rotation = 0;
    251                 break;
    252             case 1  :
    253                 Rotation = 3;
    254                 break;
    255             case 2  :
    256                 Rotation = 2;
    257                 break;
    258             case 3  :
    259                 Rotation = 1;
    260                 break;
    261             case 4  :
    262                 Rotation = 4;
    263                 break;
    264             case 5  :
    265                 Rotation = 7;
    266                 break;
    267             case 6  :
    268                 Rotation = 6;
    269                 break;
    270             case 7  :
    271                 Rotation = 5;
    272                 break;
    273             default :
    274                 break;
    275         }
    276 
    277 
    278         if (!EncoderInput->Init(Src_width, Src_height, Src_pitch, Dst_width, Dst_height, Dst_pitch, Rotation))
    279         {
    280             return 0;
    281         }
    282         if (!EncoderInput->SetMode(1))
    283         {
    284             return 0;
    285         }
    286     }
    287 
    288     mInitOutputBlend = true;
    289 
    290     return 1;
    291 }
    292 
    293 
    294 OSCL_EXPORT_REF int32 CPVVideoBlend :: BlendOutput(PVBlendFrame *pFromDecode, PVCoordinate *pos1,
    295         PVBlendFrame *pToEncode, PVCoordinate *pos2,
    296         PVBitmap *pDropDownMenu, PVCoordinate *pos3,
    297         uint32 changeOutputOrder,
    298         PVBitmap *pDisplayOutput)
    299 {
    300 
    301     uint8 *yuvBuf[3], *yuvBufDec[3], *rgbBuf = NULL, *temprgbBuf;
    302     int32 srcFrameSizeEnc = 0;
    303     int32 srcFrameSizeDec = 0;
    304 
    305     if (mInitOutputBlend == false)
    306     {
    307         return 0;
    308     }
    309 
    310     rgbBuf = pDisplayOutput->pBuffer;
    311 
    312     if (pToEncode)
    313     {
    314         srcFrameSizeEnc = pToEncode->width * pToEncode->height;
    315     }
    316 
    317     if (pFromDecode)
    318     {
    319         srcFrameSizeDec = pFromDecode->width * pFromDecode->height;
    320     }
    321 
    322     if (changeOutputOrder)
    323     {
    324         if (pToEncode != NULL)
    325         {
    326             yuvBuf[0] = pToEncode->pBuffer;
    327             yuvBuf[1] = yuvBuf[0] + srcFrameSizeEnc;
    328             yuvBuf[2] = yuvBuf[1] + srcFrameSizeEnc / 4;
    329             EncoderInput->Convert(yuvBuf, rgbBuf + (pos2->y * pDisplayOutput->width + pos2->x)*2);
    330         }
    331         if (pFromDecode != NULL)
    332         {
    333             yuvBufDec[0] = pFromDecode->pBuffer;
    334             yuvBufDec[1] = yuvBufDec[0] + srcFrameSizeDec;
    335             yuvBufDec[2] = yuvBufDec[1] + srcFrameSizeDec / 4;
    336             DecoderOutput->Convert(yuvBufDec, rgbBuf + (pos1->y * pDisplayOutput->width + pos1->x)*2);
    337         }
    338     }
    339     else
    340     {
    341         if (pFromDecode != NULL)
    342         {
    343             yuvBufDec[0] = pFromDecode->pBuffer;
    344             yuvBufDec[1] = yuvBufDec[0] + srcFrameSizeDec;
    345             yuvBufDec[2] = yuvBufDec[1] + srcFrameSizeDec / 4;
    346             DecoderOutput->Convert(yuvBufDec, rgbBuf + (pos1->y * pDisplayOutput->width + pos1->x)*2);
    347         }
    348         if (pToEncode != NULL)
    349         {
    350             yuvBuf[0] = pToEncode->pBuffer;
    351             yuvBuf[1] = yuvBuf[0] + srcFrameSizeEnc;
    352             yuvBuf[2] = yuvBuf[1] + srcFrameSizeEnc / 4;
    353             EncoderInput->Convert(yuvBuf, rgbBuf + (pos2->y * pDisplayOutput->width + pos2->x)*2);
    354         }
    355     }
    356 
    357     if (pDropDownMenu != NULL)
    358     {
    359         temprgbBuf = pDropDownMenu->pBuffer ;
    360         rgbBuf += (pos3->y * pDisplayOutput->width + pos3->x) * 2;
    361         for (int i = 0; i < pDropDownMenu->height; i++)
    362         {
    363             for (int j = 0; j < pDropDownMenu->width*2; j++)
    364             {
    365                 *rgbBuf++ = *temprgbBuf++;
    366             }
    367 
    368             rgbBuf += (Dst_pitch * 2) - (pDropDownMenu->width * 2);
    369         }
    370     }
    371 
    372     return 1;
    373 }
    374 
    375