1 /***************************************************************************
2 \fn libvaEnc_plugin
3 \brief Plugin to use libva hw encoder (intel mostly)
4 -------------------
5
6 copyright : (C) 2018 by mean
7 email : fixounet@free.fr
8 ***************************************************************************/
9
10 /***************************************************************************
11 * *
12 * This program is free software; you can redistribute it and/or modify *
13 * it under the terms of the GNU General Public License as published by *
14 * the Free Software Foundation; either version 2 of the License, or *
15 * (at your option) any later version. *
16 * *
17 ***************************************************************************/
18 /***************************************************************************/
19 /* Derived from libva sample code */
20 /*
21 * Copyright (c) 2007-2013 Intel Corporation. All Rights Reserved.
22 *
23 * Permission is hereby granted, free of charge, to any person obtaining a
24 * copy of this software and associated documentation files (the
25 * "Software"), to deal in the Software without restriction, including
26 * without limitation the rights to use, copy, modify, merge, publish,
27 * distribute, sub license, and/or sell copies of the Software, and to
28 * permit persons to whom the Software is furnished to do so, subject to
29 * the following conditions:
30 *
31 * The above copyright notice and this permission notice (including the
32 * next paragraph) shall be included in all copies or substantial portions
33 * of the Software.
34 *
35 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
36 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
37 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
38 * IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
39 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
40 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
41 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
42 */
43 /***************************************************************************
44 * *
45 * This program is free software; you can redistribute it and/or modify *
46 * it under the terms of the GNU General Public License as published by *
47 * the Free Software Foundation; either version 2 of the License, or *
48 * (at your option) any later version. *
49 * *
50 ***************************************************************************/
51 #include "ADM_default.h"
52 #include "ADM_bitstream.h"
53 #include "ADM_coreVideoEncoder.h"
54 #include "ADM_videoInfoExtractor.h"
55
56
57 #include "va/va.h"
58 #include "va/va_enc_h264.h"
59 #include "ADM_coreLibVA_buffer.h"
60 #include "ADM_libVaEncodingContextH264.h"
61
62
63 /**
64 *
65 * @param header_buffer
66 * @return
67 */
build_packed_pic_buffer(vaBitstream * bs)68 bool ADM_vaEncodingContextH264AnnexB::build_packed_pic_buffer(vaBitstream *bs)
69 {
70 bs->startCodePrefix();
71 bs->nalHeader(NAL_REF_IDC_HIGH, NAL_PPS);
72 pps_rbsp(bs);
73 bs->startCodePrefix();
74 return true; // Offset
75 }
76
77 /**
78 *
79 * @param header_buffer
80 * @return
81 */
build_packed_seq_buffer(vaBitstream * bs)82 bool ADM_vaEncodingContextH264AnnexB::build_packed_seq_buffer(vaBitstream *bs)
83 {
84 bs->startCodePrefix();
85 bs->nalHeader(NAL_REF_IDC_HIGH, NAL_SPS);
86 sps_rbsp(bs);
87 bs->stop();
88 return true;
89 }
90
91 /**
92 *
93 * @param init_cpb_removal_length
94 * @param init_cpb_removal_delay
95 * @param init_cpb_removal_delay_offset
96 * @param cpb_removal_length
97 * @param cpb_removal_delay
98 * @param dpb_output_length
99 * @param dpb_output_delay
100 * @param sei_buffer
101 * @return
102 */
build_packed_sei_buffer_timing(vaBitstream * bs,unsigned int init_cpb_removal_length,unsigned int init_cpb_removal_delay,unsigned int init_cpb_removal_delay_offset,unsigned int cpb_removal_length,unsigned int cpb_removal_delay,unsigned int dpb_output_length,unsigned int dpb_output_delay)103 bool ADM_vaEncodingContextH264AnnexB::build_packed_sei_buffer_timing(vaBitstream *bs,
104 unsigned int init_cpb_removal_length,
105 unsigned int init_cpb_removal_delay,
106 unsigned int init_cpb_removal_delay_offset,
107 unsigned int cpb_removal_length,
108 unsigned int cpb_removal_delay,
109 unsigned int dpb_output_length,
110 unsigned int dpb_output_delay)
111 {
112 unsigned char *byte_buf;
113 int bp_byte_size, i, pic_byte_size;
114
115
116 // sei _bp
117 vaBitstream sei_bp;
118 sei_bp.put_ue(0);
119 sei_bp.put_ui(init_cpb_removal_delay, cpb_removal_length);
120 sei_bp.put_ui(init_cpb_removal_delay_offset, cpb_removal_length);
121 sei_bp.add1BitIfNotaligned();
122 sei_bp.stop();
123 bp_byte_size = (sei_bp.lengthInBits() + 7) / 8;
124
125 // sei_pic
126 vaBitstream sei_pic;
127
128 sei_pic.put_ui(cpb_removal_delay, cpb_removal_length);
129 sei_pic.put_ui(dpb_output_delay, dpb_output_length);
130 sei_pic.add1BitIfNotaligned();
131 sei_pic.stop();
132 pic_byte_size = (sei_bp.lengthInBits() + 7) / 8;
133 //--- nal
134 vaBitstream nal;
135
136 nal.startCodePrefix();
137 nal.nalHeader(NAL_REF_IDC_NONE, NAL_SEI);
138
139 /* Write the SEI buffer period data */
140 nal.put_ui(0, 8);
141 nal.put_ui(bp_byte_size, 8);
142
143
144 //------------ Merge-------------
145
146 byte_buf = sei_bp.getPointer();
147 for (i = 0; i < bp_byte_size; i++)
148 {
149 nal.put_ui(byte_buf[i], 8);
150 }
151
152 /* write the SEI timing data */
153 nal.put_ui(0x01, 8);
154 nal.put_ui(pic_byte_size, 8);
155
156 byte_buf = sei_pic.getPointer();
157 for (i = 0; i < pic_byte_size; i++)
158 {
159 nal.put_ui(byte_buf[i], 8);
160 }
161
162 nal.rbspTrailingBits();
163 nal.stop();
164 return true;
165 }
166
167 /**
168 *
169 * @param header_buffer
170 * @return
171 */
build_packed_slice_buffer(vaBitstream * bs)172 bool ADM_vaEncodingContextH264AnnexB::build_packed_slice_buffer(vaBitstream *bs)
173 {
174 int is_idr = !!pic_param.pic_fields.bits.idr_pic_flag;
175 int is_ref = !!pic_param.pic_fields.bits.reference_pic_flag;
176
177 bs->startCodePrefix();
178 if (IS_I_SLICE(slice_param.slice_type))
179 {
180 bs->nalHeader(NAL_REF_IDC_HIGH, is_idr ? NAL_IDR : NAL_NON_IDR);
181 }
182 else if (IS_P_SLICE(slice_param.slice_type))
183 {
184 bs->nalHeader(NAL_REF_IDC_MEDIUM, NAL_NON_IDR);
185 }
186 else
187 {
188 assert(IS_B_SLICE(slice_param.slice_type));
189 bs->nalHeader(is_ref ? NAL_REF_IDC_LOW : NAL_REF_IDC_NONE, NAL_NON_IDR);
190 }
191 slice_header(bs);
192 bs->stop();
193 return true;
194 }
195
196 /**
197 *
198 */
render_packedslice()199 bool ADM_vaEncodingContextH264AnnexB::render_packedslice()
200 {
201 VAEncPackedHeaderParameterBuffer packedheader_param_buffer;
202 VABufferID packedslice_para_bufid, packedslice_data_bufid, render_id[2];
203 unsigned int length_in_bits;
204
205 VAStatus va_status;
206 vaBitstream bs;
207 build_packed_slice_buffer(&bs);
208 length_in_bits = bs.lengthInBits();
209
210 packedheader_param_buffer.type = VAEncPackedHeaderSlice;
211 packedheader_param_buffer.bit_length = length_in_bits;
212 packedheader_param_buffer.has_emulation_bytes = 0;
213
214 CHECK_VA_STATUS_BOOL(vaCreateBuffer(admLibVA::getDisplay(),
215 context_id,
216 VAEncPackedHeaderParameterBufferType,
217 sizeof (packedheader_param_buffer), 1, &packedheader_param_buffer,
218 &packedslice_para_bufid));
219
220
221 CHECK_VA_STATUS_BOOL(vaCreateBuffer(admLibVA::getDisplay(),
222 context_id,
223 VAEncPackedHeaderDataBufferType,
224 (length_in_bits + 7) / 8, 1, bs.getPointer(),
225 &packedslice_data_bufid));
226
227
228 render_id[0] = packedslice_para_bufid;
229 render_id[1] = packedslice_data_bufid;
230 CHECK_VA_STATUS_BOOL(vaRenderPicture(admLibVA::getDisplay(), context_id, render_id, 2));
231
232 return true;
233 }
234
235
236 /**
237 *
238 */
render_packedsei(int frameNumber)239 bool ADM_vaEncodingContextH264AnnexB::render_packedsei(int frameNumber)
240 {
241 VAEncPackedHeaderParameterBuffer packed_header_param_buffer;
242 VABufferID packed_sei_header_param_buf_id, packed_sei_buf_id, render_id[2];
243 unsigned int length_in_bits /*offset_in_bytes*/;
244
245 VAStatus va_status;
246 vaBitstream bs;
247 int init_cpb_size, target_bit_rate, i_initial_cpb_removal_delay_length, i_initial_cpb_removal_delay;
248 int i_cpb_removal_delay, i_dpb_output_delay_length, i_cpb_removal_delay_length;
249
250 /* it comes for the bps defined in SPS */
251 target_bit_rate = VA_BITRATE;
252 init_cpb_size = (target_bit_rate * 8) >> 10;
253 i_initial_cpb_removal_delay = init_cpb_size * 0.5 * 1024 / target_bit_rate * 90000;
254
255 i_cpb_removal_delay = 2;
256 i_initial_cpb_removal_delay_length = 24;
257 i_cpb_removal_delay_length = 24;
258 i_dpb_output_delay_length = 24;
259
260
261 build_packed_sei_buffer_timing(&bs,
262 i_initial_cpb_removal_delay_length,
263 i_initial_cpb_removal_delay,
264 0,
265 i_cpb_removal_delay_length,
266 i_cpb_removal_delay * frameNumber,
267 i_dpb_output_delay_length,
268 0);
269 length_in_bits = bs.lengthInBits();
270 //offset_in_bytes = 0;
271 packed_header_param_buffer.type = VAEncPackedHeaderH264_SEI;
272 packed_header_param_buffer.bit_length = length_in_bits;
273 packed_header_param_buffer.has_emulation_bytes = 0;
274
275 CHECK_VA_STATUS_BOOL(vaCreateBuffer(admLibVA::getDisplay(),
276 context_id,
277 VAEncPackedHeaderParameterBufferType,
278 sizeof (packed_header_param_buffer), 1, &packed_header_param_buffer,
279 &packed_sei_header_param_buf_id));
280
281
282 CHECK_VA_STATUS_BOOL(vaCreateBuffer(admLibVA::getDisplay(),
283 context_id,
284 VAEncPackedHeaderDataBufferType,
285 (length_in_bits + 7) / 8, 1, bs.getPointer(),
286 &packed_sei_buf_id));
287
288
289
290 render_id[0] = packed_sei_header_param_buf_id;
291 render_id[1] = packed_sei_buf_id;
292 CHECK_VA_STATUS_BOOL(vaRenderPicture(admLibVA::getDisplay(), context_id, render_id, 2));
293
294 return true;
295 }
296
297 /**
298 *
299 * @return
300 */
render_packedpicture(void)301 bool ADM_vaEncodingContextH264AnnexB::render_packedpicture(void)
302 {
303 VAEncPackedHeaderParameterBuffer packedheader_param_buffer;
304 VABufferID packedpic_para_bufid, packedpic_data_bufid, render_id[2];
305 unsigned int length_in_bits;
306
307 VAStatus va_status;
308 vaBitstream bs;
309
310
311 build_packed_pic_buffer(&bs);
312 length_in_bits = bs.lengthInBits();
313 packedheader_param_buffer.type = VAEncPackedHeaderPicture;
314 packedheader_param_buffer.bit_length = length_in_bits;
315 packedheader_param_buffer.has_emulation_bytes = 0;
316
317 CHECK_VA_STATUS_BOOL(vaCreateBuffer(admLibVA::getDisplay(),
318 context_id,
319 VAEncPackedHeaderParameterBufferType,
320 sizeof (packedheader_param_buffer), 1, &packedheader_param_buffer,
321 &packedpic_para_bufid));
322
323
324 CHECK_VA_STATUS_BOOL(vaCreateBuffer(admLibVA::getDisplay(),
325 context_id,
326 VAEncPackedHeaderDataBufferType,
327 (length_in_bits + 7) / 8, 1, bs.getPointer(),
328 &packedpic_data_bufid));
329
330
331 render_id[0] = packedpic_para_bufid;
332 render_id[1] = packedpic_data_bufid;
333 CHECK_VA_STATUS_BOOL(vaRenderPicture(admLibVA::getDisplay(), context_id, render_id, 2));
334
335
336 return true;
337 }
338
339 /**
340 *
341 * @return
342 */
render_packedsequence(void)343 bool ADM_vaEncodingContextH264AnnexB::render_packedsequence(void)
344 {
345 VAEncPackedHeaderParameterBuffer packedheader_param_buffer;
346 VABufferID packedseq_para_bufid, packedseq_data_bufid, render_id[2];
347 unsigned int length_in_bits;
348
349 VAStatus va_status;
350 vaBitstream bs;
351
352 build_packed_seq_buffer(&bs);
353 length_in_bits = bs.lengthInBits();
354
355 packedheader_param_buffer.type = VAEncPackedHeaderSequence;
356
357 packedheader_param_buffer.bit_length = length_in_bits; /*length_in_bits*/
358 packedheader_param_buffer.has_emulation_bytes = 0;
359 CHECK_VA_STATUS_BOOL(vaCreateBuffer(admLibVA::getDisplay(),
360 context_id,
361 VAEncPackedHeaderParameterBufferType,
362 sizeof (packedheader_param_buffer), 1, &packedheader_param_buffer,
363 &packedseq_para_bufid));
364
365
366 CHECK_VA_STATUS_BOOL(vaCreateBuffer(admLibVA::getDisplay(),
367 context_id,
368 VAEncPackedHeaderDataBufferType,
369 (length_in_bits + 7) / 8, 1, bs.getPointer(),
370 &packedseq_data_bufid));
371
372
373 render_id[0] = packedseq_para_bufid;
374 render_id[1] = packedseq_data_bufid;
375 CHECK_VA_STATUS_BOOL(vaRenderPicture(admLibVA::getDisplay(), context_id, render_id, 2));
376
377 return true;
378 }
379
380
381 /**
382 *
383 * @return
384 */
render_hrd(void)385 bool ADM_vaEncodingContextH264AnnexB::render_hrd(void)
386 {
387 VABufferID misc_parameter_hrd_buf_id;
388 VAStatus va_status;
389 VAEncMiscParameterBuffer *misc_param;
390 VAEncMiscParameterHRD *misc_hrd_param;
391
392 CHECK_VA_STATUS_BOOL(vaCreateBuffer(admLibVA::getDisplay(), context_id,
393 VAEncMiscParameterBufferType,
394 sizeof (VAEncMiscParameterBuffer) + sizeof (VAEncMiscParameterHRD),
395 1,
396 NULL,
397 &misc_parameter_hrd_buf_id));
398
399
400 vaMapBuffer(admLibVA::getDisplay(),
401 misc_parameter_hrd_buf_id,
402 (void **) &misc_param);
403 misc_param->type = VAEncMiscParameterTypeHRD;
404 misc_hrd_param = (VAEncMiscParameterHRD *) misc_param->data;
405
406 if (VA_BITRATE > 0)
407 {
408 misc_hrd_param->initial_buffer_fullness = VA_BITRATE* 1024 * 4;
409 misc_hrd_param->buffer_size = VA_BITRATE * 1024 * 8;
410 }
411 else
412 {
413 misc_hrd_param->initial_buffer_fullness = 0;
414 misc_hrd_param->buffer_size = 0;
415 }
416 vaUnmapBuffer(admLibVA::getDisplay(), misc_parameter_hrd_buf_id);
417
418 CHECK_VA_STATUS_BOOL(vaRenderPicture(admLibVA::getDisplay(), context_id, &misc_parameter_hrd_buf_id, 1));
419
420
421 return true;
422 }
423 //--
424
425
426 /**
427 *
428 * @return
429 */
render_slice(int frameNumber,vaFrameType frameType)430 bool ADM_vaEncodingContextH264AnnexB::render_slice(int frameNumber,vaFrameType frameType)
431 {
432 VABufferID slice_param_buf;
433 VAStatus va_status;
434 int i;
435
436 update_RefPicList(frameType);
437
438 /* one frame, one slice */
439 slice_param.macroblock_address = 0;
440 slice_param.num_macroblocks = frame_width_mbaligned * frame_height_mbaligned / (16 * 16); /* Measured by MB */
441 switch(frameType)
442 {
443 case FRAME_IDR:
444 slice_param.slice_type =SLICE_TYPE_I;
445 if (frameNumber)
446 slice_param.idr_pic_id++;
447 for (i = 0; i < 32; i++)
448 {
449 slice_param.RefPicList0[i].picture_id = VA_INVALID_SURFACE;
450 slice_param.RefPicList0[i].flags = VA_PICTURE_H264_INVALID;
451 slice_param.RefPicList1[i].picture_id = VA_INVALID_SURFACE;
452 slice_param.RefPicList1[i].flags = VA_PICTURE_H264_INVALID;
453
454 }
455 break;
456 case FRAME_P:
457 {
458 slice_param.slice_type=SLICE_TYPE_P;
459 int refpiclist0_max = h264->h264_maxref_p0;
460 memcpy(slice_param.RefPicList0, RefPicList0_P, refpiclist0_max * sizeof (VAPictureH264));
461 for (i = refpiclist0_max; i < 32; i++)
462 {
463 slice_param.RefPicList0[i].picture_id = VA_INVALID_SURFACE;
464 slice_param.RefPicList0[i].flags = VA_PICTURE_H264_INVALID;
465 }
466 }
467 break;
468 case FRAME_B:
469 {
470 slice_param.slice_type=SLICE_TYPE_B;
471 int refpiclist0_max = h264->h264_maxref_p0;
472 int refpiclist1_max = h264->h264_maxref_p1;
473
474 memcpy(slice_param.RefPicList0, RefPicList0_B, refpiclist0_max * sizeof (VAPictureH264));
475 for (i = refpiclist0_max; i < 32; i++)
476 {
477 slice_param.RefPicList0[i].picture_id = VA_INVALID_SURFACE;
478 slice_param.RefPicList0[i].flags = VA_PICTURE_H264_INVALID;
479 }
480
481 memcpy(slice_param.RefPicList1, RefPicList1_B, refpiclist1_max * sizeof (VAPictureH264));
482 for (i = refpiclist1_max; i < 32; i++)
483 {
484 slice_param.RefPicList1[i].picture_id = VA_INVALID_SURFACE;
485 slice_param.RefPicList1[i].flags = VA_PICTURE_H264_INVALID;
486 }
487 }
488 break;
489 default:
490 ADM_assert(0);
491 break;
492 }
493
494 slice_param.slice_alpha_c0_offset_div2 = 0;
495 slice_param.slice_beta_offset_div2 = 0;
496 slice_param.direct_spatial_mv_pred_flag = 1;
497 slice_param.pic_order_cnt_lsb = (frameNumber - gop_start) % MaxPicOrderCntLsb;
498
499
500 render_packedslice();
501
502 CHECK_VA_STATUS_BOOL(vaCreateBuffer(admLibVA::getDisplay(), context_id, VAEncSliceParameterBufferType,
503 sizeof (slice_param), 1, &slice_param, &slice_param_buf));
504 CHECK_VA_STATUS_BOOL(vaRenderPicture(admLibVA::getDisplay(), context_id, &slice_param_buf, 1));
505 return true;
506 }
507
508
509
510 /**
511 *
512 * @param in
513 * @param out
514 * @return
515 */
516
517
generateExtraData(int * size,uint8_t ** data)518 bool ADM_vaEncodingContextH264AnnexB::generateExtraData(int *size, uint8_t **data)
519 {
520 ADM_info("vaH264 extraData\n");
521
522 *size=0;
523 *data=NULL;
524 ADM_info("/vaH264 extraData\n");
525 return true;
526 }
encode(ADMImage * in,ADMBitstream * out)527 bool ADM_vaEncodingContextH264AnnexB::encode(ADMImage *in, ADMBitstream *out)
528 {
529 vaFrameType current_frame_type;
530 aprintf("Encoding frame %d, H264 AnnexB\n",current_frame_encoding);
531 if(!vaSurface[current_frame_encoding%SURFACE_NUM]->fromAdmImage(in))
532 {
533 ADM_warning("Failed to upload image to vaSurface\n");
534 return false;
535 }
536
537 encoding2display_order(current_frame_encoding, vaH264Settings.IntraPeriod, ¤t_frame_type);
538 aprintf("Encoding order = %d, frame type=%d\n",(int)current_frame_encoding,current_frame_type);
539 if (current_frame_type == FRAME_IDR)
540 {
541 numShortTerm = 0;
542 }
543 int current_slot= (current_frame_encoding % SURFACE_NUM);
544
545 CHECK_VA_STATUS_BOOL(vaBeginPicture(admLibVA::getDisplay(), context_id, vaSurface[current_slot]->surface));
546
547
548 if (current_frame_type == FRAME_IDR)
549 {
550 render_sequence();
551 render_picture(current_frame_encoding,current_frame_type);
552 render_packedsequence();
553 render_packedpicture();
554 out->flags = AVI_KEY_FRAME;
555 }
556 else
557 {
558 out->flags = AVI_P_FRAME;
559 render_picture(current_frame_encoding,current_frame_type);
560 }
561 render_slice(current_frame_encoding,current_frame_type);
562 CHECK_VA_STATUS_BOOL( vaEndPicture(admLibVA::getDisplay(),context_id));
563 //--
564
565 CHECK_VA_STATUS_BOOL( vaSyncSurface(admLibVA::getDisplay(), vaSurface[current_frame_encoding % SURFACE_NUM]->surface));
566
567 out->len=vaEncodingBuffers[current_frame_encoding % SURFACE_NUM]->read(out->data, out->bufferSize);
568 ADM_assert(out->len>=0);
569
570 /* reload a new frame data */
571
572 update_ReferenceFrames(current_frame_type);
573 current_frame_encoding++;
574 out->pts=in->Pts;
575 out->dts=out->pts;
576 return true;
577 }
578
ADM_vaEncodingContextH264AnnexB()579 ADM_vaEncodingContextH264AnnexB::ADM_vaEncodingContextH264AnnexB()
580 {
581
582 }
~ADM_vaEncodingContextH264AnnexB()583 ADM_vaEncodingContextH264AnnexB::~ADM_vaEncodingContextH264AnnexB()
584 {
585
586 }
587
588 /**
589 *
590 * @param width
591 * @param height
592 * @param knownSurfaces
593 * @return
594 */
setup(int width,int height,int frameInc,std::vector<ADM_vaSurface * > knownSurfaces)595 bool ADM_vaEncodingContextH264AnnexB::setup( int width, int height, int frameInc,std::vector<ADM_vaSurface *>knownSurfaces)
596 {
597 ADM_info("vaH264 setup\n");
598
599 h264=vaGetH264EncoderProfile();
600 if(h264->profile==VAProfileNone)
601 {
602 ADM_error("No H264 encoding support\n");
603 return false;
604 }
605
606
607 VAStatus va_status;
608 frame_width=width;
609 frame_height=height;
610 frame_width_mbaligned=(width+15)&~15;
611 frame_height_mbaligned=(height+15)&~15;
612 int i;
613 usSecondsToFrac(frameInc,&frameNum,&frameDen);
614 ADM_info("xFps : %d : %d\n",frameNum,frameDen);
615 // marshall new config...
616
617 // copy common part
618 int nAttrib=h264->newAttributes.count();
619 VAConfigAttrib *ttrib=new VAConfigAttrib[nAttrib+1];
620 const VAConfigAttrib *old=h264->newAttributes.getPointer();
621 memcpy(ttrib,old,nAttrib*sizeof(VAConfigAttrib));
622
623 // add rate control, it is per instance
624 ttrib[nAttrib].type=VAConfigAttribRateControl;
625 ttrib[nAttrib].value=VA_RC_CBR;
626
627
628 CHECK_VA_STATUS_BOOL( vaCreateConfig(admLibVA::getDisplay(), h264->profile, VAEntrypointEncSlice, ttrib, nAttrib+1, &config_id));
629
630
631 int n=knownSurfaces.size();
632 VASurfaceID *tmp_surfaceId = new VASurfaceID[n];
633 for(int i=0;i<n;i++)
634 {
635 tmp_surfaceId[i]=knownSurfaces[i]->surface;
636 }
637
638 /* Create a context for this encode pipe */
639 CHECK_VA_STATUS_BOOL( vaCreateContext(admLibVA::getDisplay(), config_id,
640 frame_width_mbaligned, frame_height_mbaligned,
641 VA_PROGRESSIVE,
642 tmp_surfaceId, n,
643 &context_id));
644
645 delete [] ttrib;
646 delete [] tmp_surfaceId;
647 tmp_surfaceId=NULL;
648
649 int codedbuf_size = (frame_width_mbaligned * frame_height_mbaligned * 400) / (16*16);
650
651 for (i = 0; i < SURFACE_NUM; i++)
652 {
653 vaEncodingBuffers[i]= ADM_vaEncodingBuffers::allocate(context_id,codedbuf_size);
654 if(!vaEncodingBuffers[i])
655 {
656 ADM_warning("Cannot create encoding buffer %d\n",i);
657 return false;;
658 }
659 }
660
661 // Allocate VAImage
662
663 for(int i=0;i<VA_ENC_NB_SURFACE;i++)
664 {
665 vaSurface[i]=ADM_vaSurface::allocateWithSurface(width,height);
666 if(!vaSurface[i])
667 {
668 ADM_warning("Cannot allocate surface\n");
669 return false;
670 }
671
672 vaRefSurface[i]=ADM_vaSurface::allocateWithSurface(width,height);
673 if(!vaRefSurface[i])
674 {
675 ADM_warning("Cannot allocate ref surface\n");
676 return false;
677 }
678 }
679 tmpBuffer=new uint8_t[codedbuf_size];
680 render_sequence();
681 ADM_info("/vaH264 setup\n");
682 return true;
683 }
684
685 // EOF