1/*--------------------------------------------------------------------------
2Copyright (c) 2010-2014, 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#include "extra_data_handler.h"
30
31int debug_level = PRIO_ERROR;
32
33extra_data_handler::extra_data_handler()
34{
35    rbsp_buf = (OMX_U8 *) calloc(1,100);
36    memset(&frame_packing_arrangement,0,sizeof(frame_packing_arrangement));
37    frame_packing_arrangement.cancel_flag = 1;
38    pack_sei = false;
39    sei_payload_type = -1;
40}
41
42extra_data_handler::~extra_data_handler()
43{
44    if (rbsp_buf) {
45        free(rbsp_buf);
46        rbsp_buf = NULL;
47    }
48}
49
50OMX_U32 extra_data_handler::d_u(OMX_U32 num_bits)
51{
52    OMX_U32 rem_bits = num_bits, bins = 0, shift = 0;
53
54    while (rem_bits >= bit_ptr) {
55        DEBUG_PRINT_LOW("In %s() bit_ptr/byte_ptr :%u/%u/%x", __func__, (unsigned int)bit_ptr,
56                (unsigned int)byte_ptr, rbsp_buf[byte_ptr]);
57        bins <<= shift;
58        shift = (8-bit_ptr);
59        bins |= ((rbsp_buf[byte_ptr] << shift) & 0xFF) >> shift;
60        rem_bits -= bit_ptr;
61        bit_ptr = 8;
62        byte_ptr ++;
63    }
64
65    DEBUG_PRINT_LOW("In %s() bit_ptr/byte_ptr :%u/%u/%x", __func__, (unsigned int)bit_ptr,
66            (unsigned int)byte_ptr, rbsp_buf[byte_ptr]);
67
68    if (rem_bits) {
69        bins <<= rem_bits;
70        bins |= ((rbsp_buf[byte_ptr] << (8-bit_ptr)) & 0xFF) >> (8-rem_bits);
71        bit_ptr -= rem_bits;
72
73        if (bit_ptr == 0) {
74            bit_ptr = 8;
75            byte_ptr++;
76        }
77    }
78
79    DEBUG_PRINT_LOW("In %s() bit_ptr/byte_ptr :%u/%u/%x", __func__, (unsigned int)bit_ptr,
80            (unsigned int)byte_ptr, rbsp_buf[byte_ptr]);
81
82    DEBUG_PRINT_LOW("In %s() bin/num_bits : %x/%u", __func__, (unsigned)bins, (unsigned int)num_bits);
83    return bins;
84}
85
86OMX_U32 extra_data_handler::d_ue()
87{
88    OMX_S32 lead_zeros = -1;
89    OMX_U32 symbol, bit;
90
91    do {
92        bit = d_u(1);
93        lead_zeros++;
94    } while (!bit);
95
96    symbol = ((1 << lead_zeros) - 1) + d_u(lead_zeros);
97
98    DEBUG_PRINT_LOW("In %s() symbol : %u", __func__, (unsigned int)symbol);
99    return symbol;
100}
101
102OMX_U32 extra_data_handler::parse_frame_pack(void)
103{
104    frame_packing_arrangement.id = d_ue();
105    frame_packing_arrangement.cancel_flag = d_u(1);
106
107    if (!frame_packing_arrangement.cancel_flag) {
108        frame_packing_arrangement.type = d_u(7);
109        frame_packing_arrangement.quincunx_sampling_flag = d_u(1);
110        frame_packing_arrangement.content_interpretation_type = d_u(6);
111        frame_packing_arrangement.spatial_flipping_flag = d_u(1);
112        frame_packing_arrangement.frame0_flipped_flag = d_u(1);
113        frame_packing_arrangement.field_views_flag = d_u(1);
114        frame_packing_arrangement.current_frame_is_frame0_flag = d_u(1);
115        frame_packing_arrangement.frame0_self_contained_flag = d_u(1);
116        frame_packing_arrangement.frame1_self_contained_flag = d_u(1);
117
118        if (!frame_packing_arrangement.quincunx_sampling_flag &&
119                frame_packing_arrangement.type != 5) {
120            frame_packing_arrangement.frame0_grid_position_x = d_u(4);
121            frame_packing_arrangement.frame0_grid_position_y = d_u(4);
122            frame_packing_arrangement.frame1_grid_position_x = d_u(4);
123            frame_packing_arrangement.frame1_grid_position_y = d_u(4);
124        }
125
126        frame_packing_arrangement.reserved_byte = d_u(8);
127        frame_packing_arrangement.repetition_period = d_ue();
128    }
129
130    frame_packing_arrangement.extension_flag = d_u(1);
131
132    return 1;
133}
134
135OMX_S32 extra_data_handler::parse_rbsp(OMX_U8 *buf, OMX_U32 len)
136{
137    OMX_U32 i = 3, j=0, startcode;
138    OMX_U32 nal_unit_type, nal_ref_idc, forbidden_zero_bit;
139
140    bit_ptr  = 8;
141    byte_ptr = 0;
142
143    startcode =  buf[0] << 16 | buf[1] <<8 | buf[2];
144
145    if (!startcode) {
146        startcode |= buf[i++];
147    }
148
149    if (startcode != H264_START_CODE) {
150        DEBUG_PRINT_ERROR("ERROR: In %s() Start code not found", __func__);
151        return -1;
152    }
153
154    forbidden_zero_bit = (buf[i] & 0x80) >>7;
155
156    if (forbidden_zero_bit) {
157        DEBUG_PRINT_ERROR("ERROR: In %s() Non-zero forbidden bit", __func__);
158        return -1;
159    }
160
161    nal_ref_idc = (buf[i] & 0x60) >>5;
162    DEBUG_PRINT_LOW("In %s() nal_ref_idc ; %u", __func__, (unsigned int)nal_ref_idc);
163
164    nal_unit_type = (buf[i++] & 0x1F);
165
166    while (i<len) {
167        if (!(buf[i] + buf[i+1]) && (buf[i+2] == H264_EMULATION_BYTE) &&
168                (i+2 < len)) {
169            rbsp_buf[j++] = buf[i++];
170            rbsp_buf[j++] = buf[i++];
171            i++;
172        } else
173            rbsp_buf[j++] = buf[i++];
174    }
175
176    return nal_unit_type;
177}
178OMX_S32 extra_data_handler::parse_sei(OMX_U8 *buffer, OMX_U32 buffer_length)
179{
180    OMX_U32 nal_unit_type, payload_type = 0, payload_size = 0;
181    OMX_U32 marker = 0, pad = 0xFF;
182
183    nal_unit_type = parse_rbsp(buffer, buffer_length);
184
185    if (nal_unit_type != NAL_TYPE_SEI) {
186        DEBUG_PRINT_ERROR("ERROR: In %s() - Non SEI NAL ", __func__);
187        return -1;
188    } else {
189
190        while (rbsp_buf[byte_ptr] == 0xFF)
191            payload_type += rbsp_buf[byte_ptr++];
192
193        payload_type += rbsp_buf[byte_ptr++];
194
195        DEBUG_PRINT_LOW("In %s() payload_type : %u", __func__, (unsigned int)payload_type);
196
197        while (rbsp_buf[byte_ptr] == 0xFF)
198            payload_size += rbsp_buf[byte_ptr++];
199
200        payload_size += rbsp_buf[byte_ptr++];
201
202        DEBUG_PRINT_LOW("In %s() payload_size : %u", __func__, (unsigned int)payload_size);
203
204        switch (payload_type) {
205            case SEI_PAYLOAD_FRAME_PACKING_ARRANGEMENT:
206                DEBUG_PRINT_LOW("In %s() Frame Packing SEI ", __func__);
207                parse_frame_pack();
208                break;
209            default:
210                DEBUG_PRINT_LOW("INFO: In %s() Not Supported SEI NAL ", __func__);
211                break;
212        }
213    }
214
215    if (bit_ptr != 8) {
216        marker = d_u(1);
217
218        if (marker) {
219            if (bit_ptr != 8) {
220                pad = d_u(bit_ptr);
221
222                if (pad) {
223                    DEBUG_PRINT_ERROR("ERROR: In %s() padding Bits Error in SEI",
224                            __func__);
225                    return -1;
226                }
227            }
228        } else {
229            DEBUG_PRINT_ERROR("ERROR: In %s() Marker Bit Error in SEI",
230                    __func__);
231            return -1;
232        }
233    }
234
235    DEBUG_PRINT_LOW("In %s() payload_size : %u/%u", __func__,
236            (unsigned int)payload_size, (unsigned int)byte_ptr);
237    return 1;
238}
239
240OMX_S32 extra_data_handler::parse_ltrinfo(OMX_OTHER_EXTRADATATYPE *pExtra)
241{
242    OMX_U32 *pLTR;
243    pExtra->eType = (OMX_EXTRADATATYPE)OMX_ExtraDataVideoLTRInfo;
244    pLTR = (OMX_U32* )pExtra + 5;
245    DEBUG_PRINT_HIGH("ExtraData LTR ID %u", (unsigned int)*pLTR);
246    return 0;
247}
248/*======================================================================
249  Slice Information will be available as below (each line is of 4 bytes)
250  | number of slices |
251  | 1st slice offset |
252  | 1st slice size   |
253  | ..               |
254  | Nth slice offset |
255  | Nth slice size   |
256  ======================================================================*/
257OMX_S32 extra_data_handler::parse_sliceinfo(
258        OMX_BUFFERHEADERTYPE *pBufHdr, OMX_OTHER_EXTRADATATYPE *pExtra)
259{
260    OMX_U32 slice_offset = 0, slice_size = 0, total_size = 0;
261    OMX_U8 *pBuffer = (OMX_U8 *)pBufHdr->pBuffer;
262    OMX_U32 *data = (OMX_U32 *)(void *)pExtra->data;
263    OMX_U32 num_slices = *data;
264    DEBUG_PRINT_LOW("number of slices = %u", (unsigned int)num_slices);
265
266    if ((4 + num_slices * 8) != (OMX_U32)pExtra->nDataSize) {
267        DEBUG_PRINT_ERROR("unknown error in slice info extradata");
268        return -1;
269    }
270
271    for (unsigned i = 0; i < num_slices; i++) {
272        slice_offset = (OMX_U32)(*(data + (i*2 + 1)));
273
274        if ((*(pBuffer + slice_offset + 0) != 0x00) ||
275                (*(pBuffer + slice_offset + 1) != 0x00) ||
276                (*(pBuffer + slice_offset + 2) != 0x00) ||
277                (*(pBuffer + slice_offset + 3) != H264_START_CODE)) {
278            DEBUG_PRINT_ERROR("found 0x%x instead of start code at offset[%u] "
279                    "for slice[%u]", (unsigned)(*(OMX_U32 *)(pBuffer + slice_offset)),
280                    (unsigned int)slice_offset, i);
281            return -1;
282        }
283
284        if (slice_offset != total_size) {
285            DEBUG_PRINT_ERROR("offset of slice number %d is not correct "
286                    "or previous slice size is not correct", i);
287            return -1;
288        }
289
290        slice_size = (OMX_U32)(*(data + (i*2 + 2)));
291        total_size += slice_size;
292        DEBUG_PRINT_LOW("slice number %d offset/size = %u/%u",
293                i, (unsigned int)slice_offset, (unsigned int)slice_size);
294    }
295
296    if (pBufHdr->nFilledLen != total_size) {
297        DEBUG_PRINT_ERROR("frame_size[%u] is not equal to "
298                "total slices size[%u]", (unsigned int)pBufHdr->nFilledLen, (unsigned int)total_size);
299        return -1;
300    }
301
302    return 0;
303}
304
305OMX_U32 extra_data_handler::parse_extra_data(OMX_BUFFERHEADERTYPE *buf_hdr)
306{
307    DEBUG_PRINT_LOW("In %s() flags: 0x%x", __func__, (unsigned)buf_hdr->nFlags);
308
309    if (buf_hdr->nFlags & OMX_BUFFERFLAG_EXTRADATA) {
310
311        OMX_OTHER_EXTRADATATYPE *extra_data = (OMX_OTHER_EXTRADATATYPE *)
312            ((unsigned long)(buf_hdr->pBuffer + buf_hdr->nOffset +
313                buf_hdr->nFilledLen + 3)&(~3));
314
315        while (extra_data &&
316                ((unsigned long)extra_data > (unsigned long)buf_hdr->pBuffer) &&
317                ((unsigned long)extra_data < (unsigned long)buf_hdr->pBuffer + buf_hdr->nAllocLen)) {
318
319            DEBUG_PRINT_LOW("extradata(%p): nSize = 0x%x, eType = 0x%x,"
320                    " nDataSize = 0x%x", extra_data, (unsigned int)extra_data->nSize,
321                    extra_data->eType, (unsigned int)extra_data->nDataSize);
322
323            if ((extra_data->eType == VDEC_EXTRADATA_NONE) ||
324                    (extra_data->eType == VEN_EXTRADATA_NONE)) {
325                DEBUG_PRINT_LOW("No more extradata available");
326                extra_data->eType = OMX_ExtraDataNone;
327                break;
328            } else if (extra_data->eType == VDEC_EXTRADATA_SEI) {
329                DEBUG_PRINT_LOW("Extradata SEI of size %u found, "
330                        "parsing it", (unsigned int)extra_data->nDataSize);
331                parse_sei(extra_data->data, extra_data->nDataSize);
332            } else if (extra_data->eType == VEN_EXTRADATA_QCOMFILLER) {
333                DEBUG_PRINT_LOW("Extradata Qcom Filler found, skip %u bytes",
334                        (unsigned int)extra_data->nSize);
335            } else if (extra_data->eType == VEN_EXTRADATA_SLICEINFO) {
336                DEBUG_PRINT_LOW("Extradata SliceInfo of size %u found, "
337                        "parsing it", (unsigned int)extra_data->nDataSize);
338                parse_sliceinfo(buf_hdr, extra_data);
339            }
340
341#ifndef _MSM8974_
342            else if (extra_data->eType == VEN_EXTRADATA_LTRINFO) {
343                DEBUG_PRINT_LOW("Extradata LTRInfo of size %d found, "
344                        "parsing it", extra_data->nDataSize);
345                parse_ltrinfo(extra_data);
346            }
347
348#endif
349            else {
350                DEBUG_PRINT_ERROR("Unknown extradata(%p) found, nSize = 0x%x, "
351                        "eType = 0x%x, nDataSize = 0x%x", extra_data,
352                        (unsigned int)extra_data->nSize, extra_data->eType, (unsigned int)extra_data->nDataSize);
353                buf_hdr->nFlags &= ~(OMX_BUFFERFLAG_EXTRADATA);
354                break;
355            }
356
357            extra_data = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) extra_data) +
358                    extra_data->nSize);
359        }
360    }
361
362    return 1;
363}
364
365OMX_U32 extra_data_handler::get_frame_pack_data(
366        OMX_QCOM_FRAME_PACK_ARRANGEMENT *frame_pack)
367{
368    DEBUG_PRINT_LOW("%s:%d get frame data", __func__, __LINE__);
369    memcpy(&frame_pack->id,&frame_packing_arrangement.id,
370            FRAME_PACK_SIZE*sizeof(OMX_U32));
371    return 1;
372}
373
374OMX_U32 extra_data_handler::set_frame_pack_data(OMX_QCOM_FRAME_PACK_ARRANGEMENT
375        *frame_pack)
376{
377    DEBUG_PRINT_LOW("%s:%d set frame data", __func__, __LINE__);
378    memcpy(&frame_packing_arrangement.id, &frame_pack->id,
379            FRAME_PACK_SIZE*sizeof(OMX_U32));
380    pack_sei = true;
381    sei_payload_type = SEI_PAYLOAD_FRAME_PACKING_ARRANGEMENT;
382    return 1;
383}
384
385OMX_U32 extra_data_handler::e_u(OMX_U32 symbol, OMX_U32 num_bits)
386{
387    OMX_U32 rem_bits = num_bits, shift;
388
389    DEBUG_PRINT_LOW("%s bin  : %x/%u", __func__, (unsigned)symbol, (unsigned int)num_bits);
390
391    while (rem_bits >= bit_ptr) {
392        shift = rem_bits - bit_ptr;
393        rbsp_buf[byte_ptr] |= (symbol >> shift);
394        symbol = (symbol << (32 - shift)) >> (32 - shift);
395        rem_bits -= bit_ptr;
396        DEBUG_PRINT_LOW("%sstream byte/rem_bits %x/%u", __func__,
397                (unsigned)rbsp_buf[byte_ptr], (unsigned int)rem_bits);
398        byte_ptr ++;
399        bit_ptr = 8;
400    }
401
402    if (rem_bits) {
403        shift = bit_ptr - rem_bits;
404        rbsp_buf[byte_ptr] |= (symbol << shift);
405        bit_ptr -= rem_bits;
406        DEBUG_PRINT_LOW("%s 2 stream byte/rem_bits %x/%u", __func__,
407                (unsigned)rbsp_buf[byte_ptr], (unsigned int)rem_bits);
408
409        if (bit_ptr == 0) {
410            bit_ptr = 8;
411            byte_ptr++;
412        }
413    }
414
415    return 1;
416}
417
418OMX_U32 extra_data_handler::e_ue(OMX_U32 symbol)
419{
420    OMX_U32 i, sym_len, sufix_len, info;
421    OMX_U32 nn =(symbol + 1) >> 1;
422
423    DEBUG_PRINT_LOW("%s bin  : %x", __func__, (unsigned)symbol);
424
425    for (i=0; i < 33 && nn != 0; i++)
426        nn >>= 1;
427
428    sym_len = ((i << 1) + 1);
429    info = symbol + 1 - (1 << i);
430    sufix_len = (1 << (sym_len >>1));
431    info = sufix_len | (info & (sufix_len - 1));
432    e_u(info, sym_len);
433    return 1;
434}
435
436OMX_U32 extra_data_handler::create_frame_pack()
437{
438    e_ue(frame_packing_arrangement.id);
439    e_u(frame_packing_arrangement.cancel_flag, 1);
440
441    if (!frame_packing_arrangement.cancel_flag) {
442        e_u(frame_packing_arrangement.type, 7);
443        e_u(frame_packing_arrangement.quincunx_sampling_flag, 1);
444        e_u(frame_packing_arrangement.content_interpretation_type, 6);
445        e_u(frame_packing_arrangement.spatial_flipping_flag, 1);
446        e_u(frame_packing_arrangement.frame0_flipped_flag, 1);
447        e_u(frame_packing_arrangement.field_views_flag, 1);
448        e_u(frame_packing_arrangement.current_frame_is_frame0_flag, 1);
449        e_u(frame_packing_arrangement.frame0_self_contained_flag, 1);
450        e_u(frame_packing_arrangement.frame1_self_contained_flag, 1);
451
452        if (!frame_packing_arrangement.quincunx_sampling_flag &&
453                frame_packing_arrangement.type != 5) {
454            e_u(frame_packing_arrangement.frame0_grid_position_x, 4);
455            e_u(frame_packing_arrangement.frame0_grid_position_y, 4);
456            e_u(frame_packing_arrangement.frame1_grid_position_x, 4);
457            e_u(frame_packing_arrangement.frame1_grid_position_y, 4);
458        }
459
460        e_u(frame_packing_arrangement.reserved_byte, 8);
461        e_ue(frame_packing_arrangement.repetition_period);
462    }
463
464    e_u(frame_packing_arrangement.extension_flag, 1);
465    return 1;
466}
467
468OMX_S32 extra_data_handler::create_rbsp(OMX_U8 *buf, OMX_U32 nalu_type)
469{
470    OMX_U32 i, j = 7;
471
472    for (i = 0; i < 3; i++)
473        *buf++ = 0x00;
474
475    *buf++ = H264_START_CODE;
476    *buf++ = nalu_type;
477    *buf++ = (sei_payload_type & 0x000000FF);
478    *buf++ = byte_ptr - 1; //payload will contain 1 byte of rbsp_trailing_bits
479    //that shouldn't be taken into account
480
481    for (i = 0; i < byte_ptr ; i += 2) {
482        *buf++ = rbsp_buf[i];
483        j++;
484
485        if (i+1 < byte_ptr) {
486            *buf++ = rbsp_buf[i+1];
487            j++;
488
489            if (!(rbsp_buf[i] + rbsp_buf[i+1])) {
490                *buf++ = H264_EMULATION_BYTE;
491                j++;
492            }
493        }
494    }
495
496    DEBUG_PRINT_LOW("%s rbsp length %u", __func__, (unsigned int)j);
497    return j;
498}
499
500OMX_U32 extra_data_handler::create_sei(OMX_U8 *buffer)
501{
502    OMX_U32 i, ret_val = 0;
503
504    byte_ptr = 0;
505    bit_ptr  = 8;
506
507    if (sei_payload_type == SEI_PAYLOAD_FRAME_PACKING_ARRANGEMENT) {
508        create_frame_pack();
509
510        if (bit_ptr != 8) {
511            e_u(1,1);
512
513            if (bit_ptr != 8)
514                e_u(0,bit_ptr);
515        }
516
517        //Payload will have been byte aligned by now,
518        //insert the rbsp trailing bits
519        e_u(1, 1);
520        e_u(0, 7);
521
522        ret_val = create_rbsp(buffer, NAL_TYPE_SEI);
523    }
524
525    pack_sei = false;
526    sei_payload_type = -1;
527
528    return ret_val;
529}
530
531OMX_U32 extra_data_handler::create_extra_data(OMX_BUFFERHEADERTYPE *buf_hdr)
532{
533    OMX_U8 *buffer = (OMX_U8 *) (buf_hdr->pBuffer +
534                buf_hdr->nOffset + buf_hdr->nFilledLen);
535    OMX_U32 msg_size;
536
537    if (buf_hdr->nFlags & OMX_BUFFERFLAG_CODECCONFIG) {
538        DEBUG_PRINT_LOW("%s:%d create extra data with config", __func__,
539                __LINE__);
540
541        if (pack_sei) {
542            msg_size = create_sei(buffer);
543
544            if ( msg_size > 0)
545                buf_hdr->nFilledLen += msg_size;
546        }
547    }
548
549    return 1;
550}
551
552