hevc_utils.cpp revision a66301743224ed885fc1b5275acd16f4843a03f5
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 "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
64This section contains definitions for constants, macros, types, variables
65and other items needed by this module.
66
67========================================================================== */
68
69HEVC_Utils::HEVC_Utils()
70{
71    initialize_frame_checking_environment();
72}
73
74HEVC_Utils::~HEVC_Utils()
75{
76}
77
78/***********************************************************************/
79/*
80FUNCTION:
81HEVC_Utils::initialize_frame_checking_environment
82
83DESCRIPTION:
84Extract RBSP data from a NAL
85
86INPUT/OUTPUT PARAMETERS:
87None
88
89RETURN VALUE:
90boolean
91
92SIDE EFFECTS:
93None.
94 */
95/***********************************************************************/
96void 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/*===========================================================================
104FUNCTION:
105HEVC_Utils::iSNewFrame
106
107DESCRIPTION:
108Returns true if NAL parsing successfull otherwise false.
109
110INPUT/OUTPUT PARAMETERS:
111<In>
112buffer : buffer containing start code or nal length + NAL units
113buffer_length : the length of the NAL buffer
114start_code : If true, start code is detected,
115otherwise size nal length is detected
116size_of_nal_length_field: size of nal length field
117<out>
118isNewFrame: true if the NAL belongs to a differenet frame
119false if the NAL belongs to a current frame
120
121RETURN VALUE:
122boolean  true, if nal parsing is successful
123false, if the nal parsing has errors
124
125SIDE EFFECTS:
126None.
127===========================================================================*/
128bool 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