Home | History | Annotate | Download | only in src
      1 /*--------------------------------------------------------------------------
      2 Copyright (c) 2013, The Linux Foundation. All rights reserved.
      3 
      4 Redistribution and use in source and binary forms, with or without
      5 modification, are permitted provided that the following conditions are met:
      6     * Redistributions of source code must retain the above copyright
      7       notice, this list of conditions and the following disclaimer.
      8     * Redistributions in binary form must reproduce the above copyright
      9       notice, this list of conditions and the following disclaimer in the
     10       documentation and/or other materials provided with the distribution.
     11     * Neither the name of The Linux Foundation nor
     12       the names of its contributors may be used to endorse or promote
     13       products derived from this software without specific prior written
     14       permission.
     15 
     16 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
     17 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     18 IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
     19 NON-INFRINGEMENT ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
     20 CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
     21 EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
     22 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
     23 OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
     24 WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
     25 OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
     26 ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     27 --------------------------------------------------------------------------*/
     28 
     29 /*========================================================================
     30 
     31                       O p e n M M
     32          V i d e o   U t i l i t i e s
     33 
     34 *//** @file VideoUtils.cpp
     35   This module contains utilities and helper routines.
     36 
     37 @par EXTERNALIZED FUNCTIONS
     38 
     39 @par INITIALIZATION AND SEQUENCING REQUIREMENTS
     40   (none)
     41 
     42 *//*====================================================================== */
     43 
     44 /* =======================================================================
     45 
     46                      INCLUDE FILES FOR MODULE
     47 
     48 ========================================================================== */
     49 #include "hevc_utils.h"
     50 #include <string.h>
     51 #include <stdlib.h>
     52 #include <limits.h>
     53 #include <sys/time.h>
     54 #ifdef _ANDROID_
     55 #include <cutils/properties.h>
     56 #endif
     57 
     58 #define DEBUG_PRINT_LOW ALOGV
     59 #define DEBUG_PRINT_ERROR ALOGE
     60 
     61 
     62 /* =======================================================================
     63 
     64                 DEFINITIONS AND DECLARATIONS FOR MODULE
     65 
     66 This section contains definitions for constants, macros, types, variables
     67 and other items needed by this module.
     68 
     69 ========================================================================== */
     70 
     71 HEVC_Utils::HEVC_Utils()
     72 {
     73     initialize_frame_checking_environment();
     74 }
     75 
     76 HEVC_Utils::~HEVC_Utils()
     77 {
     78 }
     79 
     80 /***********************************************************************/
     81 /*
     82 FUNCTION:
     83 HEVC_Utils::initialize_frame_checking_environment
     84 
     85 DESCRIPTION:
     86 Extract RBSP data from a NAL
     87 
     88 INPUT/OUTPUT PARAMETERS:
     89 None
     90 
     91 RETURN VALUE:
     92 boolean
     93 
     94 SIDE EFFECTS:
     95 None.
     96  */
     97 /***********************************************************************/
     98 void HEVC_Utils::initialize_frame_checking_environment()
     99 {
    100     m_forceToStichNextNAL = false;
    101     m_au_data = false;
    102     nalu_type = NAL_UNIT_INVALID;
    103 }
    104 
    105 /*===========================================================================
    106 FUNCTION:
    107 HEVC_Utils::iSNewFrame
    108 
    109 DESCRIPTION:
    110 Returns true if NAL parsing successfull otherwise false.
    111 
    112 INPUT/OUTPUT PARAMETERS:
    113 <In>
    114 buffer : buffer containing start code or nal length + NAL units
    115 buffer_length : the length of the NAL buffer
    116 start_code : If true, start code is detected,
    117 otherwise size nal length is detected
    118 size_of_nal_length_field: size of nal length field
    119 <out>
    120 isNewFrame: true if the NAL belongs to a differenet frame
    121 false if the NAL belongs to a current frame
    122 
    123 RETURN VALUE:
    124 boolean  true, if nal parsing is successful
    125 false, if the nal parsing has errors
    126 
    127 SIDE EFFECTS:
    128 None.
    129 ===========================================================================*/
    130 bool HEVC_Utils::isNewFrame(OMX_BUFFERHEADERTYPE *p_buf_hdr,
    131         OMX_IN OMX_U32 size_of_nal_length_field,
    132         OMX_OUT OMX_BOOL &isNewFrame)
    133 {
    134     OMX_IN OMX_U8 *buffer = p_buf_hdr->pBuffer;
    135     OMX_IN OMX_U32 buffer_length = p_buf_hdr->nFilledLen;
    136     byte bFirstSliceInPic = 0;
    137 
    138     byte coef1=1, coef2=0, coef3=0;
    139     uint32 pos = 0;
    140     uint32 nal_len = buffer_length;
    141     uint32 sizeofNalLengthField = 0;
    142     uint32 zero_count;
    143     boolean start_code = (size_of_nal_length_field==0)?true:false;
    144 
    145     if (start_code) {
    146         // Search start_code_prefix_one_3bytes (0x000001)
    147         coef2 = buffer[pos++];
    148         coef3 = buffer[pos++];
    149 
    150         do {
    151             if (pos >= buffer_length) {
    152                 DEBUG_PRINT_ERROR("ERROR: In %s() - line %d", __func__, __LINE__);
    153                 return false;
    154             }
    155 
    156             coef1 = coef2;
    157             coef2 = coef3;
    158             coef3 = buffer[pos++];
    159         } while (coef1 || coef2 || coef3 != 1);
    160     } else if (size_of_nal_length_field) {
    161         /* This is the case to play multiple NAL units inside each access unit*/
    162         /* Extract the NAL length depending on sizeOfNALength field */
    163         sizeofNalLengthField = size_of_nal_length_field;
    164         nal_len = 0;
    165 
    166         while (size_of_nal_length_field--) {
    167             nal_len |= buffer[pos++]<<(size_of_nal_length_field<<3);
    168         }
    169 
    170         if (nal_len >= buffer_length) {
    171             DEBUG_PRINT_ERROR("ERROR: In %s() - line %d", __func__, __LINE__);
    172             return false;
    173         }
    174     }
    175 
    176     if (nal_len > buffer_length) {
    177         DEBUG_PRINT_ERROR("ERROR: In %s() - line %d", __func__, __LINE__);
    178         return false;
    179     }
    180 
    181     if (pos + 2 > (nal_len + sizeofNalLengthField)) {
    182         DEBUG_PRINT_ERROR("ERROR: In %s() - line %d", __func__, __LINE__);
    183         return false;
    184     }
    185 
    186     nalu_type = (buffer[pos] & 0x7E)>>1 ;      //=== nal_unit_type
    187 
    188     DEBUG_PRINT_LOW("\n@#@# Pos = %x NalType = %x buflen = %d", pos-1, nalu_type, buffer_length);
    189 
    190     isNewFrame =  OMX_FALSE;
    191 
    192     if (nalu_type == NAL_UNIT_VPS ||
    193             nalu_type == NAL_UNIT_SPS ||
    194             nalu_type == NAL_UNIT_PPS ||
    195             nalu_type == NAL_UNIT_SEI) {
    196         DEBUG_PRINT_LOW("\n Non-AU boundary with NAL type %d", nalu_type);
    197 
    198         if (m_au_data) {
    199             isNewFrame = OMX_TRUE;
    200             m_au_data = false;
    201         }
    202 
    203         m_forceToStichNextNAL = true;
    204     } else if (nalu_type <= NAL_UNIT_RESERVED_23) {
    205         DEBUG_PRINT_LOW("\n AU Boundary with NAL type %d ",nal_unit.nalu_type);
    206 
    207         if (!m_forceToStichNextNAL) {
    208             bFirstSliceInPic = ((buffer[pos+2] & 0x80)>>7);
    209 
    210             if (bFirstSliceInPic) {    //=== first_ctb_in_slice is only 1'b1  coded tree block
    211                 DEBUG_PRINT_LOW("Found a New Frame due to 1st coded tree block");
    212                 isNewFrame = OMX_TRUE;
    213             }
    214         }
    215 
    216         m_au_data = true;
    217         m_forceToStichNextNAL = false;
    218     }
    219 
    220     DEBUG_PRINT_LOW("get_HEVC_nal_type - newFrame value %d\n",isNewFrame);
    221     return true;
    222 }
    223 
    224