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 "vidc_debug.h"
     51 #include <string.h>
     52 #include <stdlib.h>
     53 #include <limits.h>
     54 #include <sys/time.h>
     55 #ifdef _ANDROID_
     56 #include <cutils/properties.h>
     57 #endif
     58 
     59 
     60 /* =======================================================================
     61 
     62                 DEFINITIONS AND DECLARATIONS FOR MODULE
     63 
     64 This section contains definitions for constants, macros, types, variables
     65 and other items needed by this module.
     66 
     67 ========================================================================== */
     68 
     69 HEVC_Utils::HEVC_Utils()
     70 {
     71     initialize_frame_checking_environment();
     72 }
     73 
     74 HEVC_Utils::~HEVC_Utils()
     75 {
     76 }
     77 
     78 /***********************************************************************/
     79 /*
     80 FUNCTION:
     81 HEVC_Utils::initialize_frame_checking_environment
     82 
     83 DESCRIPTION:
     84 Extract RBSP data from a NAL
     85 
     86 INPUT/OUTPUT PARAMETERS:
     87 None
     88 
     89 RETURN VALUE:
     90 boolean
     91 
     92 SIDE EFFECTS:
     93 None.
     94  */
     95 /***********************************************************************/
     96 void HEVC_Utils::initialize_frame_checking_environment()
     97 {
     98     m_forceToStichNextNAL = false;
     99     m_au_data = false;
    100     nalu_type = NAL_UNIT_INVALID;
    101 }
    102 
    103 /*===========================================================================
    104 FUNCTION:
    105 HEVC_Utils::iSNewFrame
    106 
    107 DESCRIPTION:
    108 Returns true if NAL parsing successfull otherwise false.
    109 
    110 INPUT/OUTPUT PARAMETERS:
    111 <In>
    112 buffer : buffer containing start code or nal length + NAL units
    113 buffer_length : the length of the NAL buffer
    114 start_code : If true, start code is detected,
    115 otherwise size nal length is detected
    116 size_of_nal_length_field: size of nal length field
    117 <out>
    118 isNewFrame: true if the NAL belongs to a differenet frame
    119 false if the NAL belongs to a current frame
    120 
    121 RETURN VALUE:
    122 boolean  true, if nal parsing is successful
    123 false, if the nal parsing has errors
    124 
    125 SIDE EFFECTS:
    126 None.
    127 ===========================================================================*/
    128 bool HEVC_Utils::isNewFrame(OMX_BUFFERHEADERTYPE *p_buf_hdr,
    129         OMX_IN OMX_U32 size_of_nal_length_field,
    130         OMX_OUT OMX_BOOL &isNewFrame)
    131 {
    132     OMX_IN OMX_U8 *buffer = p_buf_hdr->pBuffer;
    133     OMX_IN OMX_U32 buffer_length = p_buf_hdr->nFilledLen;
    134     byte bFirstSliceInPic = 0;
    135 
    136     byte coef1=1, coef2=0, coef3=0;
    137     uint32 pos = 0;
    138     uint32 nal_len = buffer_length;
    139     uint32 sizeofNalLengthField = 0;
    140     uint32 zero_count;
    141     boolean start_code = (size_of_nal_length_field==0)?true:false;
    142 
    143     if (start_code) {
    144         // Search start_code_prefix_one_3bytes (0x000001)
    145         coef2 = buffer[pos++];
    146         coef3 = buffer[pos++];
    147 
    148         do {
    149             if (pos >= buffer_length) {
    150                 DEBUG_PRINT_ERROR("ERROR: In %s() - line %d", __func__, __LINE__);
    151                 return false;
    152             }
    153 
    154             coef1 = coef2;
    155             coef2 = coef3;
    156             coef3 = buffer[pos++];
    157         } while (coef1 || coef2 || coef3 != 1);
    158     } else if (size_of_nal_length_field) {
    159         /* This is the case to play multiple NAL units inside each access unit*/
    160         /* Extract the NAL length depending on sizeOfNALength field */
    161         sizeofNalLengthField = size_of_nal_length_field;
    162         nal_len = 0;
    163 
    164         while (size_of_nal_length_field--) {
    165             nal_len |= buffer[pos++]<<(size_of_nal_length_field<<3);
    166         }
    167 
    168         if (nal_len >= buffer_length) {
    169             DEBUG_PRINT_ERROR("ERROR: In %s() - line %d", __func__, __LINE__);
    170             return false;
    171         }
    172     }
    173 
    174     if (nal_len > buffer_length) {
    175         DEBUG_PRINT_ERROR("ERROR: In %s() - line %d", __func__, __LINE__);
    176         return false;
    177     }
    178 
    179     if (pos + 2 > (nal_len + sizeofNalLengthField)) {
    180         DEBUG_PRINT_ERROR("ERROR: In %s() - line %d", __func__, __LINE__);
    181         return false;
    182     }
    183 
    184     nalu_type = (buffer[pos] & 0x7E)>>1 ;      //=== nal_unit_type
    185 
    186     DEBUG_PRINT_LOW("@#@# Pos = %x NalType = %x buflen = %u", pos-1, nalu_type, (unsigned int) buffer_length);
    187 
    188     isNewFrame =  OMX_FALSE;
    189 
    190     if (nalu_type == NAL_UNIT_VPS ||
    191             nalu_type == NAL_UNIT_SPS ||
    192             nalu_type == NAL_UNIT_PPS ||
    193             nalu_type == NAL_UNIT_SEI) {
    194         DEBUG_PRINT_LOW("Non-AU boundary with NAL type %d", nalu_type);
    195 
    196         if (m_au_data) {
    197             isNewFrame = OMX_TRUE;
    198             m_au_data = false;
    199         }
    200 
    201         m_forceToStichNextNAL = true;
    202     } else if (nalu_type <= NAL_UNIT_RESERVED_23) {
    203         DEBUG_PRINT_LOW("AU Boundary with NAL type %d ", nalu_type);
    204 
    205         if (!m_forceToStichNextNAL) {
    206             bFirstSliceInPic = ((buffer[pos+2] & 0x80)>>7);
    207 
    208             if (bFirstSliceInPic) {    //=== first_ctb_in_slice is only 1'b1  coded tree block
    209                 DEBUG_PRINT_LOW("Found a New Frame due to 1st coded tree block");
    210                 isNewFrame = OMX_TRUE;
    211             }
    212         }
    213 
    214         m_au_data = true;
    215         m_forceToStichNextNAL = false;
    216     }
    217 
    218     DEBUG_PRINT_LOW("get_HEVC_nal_type - newFrame value %d",isNewFrame);
    219     return true;
    220 }
    221 
    222