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