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 #ifndef OSCL_BASE_H_INCLUDED 19 #include "oscl_base.h" 20 #endif 21 22 #include "mpeg4_dec.h" 23 #include "oscl_mem.h" 24 #include "omx_mpeg4_component.h" 25 26 27 #define MAX_LAYERS 1 28 #define PVH263DEFAULTHEIGHT 288 29 #define PVH263DEFAULTWIDTH 352 30 31 #include <utils/Log.h> 32 #undef LOG_TAG 33 #define LOG_TAG "SW_DEC" 34 // from m4v_config_parser.h 35 OSCL_IMPORT_REF int16 iGetM4VConfigInfo(uint8 *buffer, int32 length, int32 *width, int32 *height, int32 *, int32 *); 36 37 Mpeg4Decoder_OMX::Mpeg4Decoder_OMX() 38 { 39 pFrame0 = NULL; 40 pFrame1 = NULL; 41 42 iDisplay_Width = 0; 43 iDisplay_Height = 0; 44 45 VO_START_CODE1[0] = 0x00; 46 VO_START_CODE1[1] = 0x00; 47 VO_START_CODE1[2] = 0x01; 48 VO_START_CODE1[3] = 0x00; 49 50 VOSH_START_CODE1[0] = 0x00; 51 VOSH_START_CODE1[1] = 0x00; 52 VOSH_START_CODE1[2] = 0x01; 53 VOSH_START_CODE1[3] = 0xB0; 54 55 VOP_START_CODE1[0] = 0x00; 56 VOP_START_CODE1[1] = 0x00; 57 VOP_START_CODE1[2] = 0x01; 58 VOP_START_CODE1[3] = 0xB6; 59 60 H263_START_CODE1[0] = 0x00; 61 H263_START_CODE1[1] = 0x00; 62 H263_START_CODE1[2] = 0x80; 63 64 } 65 66 67 /* Initialization routine */ 68 OMX_ERRORTYPE Mpeg4Decoder_OMX::Mp4DecInit() 69 { 70 Mpeg4InitCompleteFlag = OMX_FALSE; 71 return OMX_ErrorNone; 72 } 73 74 75 /*Decode routine */ 76 OMX_BOOL Mpeg4Decoder_OMX::Mp4DecodeVideo(OMX_U8* aOutBuffer, OMX_U32* aOutputLength, 77 OMX_U8** aInputBuf, OMX_U32* aInBufSize, 78 OMX_PARAM_PORTDEFINITIONTYPE* aPortParam, 79 OMX_S32* aFrameCount, OMX_BOOL aMarkerFlag, OMX_BOOL *aResizeFlag) 80 { 81 OMX_BOOL Status = OMX_TRUE; 82 OMX_S32 OldWidth, OldHeight, OldFrameSize; 83 84 OldWidth = aPortParam->format.video.nFrameWidth; 85 OldHeight = aPortParam->format.video.nFrameHeight; 86 *aResizeFlag = OMX_FALSE; 87 88 #ifdef _DEBUG 89 static OMX_U32 FrameCount = 0; 90 #endif 91 uint32 UseExtTimestamp = 0; 92 uint32 TimeStamp; 93 //OMX_S32 MaxSize = BIT_BUFF_SIZE; 94 OMX_S32 FrameSize, InputSize, InitSize; 95 OMX_U8* pTempFrame, *pSrc[3]; 96 97 if (Mpeg4InitCompleteFlag == OMX_FALSE) 98 { 99 if (!aMarkerFlag) 100 { 101 InitSize = GetVideoHeader(0, *aInputBuf, *aInBufSize); 102 } 103 else 104 { 105 InitSize = *aInBufSize; 106 } 107 108 if (PV_TRUE != InitializeVideoDecode(&iDisplay_Width, &iDisplay_Height, 109 aInputBuf, (OMX_S32*)aInBufSize, MPEG4_MODE)) 110 return OMX_FALSE; 111 112 Mpeg4InitCompleteFlag = OMX_TRUE; 113 aPortParam->format.video.nFrameWidth = iDisplay_Width; 114 aPortParam->format.video.nFrameHeight = iDisplay_Height; 115 116 OMX_U32 min_stride = ((aPortParam->format.video.nFrameWidth + 15) & (~15)); 117 OMX_U32 min_sliceheight = ((aPortParam->format.video.nFrameHeight + 15) & (~15)); 118 119 120 aPortParam->format.video.nStride = min_stride; 121 aPortParam->format.video.nSliceHeight = min_sliceheight; 122 123 124 // finally, compute the new minimum buffer size. 125 126 // Decoder components always output YUV420 format 127 aPortParam->nBufferSize = (aPortParam->format.video.nSliceHeight * aPortParam->format.video.nStride * 3) >> 1; 128 129 130 if ((iDisplay_Width != OldWidth) || (iDisplay_Height != OldHeight)) 131 *aResizeFlag = OMX_TRUE; 132 133 *aFrameCount = 1; 134 *aInBufSize -= InitSize; 135 return OMX_TRUE; 136 } 137 138 //MaxSize = *aInBufSize; 139 140 if ((*(OMX_S32*)aInBufSize) <= 0) 141 { 142 return OMX_FALSE; 143 } 144 145 TimeStamp = 0xFFFFFFFF; 146 InputSize = *aInBufSize; 147 148 // in case of H263, read the 1st frame to find out the sizes (use the m4v_config) 149 if ((0 == *aFrameCount) && (H263_MODE == CodecMode)) 150 { 151 int32 aligned_width, aligned_height; 152 int32 display_width, display_height; 153 154 if (iGetM4VConfigInfo(*aInputBuf, *aInBufSize, &aligned_width, &aligned_height, &display_width, &display_height)) 155 { 156 return OMX_FALSE; 157 } 158 159 iDisplay_Width = display_width; 160 iDisplay_Height = display_height; 161 aPortParam->format.video.nFrameWidth = iDisplay_Width; // use non 16byte aligned values (display_width) for H263 162 aPortParam->format.video.nFrameHeight = iDisplay_Height; // like in the case of M4V (PVGetVideoDimensions also returns display_width/height) 163 164 OMX_U32 min_stride = ((aPortParam->format.video.nFrameWidth + 15) & (~15)); 165 OMX_U32 min_sliceheight = ((aPortParam->format.video.nFrameHeight + 15) & (~15)); 166 167 168 aPortParam->format.video.nStride = min_stride; 169 aPortParam->format.video.nSliceHeight = min_sliceheight; 170 171 // finally, compute the new minimum buffer size. 172 173 // Decoder components always output YUV420 format 174 aPortParam->nBufferSize = (aPortParam->format.video.nSliceHeight * aPortParam->format.video.nStride * 3) >> 1; 175 176 177 if ((iDisplay_Width != OldWidth) || (iDisplay_Height != OldHeight)) 178 *aResizeFlag = OMX_TRUE; 179 180 *aFrameCount = 1; 181 return OMX_TRUE; 182 } 183 184 Status = (OMX_BOOL) PVDecodeVideoFrame(&VideoCtrl, aInputBuf, 185 &TimeStamp, 186 (int32*)aInBufSize, 187 &UseExtTimestamp, 188 (OMX_U8*) pFrame0); 189 190 if (Status == PV_TRUE) 191 { 192 193 #ifdef _DEBUG 194 //printf("Frame number %d\n", ++FrameCount); 195 #endif 196 // advance input buffer ptr 197 *aInputBuf += (InputSize - *aInBufSize); 198 199 pTempFrame = (OMX_U8*) pFrame0; 200 pFrame0 = (OMX_U8*) pFrame1; 201 pFrame1 = (OMX_U8*) pTempFrame; 202 203 int32 display_width, display_height; 204 PVGetVideoDimensions(&VideoCtrl, &display_width, &display_height); 205 iDisplay_Width = display_width; 206 iDisplay_Height = display_height; 207 if ((iDisplay_Width != OldWidth) || (iDisplay_Height != OldHeight)) 208 { 209 210 aPortParam->format.video.nFrameWidth = iDisplay_Width; 211 aPortParam->format.video.nFrameHeight = iDisplay_Height; 212 213 OMX_U32 min_stride = ((aPortParam->format.video.nFrameWidth + 15) & (~15)); 214 OMX_U32 min_sliceheight = ((aPortParam->format.video.nFrameHeight + 15) & (~15)); 215 216 217 aPortParam->format.video.nStride = min_stride; 218 aPortParam->format.video.nSliceHeight = min_sliceheight; 219 220 // finally, compute the new minimum buffer size. 221 222 // Decoder components always output YUV420 format 223 aPortParam->nBufferSize = (aPortParam->format.video.nSliceHeight * aPortParam->format.video.nStride * 3) >> 1; 224 225 *aResizeFlag = OMX_TRUE; 226 } 227 FrameSize = (((iDisplay_Width + 15) >> 4) << 4) * (((iDisplay_Height + 15) >> 4) << 4); 228 OldFrameSize = (((OldWidth + 15) >> 4) << 4) * (((OldHeight + 15) >> 4) << 4); 229 230 // THIS SHOULD NEVER HAPPEN, but just in case 231 // check so to not write a larger output into a smaller buffer 232 if (FrameSize <= OldFrameSize) 233 { 234 *aOutputLength = (FrameSize * 3) >> 1; 235 236 pSrc[0] = VideoCtrl.outputFrame; 237 pSrc[1] = pSrc[0] + FrameSize; 238 pSrc[2] = pSrc[0] + FrameSize + FrameSize / 4; 239 240 *aOutputLength = (FrameSize * 3) >> 1; 241 242 oscl_memcpy(aOutBuffer, pSrc[0], FrameSize); 243 oscl_memcpy(aOutBuffer + FrameSize, pSrc[1], FrameSize >> 2); 244 oscl_memcpy(aOutBuffer + FrameSize + FrameSize / 4, pSrc[2], FrameSize >> 2); 245 } 246 else 247 { 248 *aOutputLength = 0; 249 } 250 251 (*aFrameCount)++; 252 } 253 else 254 { 255 *aInBufSize = InputSize; 256 *aOutputLength = 0; 257 } 258 259 return Status; 260 } 261 262 OMX_S32 Mpeg4Decoder_OMX::InitializeVideoDecode( 263 OMX_S32* aWidth, OMX_S32* aHeight, OMX_U8** aBuffer, OMX_S32* aSize, OMX_S32 mode) 264 { 265 OMX_U32 VideoDecOutputSize; 266 OMX_S32 OK = PV_TRUE; 267 CodecMode = MPEG4_MODE; 268 269 if (mode == MODE_H263) 270 { 271 LOGE("PV SW DECODER is used for H.263"); 272 CodecMode = H263_MODE; 273 } 274 else 275 { 276 LOGE("PV SW DECODER is used for MPEG4"); 277 } 278 279 OK = PVInitVideoDecoder(&VideoCtrl, aBuffer, (int32*) aSize, 1, 280 PVH263DEFAULTWIDTH, PVH263DEFAULTHEIGHT, CodecMode); 281 282 if (OK) 283 { 284 PVGetVideoDimensions(&VideoCtrl, (int32*) aWidth, (int32*) aHeight); 285 CodecMode = PVGetDecBitstreamMode(&VideoCtrl); 286 287 if (CodecMode == H263_MODE && (*aWidth == 0 || *aHeight == 0)) 288 { 289 *aWidth = PVH263DEFAULTWIDTH; 290 *aHeight = PVH263DEFAULTHEIGHT; 291 } 292 293 PVSetPostProcType(&VideoCtrl, 0); 294 VideoDecOutputSize = (((*aWidth + 15) & - 16) * ((*aHeight + 15) & - 16) * 3) / 2; 295 pFrame0 = (OMX_U8*) oscl_malloc(VideoDecOutputSize); 296 pFrame1 = (OMX_U8*) oscl_malloc(VideoDecOutputSize); 297 PVSetReferenceYUV(&VideoCtrl, pFrame1); 298 return PV_TRUE; 299 } 300 else 301 { 302 return PV_FALSE; 303 } 304 305 306 } 307 308 OMX_ERRORTYPE Mpeg4Decoder_OMX::Mp4DecDeinit() 309 { 310 OMX_BOOL Status; 311 312 if (pFrame0) 313 { 314 oscl_free(pFrame0); 315 pFrame0 = NULL; 316 } 317 if (pFrame1) 318 { 319 oscl_free(pFrame1); 320 pFrame1 = NULL; 321 } 322 323 Status = (OMX_BOOL) PVCleanUpVideoDecoder(&VideoCtrl); 324 if (Status != OMX_TRUE) 325 { 326 return OMX_ErrorUndefined; 327 } 328 return OMX_ErrorNone; 329 } 330 331 OMX_S32 Mpeg4Decoder_OMX::GetVideoHeader(int32 aLayer, uint8* aBuf, int32 aMaxSize) 332 { 333 OSCL_UNUSED_ARG(aLayer); 334 335 int32 count = 0; 336 char my_sc[4]; 337 338 uint8 *tmp_bs = aBuf; 339 340 oscl_memcpy(my_sc, tmp_bs, 4); 341 my_sc[3] &= 0xf0; 342 343 if (aMaxSize >= 4) 344 { 345 if (oscl_memcmp(my_sc, VOSH_START_CODE1, 4) && oscl_memcmp(my_sc, VO_START_CODE1, 4)) 346 { 347 count = 0; 348 iShortVideoHeader = OMX_TRUE; 349 } 350 else 351 { 352 count = 0; 353 iShortVideoHeader = FALSE; 354 while (oscl_memcmp(tmp_bs + count, VOP_START_CODE1, 4)) 355 { 356 count++; 357 if (count > 1000) 358 { 359 iShortVideoHeader = OMX_TRUE; 360 break; 361 } 362 } 363 if (iShortVideoHeader == OMX_TRUE) 364 { 365 count = 0; 366 while (oscl_memcmp(tmp_bs + count, H263_START_CODE1, 3)) 367 { 368 count++; 369 } 370 } 371 } 372 } 373 return count; 374 } 375 376