1 /*--------------------------------------------------------------------------
2 Copyright (c) 2010-2015, The Linux Foundation. All rights reserved.
3 
4 Redistribution and use in source and binary forms, with or without
5 modification, 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 
16 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19 NON-INFRINGEMENT ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
20 CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
21 EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
22 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
23 OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
24 WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
25 OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
26 ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 --------------------------------------------------------------------------*/
28 
29 #include "extra_data_handler.h"
30 
31 int debug_level = PRIO_ERROR;
32 
extra_data_handler()33 extra_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 
~extra_data_handler()42 extra_data_handler::~extra_data_handler()
43 {
44     if (rbsp_buf) {
45         free(rbsp_buf);
46         rbsp_buf = NULL;
47     }
48 }
49 
d_u(OMX_U32 num_bits)50 OMX_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 
d_ue()86 OMX_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 
parse_frame_pack(void)102 OMX_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 
parse_rbsp(OMX_U8 * buf,OMX_U32 len)135 OMX_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 }
parse_sei(OMX_U8 * buffer,OMX_U32 buffer_length)178 OMX_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 
parse_ltrinfo(OMX_OTHER_EXTRADATATYPE * pExtra)240 OMX_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   ======================================================================*/
parse_sliceinfo(OMX_BUFFERHEADERTYPE * pBufHdr,OMX_OTHER_EXTRADATATYPE * pExtra)257 OMX_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 
parse_extra_data(OMX_BUFFERHEADERTYPE * buf_hdr)305 OMX_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 
get_frame_pack_data(OMX_QCOM_FRAME_PACK_ARRANGEMENT * frame_pack)365 OMX_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 
set_frame_pack_data(OMX_QCOM_FRAME_PACK_ARRANGEMENT * frame_pack)374 OMX_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 
e_u(OMX_U32 symbol,OMX_U32 num_bits)385 OMX_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 
e_ue(OMX_U32 symbol)418 OMX_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 
create_frame_pack()436 OMX_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 
create_rbsp(OMX_U8 * buf,OMX_U32 nalu_type)468 OMX_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 
create_sei(OMX_U8 * buffer)500 OMX_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 
create_extra_data(OMX_BUFFERHEADERTYPE * buf_hdr)531 OMX_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