1 /*
2 * gstvaapiencoder_objects.c - VA encoder objects abstraction
3 *
4 * Copyright (C) 2013-2014 Intel Corporation
5 * Author: Wind Yuan <feng.yuan@intel.com>
6 *
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public License
9 * as published by the Free Software Foundation; either version 2.1
10 * of the License, or (at your option) any later version.
11 *
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free
19 * Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
20 * Boston, MA 02110-1301 USA
21 */
22
23 #include "sysdeps.h"
24 #include "gstvaapiencoder_objects.h"
25 #include "gstvaapiencoder_priv.h"
26 #include "gstvaapisurfaceproxy_priv.h"
27 #include "gstvaapicompat.h"
28 #include "gstvaapiutils.h"
29
30 #define DEBUG 1
31 #include "gstvaapidebug.h"
32
33 #define GET_ENCODER(obj) GST_VAAPI_ENCODER_CAST((obj)->parent_instance.codec)
34 #define GET_VA_DISPLAY(obj) GET_ENCODER(obj)->va_display
35 #define GET_VA_CONTEXT(obj) GET_ENCODER(obj)->va_context
36
37 /* ------------------------------------------------------------------------- */
38 /* --- Encoder Packed Header --- */
39 /* ------------------------------------------------------------------------- */
40
41 GST_VAAPI_CODEC_DEFINE_TYPE (GstVaapiEncPackedHeader,
42 gst_vaapi_enc_packed_header);
43
44 void
gst_vaapi_enc_packed_header_destroy(GstVaapiEncPackedHeader * header)45 gst_vaapi_enc_packed_header_destroy (GstVaapiEncPackedHeader * header)
46 {
47 vaapi_destroy_buffer (GET_VA_DISPLAY (header), &header->param_id);
48 vaapi_destroy_buffer (GET_VA_DISPLAY (header), &header->data_id);
49 header->param = NULL;
50 header->data = NULL;
51 }
52
53 gboolean
gst_vaapi_enc_packed_header_create(GstVaapiEncPackedHeader * header,const GstVaapiCodecObjectConstructorArgs * args)54 gst_vaapi_enc_packed_header_create (GstVaapiEncPackedHeader * header,
55 const GstVaapiCodecObjectConstructorArgs * args)
56 {
57 gboolean success;
58
59 header->param_id = VA_INVALID_ID;
60 header->data_id = VA_INVALID_ID;
61
62 success = vaapi_create_buffer (GET_VA_DISPLAY (header),
63 GET_VA_CONTEXT (header),
64 VAEncPackedHeaderParameterBufferType,
65 args->param_size, args->param, &header->param_id, &header->param);
66 if (!success)
67 return FALSE;
68
69 if (!args->data_size)
70 return TRUE;
71
72 success = vaapi_create_buffer (GET_VA_DISPLAY (header),
73 GET_VA_CONTEXT (header),
74 VAEncPackedHeaderDataBufferType,
75 args->data_size, args->data, &header->data_id, &header->data);
76 if (!success)
77 return FALSE;
78 return TRUE;
79 }
80
81 GstVaapiEncPackedHeader *
gst_vaapi_enc_packed_header_new(GstVaapiEncoder * encoder,gconstpointer param,guint param_size,gconstpointer data,guint data_size)82 gst_vaapi_enc_packed_header_new (GstVaapiEncoder * encoder,
83 gconstpointer param, guint param_size, gconstpointer data, guint data_size)
84 {
85 GstVaapiCodecObject *object;
86
87 object = gst_vaapi_codec_object_new (&GstVaapiEncPackedHeaderClass,
88 GST_VAAPI_CODEC_BASE (encoder), param, param_size, data, data_size, 0);
89 return GST_VAAPI_ENC_PACKED_HEADER (object);
90 }
91
92 gboolean
gst_vaapi_enc_packed_header_set_data(GstVaapiEncPackedHeader * header,gconstpointer data,guint data_size)93 gst_vaapi_enc_packed_header_set_data (GstVaapiEncPackedHeader * header,
94 gconstpointer data, guint data_size)
95 {
96 gboolean success;
97
98 vaapi_destroy_buffer (GET_VA_DISPLAY (header), &header->data_id);
99 header->data = NULL;
100
101 success = vaapi_create_buffer (GET_VA_DISPLAY (header),
102 GET_VA_CONTEXT (header),
103 VAEncPackedHeaderDataBufferType,
104 data_size, data, &header->data_id, &header->data);
105 if (!success)
106 return FALSE;
107 return TRUE;
108 }
109
110 /* ------------------------------------------------------------------------- */
111 /* --- Encoder Sequence --- */
112 /* ------------------------------------------------------------------------- */
113
114 GST_VAAPI_CODEC_DEFINE_TYPE (GstVaapiEncSequence, gst_vaapi_enc_sequence);
115
116 void
gst_vaapi_enc_sequence_destroy(GstVaapiEncSequence * sequence)117 gst_vaapi_enc_sequence_destroy (GstVaapiEncSequence * sequence)
118 {
119 vaapi_destroy_buffer (GET_VA_DISPLAY (sequence), &sequence->param_id);
120 sequence->param = NULL;
121 }
122
123 gboolean
gst_vaapi_enc_sequence_create(GstVaapiEncSequence * sequence,const GstVaapiCodecObjectConstructorArgs * args)124 gst_vaapi_enc_sequence_create (GstVaapiEncSequence * sequence,
125 const GstVaapiCodecObjectConstructorArgs * args)
126 {
127 gboolean success;
128
129 sequence->param_id = VA_INVALID_ID;
130 success = vaapi_create_buffer (GET_VA_DISPLAY (sequence),
131 GET_VA_CONTEXT (sequence),
132 VAEncSequenceParameterBufferType,
133 args->param_size, args->param, &sequence->param_id, &sequence->param);
134 if (!success)
135 return FALSE;
136 return TRUE;
137 }
138
139 GstVaapiEncSequence *
gst_vaapi_enc_sequence_new(GstVaapiEncoder * encoder,gconstpointer param,guint param_size)140 gst_vaapi_enc_sequence_new (GstVaapiEncoder * encoder,
141 gconstpointer param, guint param_size)
142 {
143 GstVaapiCodecObject *object;
144
145 object = gst_vaapi_codec_object_new (&GstVaapiEncSequenceClass,
146 GST_VAAPI_CODEC_BASE (encoder), param, param_size, NULL, 0, 0);
147 return GST_VAAPI_ENC_SEQUENCE (object);
148 }
149
150 /* ------------------------------------------------------------------------- */
151 /* --- Encoder Slice --- */
152 /* ------------------------------------------------------------------------- */
153
154 GST_VAAPI_CODEC_DEFINE_TYPE (GstVaapiEncSlice, gst_vaapi_enc_slice);
155
156 void
gst_vaapi_enc_slice_destroy(GstVaapiEncSlice * slice)157 gst_vaapi_enc_slice_destroy (GstVaapiEncSlice * slice)
158 {
159 if (slice->packed_headers) {
160 g_ptr_array_unref (slice->packed_headers);
161 slice->packed_headers = NULL;
162 }
163
164 vaapi_destroy_buffer (GET_VA_DISPLAY (slice), &slice->param_id);
165 slice->param = NULL;
166 }
167
168 gboolean
gst_vaapi_enc_slice_create(GstVaapiEncSlice * slice,const GstVaapiCodecObjectConstructorArgs * args)169 gst_vaapi_enc_slice_create (GstVaapiEncSlice * slice,
170 const GstVaapiCodecObjectConstructorArgs * args)
171 {
172 gboolean success;
173
174 slice->param_id = VA_INVALID_ID;
175 success = vaapi_create_buffer (GET_VA_DISPLAY (slice),
176 GET_VA_CONTEXT (slice),
177 VAEncSliceParameterBufferType,
178 args->param_size, args->param, &slice->param_id, &slice->param);
179 if (!success)
180 return FALSE;
181
182 slice->packed_headers = g_ptr_array_new_with_free_func ((GDestroyNotify)
183 gst_vaapi_mini_object_unref);
184 if (!slice->packed_headers)
185 return FALSE;
186
187 return TRUE;
188 }
189
190 GstVaapiEncSlice *
gst_vaapi_enc_slice_new(GstVaapiEncoder * encoder,gconstpointer param,guint param_size)191 gst_vaapi_enc_slice_new (GstVaapiEncoder * encoder,
192 gconstpointer param, guint param_size)
193 {
194 GstVaapiCodecObject *object;
195
196 object = gst_vaapi_codec_object_new (&GstVaapiEncSliceClass,
197 GST_VAAPI_CODEC_BASE (encoder), param, param_size, NULL, 0, 0);
198 return GST_VAAPI_ENC_SLICE (object);
199 }
200
201 /* ------------------------------------------------------------------------- */
202 /* --- Encoder Misc Parameter Buffer --- */
203 /* ------------------------------------------------------------------------- */
204
205 GST_VAAPI_CODEC_DEFINE_TYPE (GstVaapiEncMiscParam, gst_vaapi_enc_misc_param);
206
207 void
gst_vaapi_enc_misc_param_destroy(GstVaapiEncMiscParam * misc)208 gst_vaapi_enc_misc_param_destroy (GstVaapiEncMiscParam * misc)
209 {
210 vaapi_destroy_buffer (GET_VA_DISPLAY (misc), &misc->param_id);
211 misc->param = NULL;
212 misc->data = NULL;
213 }
214
215 gboolean
gst_vaapi_enc_misc_param_create(GstVaapiEncMiscParam * misc,const GstVaapiCodecObjectConstructorArgs * args)216 gst_vaapi_enc_misc_param_create (GstVaapiEncMiscParam * misc,
217 const GstVaapiCodecObjectConstructorArgs * args)
218 {
219 gboolean success;
220
221 misc->param_id = VA_INVALID_ID;
222 success = vaapi_create_buffer (GET_VA_DISPLAY (misc),
223 GET_VA_CONTEXT (misc),
224 VAEncMiscParameterBufferType,
225 args->param_size, args->param, &misc->param_id, &misc->param);
226 if (!success)
227 return FALSE;
228 return TRUE;
229 }
230
231 GstVaapiEncMiscParam *
gst_vaapi_enc_misc_param_new(GstVaapiEncoder * encoder,VAEncMiscParameterType type,guint data_size)232 gst_vaapi_enc_misc_param_new (GstVaapiEncoder * encoder,
233 VAEncMiscParameterType type, guint data_size)
234 {
235 GstVaapiCodecObject *object;
236 GstVaapiEncMiscParam *misc;
237 VAEncMiscParameterBuffer *va_misc;
238
239 object = gst_vaapi_codec_object_new (&GstVaapiEncMiscParamClass,
240 GST_VAAPI_CODEC_BASE (encoder),
241 NULL, sizeof (VAEncMiscParameterBuffer) + data_size, NULL, 0, 0);
242 if (!object)
243 return NULL;
244
245 misc = GST_VAAPI_ENC_MISC_PARAM (object);
246 va_misc = misc->param;
247 va_misc->type = type;
248 misc->data = va_misc->data;
249 return misc;
250 }
251
252 /* ------------------------------------------------------------------------- */
253 /* --- Quantization Matrices --- */
254 /* ------------------------------------------------------------------------- */
255
256 GST_VAAPI_CODEC_DEFINE_TYPE (GstVaapiEncQMatrix, gst_vaapi_enc_q_matrix);
257
258 void
gst_vaapi_enc_q_matrix_destroy(GstVaapiEncQMatrix * q_matrix)259 gst_vaapi_enc_q_matrix_destroy (GstVaapiEncQMatrix * q_matrix)
260 {
261 vaapi_destroy_buffer (GET_VA_DISPLAY (q_matrix), &q_matrix->param_id);
262 q_matrix->param = NULL;
263 }
264
265 gboolean
gst_vaapi_enc_q_matrix_create(GstVaapiEncQMatrix * q_matrix,const GstVaapiCodecObjectConstructorArgs * args)266 gst_vaapi_enc_q_matrix_create (GstVaapiEncQMatrix * q_matrix,
267 const GstVaapiCodecObjectConstructorArgs * args)
268 {
269 q_matrix->param_id = VA_INVALID_ID;
270 return vaapi_create_buffer (GET_VA_DISPLAY (q_matrix),
271 GET_VA_CONTEXT (q_matrix), VAQMatrixBufferType,
272 args->param_size, args->param, &q_matrix->param_id, &q_matrix->param);
273 }
274
275 GstVaapiEncQMatrix *
gst_vaapi_enc_q_matrix_new(GstVaapiEncoder * encoder,gconstpointer param,guint param_size)276 gst_vaapi_enc_q_matrix_new (GstVaapiEncoder * encoder,
277 gconstpointer param, guint param_size)
278 {
279 GstVaapiCodecObject *object;
280
281 object = gst_vaapi_codec_object_new (&GstVaapiEncQMatrixClass,
282 GST_VAAPI_CODEC_BASE (encoder), param, param_size, NULL, 0, 0);
283 if (!object)
284 return NULL;
285 return GST_VAAPI_ENC_Q_MATRIX_CAST (object);
286 }
287
288 /* ------------------------------------------------------------------------- */
289 /* --- JPEG Huffman Tables --- */
290 /* ------------------------------------------------------------------------- */
291
292 GST_VAAPI_CODEC_DEFINE_TYPE (GstVaapiEncHuffmanTable,
293 gst_vaapi_enc_huffman_table);
294
295 void
gst_vaapi_enc_huffman_table_destroy(GstVaapiEncHuffmanTable * huf_table)296 gst_vaapi_enc_huffman_table_destroy (GstVaapiEncHuffmanTable * huf_table)
297 {
298 vaapi_destroy_buffer (GET_VA_DISPLAY (huf_table), &huf_table->param_id);
299 huf_table->param = NULL;
300 }
301
302 gboolean
gst_vaapi_enc_huffman_table_create(GstVaapiEncHuffmanTable * huf_table,const GstVaapiCodecObjectConstructorArgs * args)303 gst_vaapi_enc_huffman_table_create (GstVaapiEncHuffmanTable * huf_table,
304 const GstVaapiCodecObjectConstructorArgs * args)
305 {
306 huf_table->param_id = VA_INVALID_ID;
307 return vaapi_create_buffer (GET_VA_DISPLAY (huf_table),
308 GET_VA_CONTEXT (huf_table), VAHuffmanTableBufferType, args->param_size,
309 args->param, &huf_table->param_id, (void **) &huf_table->param);
310 }
311
312 GstVaapiEncHuffmanTable *
gst_vaapi_enc_huffman_table_new(GstVaapiEncoder * encoder,guint8 * data,guint data_size)313 gst_vaapi_enc_huffman_table_new (GstVaapiEncoder * encoder,
314 guint8 * data, guint data_size)
315 {
316 GstVaapiCodecObject *object;
317
318 object = gst_vaapi_codec_object_new (&GstVaapiEncHuffmanTableClass,
319 GST_VAAPI_CODEC_BASE (encoder), data, data_size, NULL, 0, 0);
320 if (!object)
321 return NULL;
322 return GST_VAAPI_ENC_HUFFMAN_TABLE_CAST (object);
323 }
324
325 /* ------------------------------------------------------------------------- */
326 /* --- Encoder Picture --- */
327 /* ------------------------------------------------------------------------- */
328
329 GST_VAAPI_CODEC_DEFINE_TYPE (GstVaapiEncPicture, gst_vaapi_enc_picture);
330
331 void
gst_vaapi_enc_picture_destroy(GstVaapiEncPicture * picture)332 gst_vaapi_enc_picture_destroy (GstVaapiEncPicture * picture)
333 {
334 if (picture->packed_headers) {
335 g_ptr_array_unref (picture->packed_headers);
336 picture->packed_headers = NULL;
337 }
338 if (picture->misc_params) {
339 g_ptr_array_unref (picture->misc_params);
340 picture->misc_params = NULL;
341 }
342 if (picture->slices) {
343 g_ptr_array_unref (picture->slices);
344 picture->slices = NULL;
345 }
346
347 gst_vaapi_codec_object_replace (&picture->q_matrix, NULL);
348 gst_vaapi_codec_object_replace (&picture->huf_table, NULL);
349
350 gst_vaapi_codec_object_replace (&picture->sequence, NULL);
351
352 #if USE_H264_FEI_ENCODER
353 gst_vaapi_codec_object_replace (&picture->mvpred, NULL);
354 gst_vaapi_codec_object_replace (&picture->mbcntrl, NULL);
355 gst_vaapi_codec_object_replace (&picture->qp, NULL);
356 gst_vaapi_codec_object_replace (&picture->mbcode, NULL);
357 gst_vaapi_codec_object_replace (&picture->mv, NULL);
358 gst_vaapi_codec_object_replace (&picture->dist, NULL);
359 #endif
360
361 gst_vaapi_surface_proxy_replace (&picture->proxy, NULL);
362 picture->surface_id = VA_INVALID_ID;
363 picture->surface = NULL;
364
365 vaapi_destroy_buffer (GET_VA_DISPLAY (picture), &picture->param_id);
366 picture->param = NULL;
367
368 if (picture->frame) {
369 gst_video_codec_frame_unref (picture->frame);
370 picture->frame = NULL;
371 }
372 }
373
374 gboolean
gst_vaapi_enc_picture_create(GstVaapiEncPicture * picture,const GstVaapiCodecObjectConstructorArgs * args)375 gst_vaapi_enc_picture_create (GstVaapiEncPicture * picture,
376 const GstVaapiCodecObjectConstructorArgs * args)
377 {
378 GstVideoCodecFrame *const frame = (GstVideoCodecFrame *) args->data;
379 gboolean success;
380
381 picture->proxy = gst_video_codec_frame_get_user_data (frame);
382 if (!gst_vaapi_surface_proxy_ref (picture->proxy))
383 return FALSE;
384
385 picture->surface = GST_VAAPI_SURFACE_PROXY_SURFACE (picture->proxy);
386 if (!picture->surface)
387 return FALSE;
388
389 picture->surface_id = GST_VAAPI_OBJECT_ID (picture->surface);
390 if (picture->surface_id == VA_INVALID_ID)
391 return FALSE;
392
393 picture->type = GST_VAAPI_PICTURE_TYPE_NONE;
394 picture->pts = GST_CLOCK_TIME_NONE;
395 picture->frame_num = 0;
396 picture->poc = 0;
397
398 picture->param_id = VA_INVALID_ID;
399 picture->param_size = args->param_size;
400 success = vaapi_create_buffer (GET_VA_DISPLAY (picture),
401 GET_VA_CONTEXT (picture),
402 VAEncPictureParameterBufferType,
403 args->param_size, args->param, &picture->param_id, &picture->param);
404 if (!success)
405 return FALSE;
406 picture->param_size = args->param_size;
407
408 picture->packed_headers = g_ptr_array_new_with_free_func ((GDestroyNotify)
409 gst_vaapi_mini_object_unref);
410 if (!picture->packed_headers)
411 return FALSE;
412
413 picture->misc_params = g_ptr_array_new_with_free_func ((GDestroyNotify)
414 gst_vaapi_mini_object_unref);
415 if (!picture->misc_params)
416 return FALSE;
417
418 picture->slices = g_ptr_array_new_with_free_func ((GDestroyNotify)
419 gst_vaapi_mini_object_unref);
420 if (!picture->slices)
421 return FALSE;
422
423 picture->frame = gst_video_codec_frame_ref (frame);
424 return TRUE;
425 }
426
427 GstVaapiEncPicture *
gst_vaapi_enc_picture_new(GstVaapiEncoder * encoder,gconstpointer param,guint param_size,GstVideoCodecFrame * frame)428 gst_vaapi_enc_picture_new (GstVaapiEncoder * encoder,
429 gconstpointer param, guint param_size, GstVideoCodecFrame * frame)
430 {
431 GstVaapiCodecObject *object;
432
433 g_return_val_if_fail (frame != NULL, NULL);
434
435 object = gst_vaapi_codec_object_new (&GstVaapiEncPictureClass,
436 GST_VAAPI_CODEC_BASE (encoder), param, param_size, frame, 0, 0);
437 return GST_VAAPI_ENC_PICTURE (object);
438 }
439
440 void
gst_vaapi_enc_picture_set_sequence(GstVaapiEncPicture * picture,GstVaapiEncSequence * sequence)441 gst_vaapi_enc_picture_set_sequence (GstVaapiEncPicture * picture,
442 GstVaapiEncSequence * sequence)
443 {
444 g_return_if_fail (picture != NULL);
445 g_return_if_fail (sequence != NULL);
446
447 gst_vaapi_codec_object_replace (&picture->sequence, sequence);
448 }
449
450 void
gst_vaapi_enc_picture_add_packed_header(GstVaapiEncPicture * picture,GstVaapiEncPackedHeader * header)451 gst_vaapi_enc_picture_add_packed_header (GstVaapiEncPicture * picture,
452 GstVaapiEncPackedHeader * header)
453 {
454 g_return_if_fail (picture != NULL);
455 g_return_if_fail (header != NULL);
456
457 g_ptr_array_add (picture->packed_headers,
458 gst_vaapi_codec_object_ref (header));
459 }
460
461 void
gst_vaapi_enc_picture_add_misc_param(GstVaapiEncPicture * picture,GstVaapiEncMiscParam * misc)462 gst_vaapi_enc_picture_add_misc_param (GstVaapiEncPicture * picture,
463 GstVaapiEncMiscParam * misc)
464 {
465 g_return_if_fail (picture != NULL);
466 g_return_if_fail (misc != NULL);
467
468 g_ptr_array_add (picture->misc_params, gst_vaapi_codec_object_ref (misc));
469 }
470
471 void
gst_vaapi_enc_picture_add_slice(GstVaapiEncPicture * picture,GstVaapiEncSlice * slice)472 gst_vaapi_enc_picture_add_slice (GstVaapiEncPicture * picture,
473 GstVaapiEncSlice * slice)
474 {
475 g_return_if_fail (picture != NULL);
476 g_return_if_fail (slice != NULL);
477
478 g_ptr_array_add (picture->slices, gst_vaapi_codec_object_ref (slice));
479 }
480
481 void
gst_vaapi_enc_slice_add_packed_header(GstVaapiEncSlice * slice,GstVaapiEncPackedHeader * header)482 gst_vaapi_enc_slice_add_packed_header (GstVaapiEncSlice * slice,
483 GstVaapiEncPackedHeader * header)
484 {
485 g_return_if_fail (slice != NULL);
486 g_return_if_fail (header != NULL);
487
488 g_ptr_array_add (slice->packed_headers, gst_vaapi_codec_object_ref (header));
489 }
490
491 static gboolean
do_encode(VADisplay dpy,VAContextID ctx,VABufferID * buf_id,void ** buf_ptr)492 do_encode (VADisplay dpy, VAContextID ctx, VABufferID * buf_id, void **buf_ptr)
493 {
494 VAStatus status;
495
496 vaapi_unmap_buffer (dpy, *buf_id, buf_ptr);
497
498 status = vaRenderPicture (dpy, ctx, buf_id, 1);
499 if (!vaapi_check_status (status, "vaRenderPicture()"))
500 return FALSE;
501
502 /* XXX: vaRenderPicture() is meant to destroy the VA buffer implicitly */
503 vaapi_destroy_buffer (dpy, buf_id);
504 return TRUE;
505 }
506
507 gboolean
gst_vaapi_enc_picture_encode(GstVaapiEncPicture * picture)508 gst_vaapi_enc_picture_encode (GstVaapiEncPicture * picture)
509 {
510 GstVaapiEncSequence *sequence;
511 GstVaapiEncQMatrix *q_matrix;
512 GstVaapiEncHuffmanTable *huf_table;
513 VADisplay va_display;
514 VAContextID va_context;
515 VAStatus status;
516 guint i;
517
518 g_return_val_if_fail (picture != NULL, FALSE);
519 g_return_val_if_fail (picture->surface_id != VA_INVALID_SURFACE, FALSE);
520
521 va_display = GET_VA_DISPLAY (picture);
522 va_context = GET_VA_CONTEXT (picture);
523
524 GST_DEBUG ("encode picture 0x%08x", picture->surface_id);
525
526 status = vaBeginPicture (va_display, va_context, picture->surface_id);
527 if (!vaapi_check_status (status, "vaBeginPicture()"))
528 return FALSE;
529
530 /* Submit Sequence parameter */
531 sequence = picture->sequence;
532 if (sequence && !do_encode (va_display, va_context,
533 &sequence->param_id, &sequence->param))
534 return FALSE;
535
536 /* Submit Quantization matrix */
537 q_matrix = picture->q_matrix;
538 if (q_matrix && !do_encode (va_display, va_context,
539 &q_matrix->param_id, &q_matrix->param))
540 return FALSE;
541
542 /* Submit huffman table */
543 huf_table = picture->huf_table;
544 if (huf_table && !do_encode (va_display, va_context,
545 &huf_table->param_id, (void **) &huf_table->param))
546 return FALSE;
547
548 /* Submit Packed Headers */
549 for (i = 0; i < picture->packed_headers->len; i++) {
550 GstVaapiEncPackedHeader *const header =
551 g_ptr_array_index (picture->packed_headers, i);
552 if (!do_encode (va_display, va_context,
553 &header->param_id, &header->param) ||
554 !do_encode (va_display, va_context, &header->data_id, &header->data))
555 return FALSE;
556 }
557
558 /* Submit Picture parameter */
559 if (!do_encode (va_display, va_context, &picture->param_id, &picture->param))
560 return FALSE;
561
562 /* Submit Misc Params */
563 for (i = 0; i < picture->misc_params->len; i++) {
564 GstVaapiEncMiscParam *const misc =
565 g_ptr_array_index (picture->misc_params, i);
566 if (!do_encode (va_display, va_context, &misc->param_id, &misc->param))
567 return FALSE;
568 }
569
570 /* Submit Slice parameters */
571 for (i = 0; i < picture->slices->len; i++) {
572 GstVaapiEncSlice *const slice = g_ptr_array_index (picture->slices, i);
573 guint j;
574
575 /* Submit packed_slice_header and packed_raw_data */
576 for (j = 0; j < slice->packed_headers->len; j++) {
577 GstVaapiEncPackedHeader *const header =
578 g_ptr_array_index (slice->packed_headers, j);
579 if (!do_encode (va_display, va_context,
580 &header->param_id, &header->param) ||
581 !do_encode (va_display, va_context, &header->data_id, &header->data))
582 return FALSE;
583 }
584 if (!do_encode (va_display, va_context, &slice->param_id, &slice->param))
585 return FALSE;
586 }
587
588 status = vaEndPicture (va_display, va_context);
589 if (!vaapi_check_status (status, "vaEndPicture()"))
590 return FALSE;
591 return TRUE;
592 }
593