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