111e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel/*--------------------------------------------------------------------------
211e4d07ddf6a35f55d6ad06edb850b015218c7acThierry StrudelCopyright (c) 2010-2014, The Linux Foundation. All rights reserved.
311e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel
411e4d07ddf6a35f55d6ad06edb850b015218c7acThierry StrudelRedistribution and use in source and binary forms, with or without
511e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudelmodification, are permitted provided that the following conditions are met:
611e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel    * Redistributions of source code must retain the above copyright
711e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel      notice, this list of conditions and the following disclaimer.
811e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel    * Redistributions in binary form must reproduce the above copyright
911e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel      notice, this list of conditions and the following disclaimer in the
1011e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel      documentation and/or other materials provided with the distribution.
1111e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel    * Neither the name of The Linux Foundation nor
1211e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel      the names of its contributors may be used to endorse or promote
1311e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel      products derived from this software without specific prior written
1411e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel      permission.
1511e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel
1611e4d07ddf6a35f55d6ad06edb850b015218c7acThierry StrudelTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
1711e4d07ddf6a35f55d6ad06edb850b015218c7acThierry StrudelAND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
1811e4d07ddf6a35f55d6ad06edb850b015218c7acThierry StrudelIMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
1911e4d07ddf6a35f55d6ad06edb850b015218c7acThierry StrudelNON-INFRINGEMENT ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
2011e4d07ddf6a35f55d6ad06edb850b015218c7acThierry StrudelCONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
2111e4d07ddf6a35f55d6ad06edb850b015218c7acThierry StrudelEXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
2211e4d07ddf6a35f55d6ad06edb850b015218c7acThierry StrudelPROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
2311e4d07ddf6a35f55d6ad06edb850b015218c7acThierry StrudelOR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
2411e4d07ddf6a35f55d6ad06edb850b015218c7acThierry StrudelWHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
2511e4d07ddf6a35f55d6ad06edb850b015218c7acThierry StrudelOTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
2611e4d07ddf6a35f55d6ad06edb850b015218c7acThierry StrudelADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2711e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel--------------------------------------------------------------------------*/
2811e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel
29a5bf317aa35f90b6fcc533882760f86342b79547Thierry Strudel#include <inttypes.h>
30a5bf317aa35f90b6fcc533882760f86342b79547Thierry Strudel#include <cstddef>
31a5bf317aa35f90b6fcc533882760f86342b79547Thierry Strudel#include <qdMetaData.h>
32a5bf317aa35f90b6fcc533882760f86342b79547Thierry Strudel#include <gralloc_priv.h>
3311e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel#include "extra_data_handler.h"
3411e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel
3511e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudelint debug_level = PRIO_ERROR;
3611e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel
3711e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudelextra_data_handler::extra_data_handler()
3811e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel{
3911e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel    rbsp_buf = (OMX_U8 *) calloc(1,100);
4011e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel    memset(&frame_packing_arrangement,0,sizeof(frame_packing_arrangement));
4111e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel    frame_packing_arrangement.cancel_flag = 1;
4211e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel    pack_sei = false;
4311e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel    sei_payload_type = -1;
4411e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel}
4511e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel
4611e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudelextra_data_handler::~extra_data_handler()
4711e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel{
4811e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel    if (rbsp_buf) {
4911e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel        free(rbsp_buf);
5011e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel        rbsp_buf = NULL;
5111e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel    }
5211e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel}
5311e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel
5411e4d07ddf6a35f55d6ad06edb850b015218c7acThierry StrudelOMX_U32 extra_data_handler::d_u(OMX_U32 num_bits)
5511e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel{
5611e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel    OMX_U32 rem_bits = num_bits, bins = 0, shift = 0;
5711e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel
5811e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel    while (rem_bits >= bit_ptr) {
5911e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel        DEBUG_PRINT_LOW("In %s() bit_ptr/byte_ptr :%u/%u/%x", __func__, (unsigned int)bit_ptr,
6011e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel                (unsigned int)byte_ptr, rbsp_buf[byte_ptr]);
6111e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel        bins <<= shift;
6211e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel        shift = (8-bit_ptr);
6311e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel        bins |= ((rbsp_buf[byte_ptr] << shift) & 0xFF) >> shift;
6411e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel        rem_bits -= bit_ptr;
6511e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel        bit_ptr = 8;
6611e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel        byte_ptr ++;
6711e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel    }
6811e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel
6911e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel    DEBUG_PRINT_LOW("In %s() bit_ptr/byte_ptr :%u/%u/%x", __func__, (unsigned int)bit_ptr,
7011e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel            (unsigned int)byte_ptr, rbsp_buf[byte_ptr]);
7111e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel
7211e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel    if (rem_bits) {
7311e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel        bins <<= rem_bits;
7411e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel        bins |= ((rbsp_buf[byte_ptr] << (8-bit_ptr)) & 0xFF) >> (8-rem_bits);
7511e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel        bit_ptr -= rem_bits;
7611e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel
7711e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel        if (bit_ptr == 0) {
7811e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel            bit_ptr = 8;
7911e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel            byte_ptr++;
8011e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel        }
8111e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel    }
8211e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel
8311e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel    DEBUG_PRINT_LOW("In %s() bit_ptr/byte_ptr :%u/%u/%x", __func__, (unsigned int)bit_ptr,
8411e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel            (unsigned int)byte_ptr, rbsp_buf[byte_ptr]);
8511e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel
8611e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel    DEBUG_PRINT_LOW("In %s() bin/num_bits : %x/%u", __func__, (unsigned)bins, (unsigned int)num_bits);
8711e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel    return bins;
8811e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel}
8911e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel
9011e4d07ddf6a35f55d6ad06edb850b015218c7acThierry StrudelOMX_U32 extra_data_handler::d_ue()
9111e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel{
9211e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel    OMX_S32 lead_zeros = -1;
9311e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel    OMX_U32 symbol, bit;
9411e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel
9511e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel    do {
9611e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel        bit = d_u(1);
9711e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel        lead_zeros++;
9811e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel    } while (!bit);
9911e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel
10011e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel    symbol = ((1 << lead_zeros) - 1) + d_u(lead_zeros);
10111e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel
10211e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel    DEBUG_PRINT_LOW("In %s() symbol : %u", __func__, (unsigned int)symbol);
10311e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel    return symbol;
10411e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel}
10511e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel
10611e4d07ddf6a35f55d6ad06edb850b015218c7acThierry StrudelOMX_U32 extra_data_handler::parse_frame_pack(void)
10711e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel{
10811e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel    frame_packing_arrangement.id = d_ue();
10911e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel    frame_packing_arrangement.cancel_flag = d_u(1);
11011e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel
11111e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel    if (!frame_packing_arrangement.cancel_flag) {
11211e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel        frame_packing_arrangement.type = d_u(7);
11311e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel        frame_packing_arrangement.quincunx_sampling_flag = d_u(1);
11411e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel        frame_packing_arrangement.content_interpretation_type = d_u(6);
11511e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel        frame_packing_arrangement.spatial_flipping_flag = d_u(1);
11611e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel        frame_packing_arrangement.frame0_flipped_flag = d_u(1);
11711e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel        frame_packing_arrangement.field_views_flag = d_u(1);
11811e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel        frame_packing_arrangement.current_frame_is_frame0_flag = d_u(1);
11911e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel        frame_packing_arrangement.frame0_self_contained_flag = d_u(1);
12011e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel        frame_packing_arrangement.frame1_self_contained_flag = d_u(1);
12111e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel
12211e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel        if (!frame_packing_arrangement.quincunx_sampling_flag &&
12311e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel                frame_packing_arrangement.type != 5) {
12411e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel            frame_packing_arrangement.frame0_grid_position_x = d_u(4);
12511e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel            frame_packing_arrangement.frame0_grid_position_y = d_u(4);
12611e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel            frame_packing_arrangement.frame1_grid_position_x = d_u(4);
12711e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel            frame_packing_arrangement.frame1_grid_position_y = d_u(4);
12811e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel        }
12911e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel
13011e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel        frame_packing_arrangement.reserved_byte = d_u(8);
13111e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel        frame_packing_arrangement.repetition_period = d_ue();
13211e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel    }
13311e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel
13411e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel    frame_packing_arrangement.extension_flag = d_u(1);
13511e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel
13611e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel    return 1;
13711e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel}
13811e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel
13911e4d07ddf6a35f55d6ad06edb850b015218c7acThierry StrudelOMX_S32 extra_data_handler::parse_rbsp(OMX_U8 *buf, OMX_U32 len)
14011e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel{
14111e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel    OMX_U32 i = 3, j=0, startcode;
14211e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel    OMX_U32 nal_unit_type, nal_ref_idc, forbidden_zero_bit;
14311e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel
14411e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel    bit_ptr  = 8;
14511e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel    byte_ptr = 0;
14611e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel
14711e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel    startcode =  buf[0] << 16 | buf[1] <<8 | buf[2];
14811e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel
14911e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel    if (!startcode) {
15011e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel        startcode |= buf[i++];
15111e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel    }
15211e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel
15311e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel    if (startcode != H264_START_CODE) {
15411e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel        DEBUG_PRINT_ERROR("ERROR: In %s() Start code not found", __func__);
15511e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel        return -1;
15611e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel    }
15711e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel
15811e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel    forbidden_zero_bit = (buf[i] & 0x80) >>7;
15911e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel
16011e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel    if (forbidden_zero_bit) {
16111e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel        DEBUG_PRINT_ERROR("ERROR: In %s() Non-zero forbidden bit", __func__);
16211e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel        return -1;
16311e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel    }
16411e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel
16511e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel    nal_ref_idc = (buf[i] & 0x60) >>5;
16611e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel    DEBUG_PRINT_LOW("In %s() nal_ref_idc ; %u", __func__, (unsigned int)nal_ref_idc);
16711e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel
16811e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel    nal_unit_type = (buf[i++] & 0x1F);
16911e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel
17011e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel    while (i<len) {
17111e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel        if (!(buf[i] + buf[i+1]) && (buf[i+2] == H264_EMULATION_BYTE) &&
17211e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel                (i+2 < len)) {
17311e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel            rbsp_buf[j++] = buf[i++];
17411e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel            rbsp_buf[j++] = buf[i++];
17511e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel            i++;
17611e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel        } else
17711e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel            rbsp_buf[j++] = buf[i++];
17811e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel    }
17911e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel
18011e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel    return nal_unit_type;
18111e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel}
18211e4d07ddf6a35f55d6ad06edb850b015218c7acThierry StrudelOMX_S32 extra_data_handler::parse_sei(OMX_U8 *buffer, OMX_U32 buffer_length)
18311e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel{
18411e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel    OMX_U32 nal_unit_type, payload_type = 0, payload_size = 0;
18511e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel    OMX_U32 marker = 0, pad = 0xFF;
18611e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel
18711e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel    nal_unit_type = parse_rbsp(buffer, buffer_length);
18811e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel
18911e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel    if (nal_unit_type != NAL_TYPE_SEI) {
19011e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel        DEBUG_PRINT_ERROR("ERROR: In %s() - Non SEI NAL ", __func__);
19111e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel        return -1;
19211e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel    } else {
19311e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel
19411e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel        while (rbsp_buf[byte_ptr] == 0xFF)
19511e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel            payload_type += rbsp_buf[byte_ptr++];
19611e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel
19711e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel        payload_type += rbsp_buf[byte_ptr++];
19811e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel
19911e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel        DEBUG_PRINT_LOW("In %s() payload_type : %u", __func__, (unsigned int)payload_type);
20011e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel
20111e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel        while (rbsp_buf[byte_ptr] == 0xFF)
20211e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel            payload_size += rbsp_buf[byte_ptr++];
20311e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel
20411e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel        payload_size += rbsp_buf[byte_ptr++];
20511e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel
20611e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel        DEBUG_PRINT_LOW("In %s() payload_size : %u", __func__, (unsigned int)payload_size);
20711e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel
20811e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel        switch (payload_type) {
20911e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel            case SEI_PAYLOAD_FRAME_PACKING_ARRANGEMENT:
21011e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel                DEBUG_PRINT_LOW("In %s() Frame Packing SEI ", __func__);
21111e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel                parse_frame_pack();
21211e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel                break;
21311e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel            default:
21411e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel                DEBUG_PRINT_LOW("INFO: In %s() Not Supported SEI NAL ", __func__);
21511e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel                break;
21611e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel        }
21711e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel    }
21811e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel
21911e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel    if (bit_ptr != 8) {
22011e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel        marker = d_u(1);
22111e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel
22211e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel        if (marker) {
22311e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel            if (bit_ptr != 8) {
22411e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel                pad = d_u(bit_ptr);
22511e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel
22611e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel                if (pad) {
22711e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel                    DEBUG_PRINT_ERROR("ERROR: In %s() padding Bits Error in SEI",
22811e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel                            __func__);
22911e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel                    return -1;
23011e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel                }
23111e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel            }
23211e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel        } else {
23311e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel            DEBUG_PRINT_ERROR("ERROR: In %s() Marker Bit Error in SEI",
23411e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel                    __func__);
23511e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel            return -1;
23611e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel        }
23711e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel    }
23811e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel
23911e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel    DEBUG_PRINT_LOW("In %s() payload_size : %u/%u", __func__,
24011e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel            (unsigned int)payload_size, (unsigned int)byte_ptr);
24111e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel    return 1;
24211e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel}
24311e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel
24411e4d07ddf6a35f55d6ad06edb850b015218c7acThierry StrudelOMX_S32 extra_data_handler::parse_ltrinfo(OMX_OTHER_EXTRADATATYPE *pExtra)
24511e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel{
24611e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel    OMX_U32 *pLTR;
24711e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel    pExtra->eType = (OMX_EXTRADATATYPE)OMX_ExtraDataVideoLTRInfo;
24811e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel    pLTR = (OMX_U32* )pExtra + 5;
24911e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel    DEBUG_PRINT_HIGH("ExtraData LTR ID %u", (unsigned int)*pLTR);
25011e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel    return 0;
25111e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel}
25211e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel/*======================================================================
25311e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel  Slice Information will be available as below (each line is of 4 bytes)
25411e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel  | number of slices |
25511e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel  | 1st slice offset |
25611e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel  | 1st slice size   |
25711e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel  | ..               |
25811e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel  | Nth slice offset |
25911e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel  | Nth slice size   |
26011e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel  ======================================================================*/
26111e4d07ddf6a35f55d6ad06edb850b015218c7acThierry StrudelOMX_S32 extra_data_handler::parse_sliceinfo(
26211e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel        OMX_BUFFERHEADERTYPE *pBufHdr, OMX_OTHER_EXTRADATATYPE *pExtra)
26311e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel{
26411e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel    OMX_U32 slice_offset = 0, slice_size = 0, total_size = 0;
26511e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel    OMX_U8 *pBuffer = (OMX_U8 *)pBufHdr->pBuffer;
26611e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel    OMX_U32 *data = (OMX_U32 *)(void *)pExtra->data;
26711e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel    OMX_U32 num_slices = *data;
26811e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel    DEBUG_PRINT_LOW("number of slices = %u", (unsigned int)num_slices);
26911e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel
27011e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel    if ((4 + num_slices * 8) != (OMX_U32)pExtra->nDataSize) {
27111e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel        DEBUG_PRINT_ERROR("unknown error in slice info extradata");
27211e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel        return -1;
27311e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel    }
27411e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel
27511e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel    for (unsigned i = 0; i < num_slices; i++) {
27611e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel        slice_offset = (OMX_U32)(*(data + (i*2 + 1)));
27711e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel
27811e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel        if ((*(pBuffer + slice_offset + 0) != 0x00) ||
27911e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel                (*(pBuffer + slice_offset + 1) != 0x00) ||
28011e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel                (*(pBuffer + slice_offset + 2) != 0x00) ||
28111e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel                (*(pBuffer + slice_offset + 3) != H264_START_CODE)) {
28211e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel            DEBUG_PRINT_ERROR("found 0x%x instead of start code at offset[%u] "
28311e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel                    "for slice[%u]", (unsigned)(*(OMX_U32 *)(pBuffer + slice_offset)),
28411e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel                    (unsigned int)slice_offset, i);
28511e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel            return -1;
28611e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel        }
28711e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel
28811e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel        if (slice_offset != total_size) {
28911e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel            DEBUG_PRINT_ERROR("offset of slice number %d is not correct "
29011e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel                    "or previous slice size is not correct", i);
29111e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel            return -1;
29211e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel        }
29311e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel
29411e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel        slice_size = (OMX_U32)(*(data + (i*2 + 2)));
29511e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel        total_size += slice_size;
29611e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel        DEBUG_PRINT_LOW("slice number %d offset/size = %u/%u",
29711e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel                i, (unsigned int)slice_offset, (unsigned int)slice_size);
29811e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel    }
29911e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel
30011e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel    if (pBufHdr->nFilledLen != total_size) {
30111e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel        DEBUG_PRINT_ERROR("frame_size[%u] is not equal to "
30211e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel                "total slices size[%u]", (unsigned int)pBufHdr->nFilledLen, (unsigned int)total_size);
30311e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel        return -1;
30411e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel    }
30511e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel
30611e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel    return 0;
30711e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel}
30811e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel
30911e4d07ddf6a35f55d6ad06edb850b015218c7acThierry StrudelOMX_U32 extra_data_handler::parse_extra_data(OMX_BUFFERHEADERTYPE *buf_hdr)
31011e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel{
31111e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel    DEBUG_PRINT_LOW("In %s() flags: 0x%x", __func__, (unsigned)buf_hdr->nFlags);
31211e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel
31311e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel    if (buf_hdr->nFlags & OMX_BUFFERFLAG_EXTRADATA) {
31411e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel
31511e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel        OMX_OTHER_EXTRADATATYPE *extra_data = (OMX_OTHER_EXTRADATATYPE *)
31611e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel            ((unsigned long)(buf_hdr->pBuffer + buf_hdr->nOffset +
31711e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel                buf_hdr->nFilledLen + 3)&(~3));
31811e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel
31911e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel        while (extra_data &&
32011e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel                ((unsigned long)extra_data > (unsigned long)buf_hdr->pBuffer) &&
32111e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel                ((unsigned long)extra_data < (unsigned long)buf_hdr->pBuffer + buf_hdr->nAllocLen)) {
32211e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel
32311e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel            DEBUG_PRINT_LOW("extradata(%p): nSize = 0x%x, eType = 0x%x,"
32411e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel                    " nDataSize = 0x%x", extra_data, (unsigned int)extra_data->nSize,
32511e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel                    extra_data->eType, (unsigned int)extra_data->nDataSize);
32611e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel
32711e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel            if ((extra_data->eType == VDEC_EXTRADATA_NONE) ||
32811e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel                    (extra_data->eType == VEN_EXTRADATA_NONE)) {
32911e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel                DEBUG_PRINT_LOW("No more extradata available");
33011e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel                extra_data->eType = OMX_ExtraDataNone;
33111e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel                break;
33211e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel            } else if (extra_data->eType == VDEC_EXTRADATA_SEI) {
33311e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel                DEBUG_PRINT_LOW("Extradata SEI of size %u found, "
33411e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel                        "parsing it", (unsigned int)extra_data->nDataSize);
33511e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel                parse_sei(extra_data->data, extra_data->nDataSize);
33611e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel            } else if (extra_data->eType == VEN_EXTRADATA_QCOMFILLER) {
33711e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel                DEBUG_PRINT_LOW("Extradata Qcom Filler found, skip %u bytes",
33811e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel                        (unsigned int)extra_data->nSize);
33911e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel            } else if (extra_data->eType == VEN_EXTRADATA_SLICEINFO) {
34011e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel                DEBUG_PRINT_LOW("Extradata SliceInfo of size %u found, "
34111e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel                        "parsing it", (unsigned int)extra_data->nDataSize);
34211e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel                parse_sliceinfo(buf_hdr, extra_data);
34311e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel            }
34411e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel
34511e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel#ifndef _MSM8974_
34611e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel            else if (extra_data->eType == VEN_EXTRADATA_LTRINFO) {
34711e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel                DEBUG_PRINT_LOW("Extradata LTRInfo of size %d found, "
34811e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel                        "parsing it", extra_data->nDataSize);
34911e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel                parse_ltrinfo(extra_data);
35011e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel            }
35111e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel
35211e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel#endif
35311e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel            else {
35411e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel                DEBUG_PRINT_ERROR("Unknown extradata(%p) found, nSize = 0x%x, "
35511e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel                        "eType = 0x%x, nDataSize = 0x%x", extra_data,
35611e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel                        (unsigned int)extra_data->nSize, extra_data->eType, (unsigned int)extra_data->nDataSize);
35711e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel                buf_hdr->nFlags &= ~(OMX_BUFFERFLAG_EXTRADATA);
35811e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel                break;
35911e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel            }
36011e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel
36111e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel            extra_data = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) extra_data) +
36211e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel                    extra_data->nSize);
36311e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel        }
36411e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel    }
36511e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel
36611e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel    return 1;
36711e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel}
36811e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel
36911e4d07ddf6a35f55d6ad06edb850b015218c7acThierry StrudelOMX_U32 extra_data_handler::get_frame_pack_data(
37011e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel        OMX_QCOM_FRAME_PACK_ARRANGEMENT *frame_pack)
37111e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel{
37211e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel    DEBUG_PRINT_LOW("%s:%d get frame data", __func__, __LINE__);
37311e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel    memcpy(&frame_pack->id,&frame_packing_arrangement.id,
37411e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel            FRAME_PACK_SIZE*sizeof(OMX_U32));
37511e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel    return 1;
37611e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel}
37711e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel
37811e4d07ddf6a35f55d6ad06edb850b015218c7acThierry StrudelOMX_U32 extra_data_handler::set_frame_pack_data(OMX_QCOM_FRAME_PACK_ARRANGEMENT
37911e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel        *frame_pack)
38011e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel{
38111e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel    DEBUG_PRINT_LOW("%s:%d set frame data", __func__, __LINE__);
38211e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel    memcpy(&frame_packing_arrangement.id, &frame_pack->id,
38311e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel            FRAME_PACK_SIZE*sizeof(OMX_U32));
38411e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel    pack_sei = true;
38511e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel    sei_payload_type = SEI_PAYLOAD_FRAME_PACKING_ARRANGEMENT;
38611e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel    return 1;
38711e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel}
38811e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel
38911e4d07ddf6a35f55d6ad06edb850b015218c7acThierry StrudelOMX_U32 extra_data_handler::e_u(OMX_U32 symbol, OMX_U32 num_bits)
39011e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel{
39111e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel    OMX_U32 rem_bits = num_bits, shift;
39211e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel
39311e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel    DEBUG_PRINT_LOW("%s bin  : %x/%u", __func__, (unsigned)symbol, (unsigned int)num_bits);
39411e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel
39511e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel    while (rem_bits >= bit_ptr) {
39611e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel        shift = rem_bits - bit_ptr;
39711e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel        rbsp_buf[byte_ptr] |= (symbol >> shift);
39811e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel        symbol = (symbol << (32 - shift)) >> (32 - shift);
39911e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel        rem_bits -= bit_ptr;
40011e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel        DEBUG_PRINT_LOW("%sstream byte/rem_bits %x/%u", __func__,
40111e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel                (unsigned)rbsp_buf[byte_ptr], (unsigned int)rem_bits);
40211e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel        byte_ptr ++;
40311e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel        bit_ptr = 8;
40411e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel    }
40511e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel
40611e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel    if (rem_bits) {
40711e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel        shift = bit_ptr - rem_bits;
40811e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel        rbsp_buf[byte_ptr] |= (symbol << shift);
40911e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel        bit_ptr -= rem_bits;
41011e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel        DEBUG_PRINT_LOW("%s 2 stream byte/rem_bits %x/%u", __func__,
41111e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel                (unsigned)rbsp_buf[byte_ptr], (unsigned int)rem_bits);
41211e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel
41311e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel        if (bit_ptr == 0) {
41411e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel            bit_ptr = 8;
41511e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel            byte_ptr++;
41611e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel        }
41711e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel    }
41811e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel
41911e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel    return 1;
42011e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel}
42111e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel
42211e4d07ddf6a35f55d6ad06edb850b015218c7acThierry StrudelOMX_U32 extra_data_handler::e_ue(OMX_U32 symbol)
42311e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel{
42411e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel    OMX_U32 i, sym_len, sufix_len, info;
42511e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel    OMX_U32 nn =(symbol + 1) >> 1;
42611e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel
42711e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel    DEBUG_PRINT_LOW("%s bin  : %x", __func__, (unsigned)symbol);
42811e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel
42911e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel    for (i=0; i < 33 && nn != 0; i++)
43011e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel        nn >>= 1;
43111e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel
43211e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel    sym_len = ((i << 1) + 1);
43311e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel    info = symbol + 1 - (1 << i);
43411e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel    sufix_len = (1 << (sym_len >>1));
43511e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel    info = sufix_len | (info & (sufix_len - 1));
43611e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel    e_u(info, sym_len);
43711e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel    return 1;
43811e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel}
43911e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel
44011e4d07ddf6a35f55d6ad06edb850b015218c7acThierry StrudelOMX_U32 extra_data_handler::create_frame_pack()
44111e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel{
44211e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel    e_ue(frame_packing_arrangement.id);
44311e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel    e_u(frame_packing_arrangement.cancel_flag, 1);
44411e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel
44511e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel    if (!frame_packing_arrangement.cancel_flag) {
44611e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel        e_u(frame_packing_arrangement.type, 7);
44711e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel        e_u(frame_packing_arrangement.quincunx_sampling_flag, 1);
44811e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel        e_u(frame_packing_arrangement.content_interpretation_type, 6);
44911e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel        e_u(frame_packing_arrangement.spatial_flipping_flag, 1);
45011e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel        e_u(frame_packing_arrangement.frame0_flipped_flag, 1);
45111e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel        e_u(frame_packing_arrangement.field_views_flag, 1);
45211e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel        e_u(frame_packing_arrangement.current_frame_is_frame0_flag, 1);
45311e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel        e_u(frame_packing_arrangement.frame0_self_contained_flag, 1);
45411e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel        e_u(frame_packing_arrangement.frame1_self_contained_flag, 1);
45511e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel
45611e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel        if (!frame_packing_arrangement.quincunx_sampling_flag &&
45711e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel                frame_packing_arrangement.type != 5) {
45811e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel            e_u(frame_packing_arrangement.frame0_grid_position_x, 4);
45911e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel            e_u(frame_packing_arrangement.frame0_grid_position_y, 4);
46011e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel            e_u(frame_packing_arrangement.frame1_grid_position_x, 4);
46111e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel            e_u(frame_packing_arrangement.frame1_grid_position_y, 4);
46211e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel        }
46311e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel
46411e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel        e_u(frame_packing_arrangement.reserved_byte, 8);
46511e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel        e_ue(frame_packing_arrangement.repetition_period);
46611e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel    }
46711e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel
46811e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel    e_u(frame_packing_arrangement.extension_flag, 1);
46911e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel    return 1;
47011e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel}
47111e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel
47211e4d07ddf6a35f55d6ad06edb850b015218c7acThierry StrudelOMX_S32 extra_data_handler::create_rbsp(OMX_U8 *buf, OMX_U32 nalu_type)
47311e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel{
47411e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel    OMX_U32 i, j = 7;
47511e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel
47611e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel    for (i = 0; i < 3; i++)
47711e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel        *buf++ = 0x00;
47811e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel
47911e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel    *buf++ = H264_START_CODE;
48011e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel    *buf++ = nalu_type;
48111e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel    *buf++ = (sei_payload_type & 0x000000FF);
48211e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel    *buf++ = byte_ptr - 1; //payload will contain 1 byte of rbsp_trailing_bits
48311e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel    //that shouldn't be taken into account
48411e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel
48511e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel    for (i = 0; i < byte_ptr ; i += 2) {
48611e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel        *buf++ = rbsp_buf[i];
48711e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel        j++;
48811e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel
48911e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel        if (i+1 < byte_ptr) {
49011e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel            *buf++ = rbsp_buf[i+1];
49111e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel            j++;
49211e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel
49311e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel            if (!(rbsp_buf[i] + rbsp_buf[i+1])) {
49411e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel                *buf++ = H264_EMULATION_BYTE;
49511e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel                j++;
49611e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel            }
49711e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel        }
49811e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel    }
49911e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel
50011e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel    DEBUG_PRINT_LOW("%s rbsp length %u", __func__, (unsigned int)j);
50111e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel    return j;
50211e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel}
50311e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel
50411e4d07ddf6a35f55d6ad06edb850b015218c7acThierry StrudelOMX_U32 extra_data_handler::create_sei(OMX_U8 *buffer)
50511e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel{
50611e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel    OMX_U32 i, ret_val = 0;
50711e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel
50811e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel    byte_ptr = 0;
50911e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel    bit_ptr  = 8;
51011e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel
51111e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel    if (sei_payload_type == SEI_PAYLOAD_FRAME_PACKING_ARRANGEMENT) {
51211e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel        create_frame_pack();
51311e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel
51411e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel        if (bit_ptr != 8) {
51511e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel            e_u(1,1);
51611e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel
51711e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel            if (bit_ptr != 8)
51811e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel                e_u(0,bit_ptr);
51911e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel        }
52011e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel
52111e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel        //Payload will have been byte aligned by now,
52211e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel        //insert the rbsp trailing bits
52311e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel        e_u(1, 1);
52411e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel        e_u(0, 7);
52511e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel
52611e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel        ret_val = create_rbsp(buffer, NAL_TYPE_SEI);
52711e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel    }
52811e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel
52911e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel    pack_sei = false;
53011e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel    sei_payload_type = -1;
53111e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel
53211e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel    return ret_val;
53311e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel}
53411e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel
53511e4d07ddf6a35f55d6ad06edb850b015218c7acThierry StrudelOMX_U32 extra_data_handler::create_extra_data(OMX_BUFFERHEADERTYPE *buf_hdr)
53611e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel{
53711e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel    OMX_U8 *buffer = (OMX_U8 *) (buf_hdr->pBuffer +
53811e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel                buf_hdr->nOffset + buf_hdr->nFilledLen);
53911e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel    OMX_U32 msg_size;
54011e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel
54111e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel    if (buf_hdr->nFlags & OMX_BUFFERFLAG_CODECCONFIG) {
54211e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel        DEBUG_PRINT_LOW("%s:%d create extra data with config", __func__,
54311e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel                __LINE__);
54411e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel
54511e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel        if (pack_sei) {
54611e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel            msg_size = create_sei(buffer);
54711e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel
54811e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel            if ( msg_size > 0)
54911e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel                buf_hdr->nFilledLen += msg_size;
55011e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel        }
55111e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel    }
55211e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel
55311e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel    return 1;
55411e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel}
55511e4d07ddf6a35f55d6ad06edb850b015218c7acThierry Strudel
556