hevc_utils.cpp revision 61a2c6a19dbd06a317a419623020e02056661876
1/*--------------------------------------------------------------------------
2Copyright (c) 2013, The Linux Foundation. All rights reserved.
3
4Redistribution and use in source and binary forms, with or without
5modification, 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
16THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19NON-INFRINGEMENT ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
20CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
21EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
22PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
23OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
24WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
25OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
26ADVISED 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
66This section contains definitions for constants, macros, types, variables
67and other items needed by this module.
68
69========================================================================== */
70
71HEVC_Utils::HEVC_Utils()
72{
73    initialize_frame_checking_environment();
74}
75
76HEVC_Utils::~HEVC_Utils()
77{
78}
79
80/***********************************************************************/
81/*
82FUNCTION:
83HEVC_Utils::initialize_frame_checking_environment
84
85DESCRIPTION:
86Extract RBSP data from a NAL
87
88INPUT/OUTPUT PARAMETERS:
89None
90
91RETURN VALUE:
92boolean
93
94SIDE EFFECTS:
95None.
96 */
97/***********************************************************************/
98void 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/*===========================================================================
106FUNCTION:
107HEVC_Utils::iSNewFrame
108
109DESCRIPTION:
110Returns true if NAL parsing successfull otherwise false.
111
112INPUT/OUTPUT PARAMETERS:
113<In>
114buffer : buffer containing start code or nal length + NAL units
115buffer_length : the length of the NAL buffer
116start_code : If true, start code is detected,
117otherwise size nal length is detected
118size_of_nal_length_field: size of nal length field
119<out>
120isNewFrame: true if the NAL belongs to a differenet frame
121false if the NAL belongs to a current frame
122
123RETURN VALUE:
124boolean  true, if nal parsing is successful
125false, if the nal parsing has errors
126
127SIDE EFFECTS:
128None.
129===========================================================================*/
130bool 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