1 /*
2  *  gstvaapiencoder_mpeg2.c - MPEG-2 encoder
3  *
4  *  Copyright (C) 2012-2014 Intel Corporation
5  *    Author: Guangxin Xu <guangxin.xu@intel.com>
6  *    Author: Gwenole Beauchesne <gwenole.beauchesne@intel.com>
7  *
8  *  This library is free software; you can redistribute it and/or
9  *  modify it under the terms of the GNU Lesser General Public License
10  *  as published by the Free Software Foundation; either version 2.1
11  *  of the License, or (at your option) any later version.
12  *
13  *  This library is distributed in the hope that it will be useful,
14  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
15  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16  *  Lesser General Public License for more details.
17  *
18  *  You should have received a copy of the GNU Lesser General Public
19  *  License along with this library; if not, write to the Free
20  *  Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
21  *  Boston, MA 02110-1301 USA
22  */
23 
24 #include <math.h>
25 #include "sysdeps.h"
26 #include <gst/base/gstbitwriter.h>
27 #include "gstvaapicompat.h"
28 #include "gstvaapiencoder_mpeg2.h"
29 #include "gstvaapiencoder_mpeg2_priv.h"
30 #include "gstvaapiutils_mpeg2_priv.h"
31 #include "gstvaapicodedbufferproxy_priv.h"
32 #include "gstvaapicontext.h"
33 #include "gstvaapisurface.h"
34 #include "gstvaapidisplay_priv.h"
35 
36 #define DEBUG 1
37 #include "gstvaapidebug.h"
38 
39 /* Define default rate control mode ("constant-qp") */
40 #define DEFAULT_RATECONTROL GST_VAAPI_RATECONTROL_CQP
41 
42 /* Supported set of VA rate controls, within this implementation */
43 #define SUPPORTED_RATECONTROLS                  \
44   (GST_VAAPI_RATECONTROL_MASK (CQP)  |          \
45    GST_VAAPI_RATECONTROL_MASK (CBR))
46 
47 /* Supported set of tuning options, within this implementation */
48 #define SUPPORTED_TUNE_OPTIONS \
49   (GST_VAAPI_ENCODER_TUNE_MASK (NONE))
50 
51 /* Supported set of VA packed headers, within this implementation */
52 #define SUPPORTED_PACKED_HEADERS                \
53   (VA_ENC_PACKED_HEADER_SEQUENCE |              \
54    VA_ENC_PACKED_HEADER_PICTURE)
55 
56 static gboolean
57 gst_bit_writer_write_sps (GstBitWriter * bitwriter,
58     const VAEncSequenceParameterBufferMPEG2 * seq_param);
59 
60 static gboolean
61 gst_bit_writer_write_pps (GstBitWriter * bitwriter,
62     const VAEncPictureParameterBufferMPEG2 * pic_param);
63 
64 static void clear_references (GstVaapiEncoderMpeg2 * encoder);
65 
66 static void push_reference (GstVaapiEncoderMpeg2 * encoder,
67     GstVaapiSurfaceProxy * ref);
68 
69 /* Derives the profile supported by the underlying hardware */
70 static gboolean
ensure_hw_profile(GstVaapiEncoderMpeg2 * encoder)71 ensure_hw_profile (GstVaapiEncoderMpeg2 * encoder)
72 {
73   GstVaapiDisplay *const display = GST_VAAPI_ENCODER_DISPLAY (encoder);
74   GstVaapiEntrypoint entrypoint = GST_VAAPI_ENTRYPOINT_SLICE_ENCODE;
75   GstVaapiProfile profile, profiles[2];
76   guint i, num_profiles = 0;
77 
78   profiles[num_profiles++] = encoder->profile;
79   switch (encoder->profile) {
80     case GST_VAAPI_PROFILE_MPEG2_SIMPLE:
81       profiles[num_profiles++] = GST_VAAPI_PROFILE_MPEG2_MAIN;
82       break;
83     default:
84       break;
85   }
86 
87   profile = GST_VAAPI_PROFILE_UNKNOWN;
88   for (i = 0; i < num_profiles; i++) {
89     if (gst_vaapi_display_has_encoder (display, profiles[i], entrypoint)) {
90       profile = profiles[i];
91       break;
92     }
93   }
94   if (profile == GST_VAAPI_PROFILE_UNKNOWN)
95     goto error_unsupported_profile;
96 
97   GST_VAAPI_ENCODER_CAST (encoder)->profile = profile;
98   return TRUE;
99 
100   /* ERRORS */
101 error_unsupported_profile:
102   {
103     GST_ERROR ("unsupported HW profile %s",
104         gst_vaapi_profile_get_name (encoder->profile));
105     return FALSE;
106   }
107 }
108 
109 /* Derives the minimum profile from the active coding tools */
110 static gboolean
ensure_profile(GstVaapiEncoderMpeg2 * encoder)111 ensure_profile (GstVaapiEncoderMpeg2 * encoder)
112 {
113   GstVaapiProfile profile;
114 
115   /* Always start from "simple" profile for maximum compatibility */
116   profile = GST_VAAPI_PROFILE_MPEG2_SIMPLE;
117 
118   /* Main profile coding tools */
119   if (encoder->ip_period > 0)
120     profile = GST_VAAPI_PROFILE_MPEG2_MAIN;
121 
122   encoder->profile = profile;
123   encoder->profile_idc = gst_vaapi_utils_mpeg2_get_profile_idc (profile);
124   return TRUE;
125 }
126 
127 /* Derives the minimum level from the current configuration */
128 static gboolean
ensure_level(GstVaapiEncoderMpeg2 * encoder)129 ensure_level (GstVaapiEncoderMpeg2 * encoder)
130 {
131   const GstVideoInfo *const vip = GST_VAAPI_ENCODER_VIDEO_INFO (encoder);
132   const guint fps = (vip->fps_n + vip->fps_d - 1) / vip->fps_d;
133   const guint bitrate = GST_VAAPI_ENCODER_CAST (encoder)->bitrate;
134   const GstVaapiMPEG2LevelLimits *limits_table;
135   guint i, num_limits, num_samples;
136 
137   num_samples = gst_util_uint64_scale_int_ceil (vip->width * vip->height,
138       vip->fps_n, vip->fps_d);
139 
140   limits_table = gst_vaapi_utils_mpeg2_get_level_limits_table (&num_limits);
141   for (i = 0; i < num_limits; i++) {
142     const GstVaapiMPEG2LevelLimits *const limits = &limits_table[i];
143     if (vip->width <= limits->horizontal_size_value &&
144         vip->height <= limits->vertical_size_value &&
145         fps <= limits->frame_rate_value &&
146         num_samples <= limits->sample_rate &&
147         (!bitrate || bitrate <= limits->bit_rate))
148       break;
149   }
150   if (i == num_limits)
151     goto error_unsupported_level;
152 
153   encoder->level = limits_table[i].level;
154   encoder->level_idc = limits_table[i].level_idc;
155   return TRUE;
156 
157   /* ERRORS */
158 error_unsupported_level:
159   {
160     GST_ERROR ("failed to find a suitable level matching codec config");
161     return FALSE;
162   }
163 }
164 
165 /* Derives the profile and level that suits best to the configuration */
166 static GstVaapiEncoderStatus
ensure_profile_and_level(GstVaapiEncoderMpeg2 * encoder)167 ensure_profile_and_level (GstVaapiEncoderMpeg2 * encoder)
168 {
169   if (!ensure_profile (encoder))
170     return GST_VAAPI_ENCODER_STATUS_ERROR_UNSUPPORTED_PROFILE;
171 
172   if (!ensure_level (encoder))
173     return GST_VAAPI_ENCODER_STATUS_ERROR_OPERATION_FAILED;
174 
175   return GST_VAAPI_ENCODER_STATUS_SUCCESS;
176 }
177 
178 static gboolean
ensure_bitrate(GstVaapiEncoderMpeg2 * encoder)179 ensure_bitrate (GstVaapiEncoderMpeg2 * encoder)
180 {
181   GstVaapiEncoder *const base_encoder = GST_VAAPI_ENCODER_CAST (encoder);
182 
183   /* Default compression: 64 bits per macroblock */
184   switch (GST_VAAPI_ENCODER_RATE_CONTROL (encoder)) {
185     case GST_VAAPI_RATECONTROL_CBR:
186       if (!base_encoder->bitrate)
187         base_encoder->bitrate =
188             gst_util_uint64_scale (GST_VAAPI_ENCODER_WIDTH (encoder) *
189             GST_VAAPI_ENCODER_HEIGHT (encoder),
190             GST_VAAPI_ENCODER_FPS_N (encoder),
191             GST_VAAPI_ENCODER_FPS_D (encoder)) / 4 / 1000;
192       break;
193     default:
194       base_encoder->bitrate = 0;
195       break;
196   }
197   return TRUE;
198 }
199 
200 static gboolean
fill_sequence(GstVaapiEncoderMpeg2 * encoder,GstVaapiEncSequence * sequence)201 fill_sequence (GstVaapiEncoderMpeg2 * encoder, GstVaapiEncSequence * sequence)
202 {
203   GstVaapiEncoder *const base_encoder = GST_VAAPI_ENCODER_CAST (encoder);
204   VAEncSequenceParameterBufferMPEG2 *const seq_param = sequence->param;
205 
206   memset (seq_param, 0, sizeof (VAEncSequenceParameterBufferMPEG2));
207 
208   seq_param->intra_period = base_encoder->keyframe_period;
209   seq_param->ip_period = encoder->ip_period;
210   seq_param->picture_width = GST_VAAPI_ENCODER_WIDTH (encoder);
211   seq_param->picture_height = GST_VAAPI_ENCODER_HEIGHT (encoder);
212 
213   if (base_encoder->bitrate > 0)
214     seq_param->bits_per_second = base_encoder->bitrate * 1000;
215   else
216     seq_param->bits_per_second = 0;
217 
218   if (GST_VAAPI_ENCODER_FPS_D (encoder))
219     seq_param->frame_rate =
220         GST_VAAPI_ENCODER_FPS_N (encoder) / GST_VAAPI_ENCODER_FPS_D (encoder);
221   else
222     seq_param->frame_rate = 0;
223 
224   seq_param->aspect_ratio_information = 1;
225   seq_param->vbv_buffer_size = 3;       /* B = 16 * 1024 * vbv_buffer_size */
226 
227   seq_param->sequence_extension.bits.profile_and_level_indication =
228       (encoder->profile_idc << 4) | encoder->level_idc;
229   seq_param->sequence_extension.bits.progressive_sequence = 1;  /* progressive frame-pictures */
230   seq_param->sequence_extension.bits.chroma_format =
231       gst_vaapi_utils_mpeg2_get_chroma_format_idc
232       (GST_VAAPI_CHROMA_TYPE_YUV420);
233   seq_param->sequence_extension.bits.low_delay = 0;     /* FIXME */
234   seq_param->sequence_extension.bits.frame_rate_extension_n = 0;        /* FIXME */
235   seq_param->sequence_extension.bits.frame_rate_extension_d = 0;
236 
237   seq_param->gop_header.bits.time_code = (1 << 12);     /* bit12: marker_bit */
238   seq_param->gop_header.bits.closed_gop = 0;
239   seq_param->gop_header.bits.broken_link = 0;
240 
241   return TRUE;
242 }
243 
244 static VAEncPictureType
get_va_enc_picture_type(GstVaapiPictureType type)245 get_va_enc_picture_type (GstVaapiPictureType type)
246 {
247   switch (type) {
248     case GST_VAAPI_PICTURE_TYPE_I:
249       return VAEncPictureTypeIntra;
250     case GST_VAAPI_PICTURE_TYPE_P:
251       return VAEncPictureTypePredictive;
252     case GST_VAAPI_PICTURE_TYPE_B:
253       return VAEncPictureTypeBidirectional;
254     default:
255       return -1;
256   }
257   return -1;
258 }
259 
260 static gboolean
fill_picture(GstVaapiEncoderMpeg2 * encoder,GstVaapiEncPicture * picture,GstVaapiCodedBuffer * codedbuf,GstVaapiSurfaceProxy * surface)261 fill_picture (GstVaapiEncoderMpeg2 * encoder,
262     GstVaapiEncPicture * picture,
263     GstVaapiCodedBuffer * codedbuf, GstVaapiSurfaceProxy * surface)
264 {
265   VAEncPictureParameterBufferMPEG2 *const pic_param = picture->param;
266   guint8 f_code_x, f_code_y;
267 
268   memset (pic_param, 0, sizeof (VAEncPictureParameterBufferMPEG2));
269 
270   pic_param->reconstructed_picture =
271       GST_VAAPI_SURFACE_PROXY_SURFACE_ID (surface);
272   pic_param->coded_buf = GST_VAAPI_OBJECT_ID (codedbuf);
273   pic_param->picture_type = get_va_enc_picture_type (picture->type);
274   pic_param->temporal_reference = picture->frame_num & (1024 - 1);
275   pic_param->vbv_delay = 0xFFFF;
276 
277   f_code_x = 0xf;
278   f_code_y = 0xf;
279   if (pic_param->picture_type != VAEncPictureTypeIntra) {
280     switch (encoder->level) {
281       case GST_VAAPI_LEVEL_MPEG2_LOW:
282         f_code_x = 7;
283         f_code_y = 4;
284         break;
285       case GST_VAAPI_LEVEL_MPEG2_MAIN:
286         f_code_x = 8;
287         f_code_y = 5;
288         break;
289       default:                 /* High-1440 and High levels */
290         f_code_x = 9;
291         f_code_y = 5;
292         break;
293     }
294   }
295 
296   if (pic_param->picture_type == VAEncPictureTypeIntra) {
297     pic_param->f_code[0][0] = 0xf;
298     pic_param->f_code[0][1] = 0xf;
299     pic_param->f_code[1][0] = 0xf;
300     pic_param->f_code[1][1] = 0xf;
301     pic_param->forward_reference_picture = VA_INVALID_SURFACE;
302     pic_param->backward_reference_picture = VA_INVALID_SURFACE;
303   } else if (pic_param->picture_type == VAEncPictureTypePredictive) {
304     pic_param->f_code[0][0] = f_code_x;
305     pic_param->f_code[0][1] = f_code_y;
306     pic_param->f_code[1][0] = 0xf;
307     pic_param->f_code[1][1] = 0xf;
308     pic_param->forward_reference_picture =
309         GST_VAAPI_SURFACE_PROXY_SURFACE_ID (encoder->forward);
310     pic_param->backward_reference_picture = VA_INVALID_SURFACE;
311   } else if (pic_param->picture_type == VAEncPictureTypeBidirectional) {
312     pic_param->f_code[0][0] = f_code_x;
313     pic_param->f_code[0][1] = f_code_y;
314     pic_param->f_code[1][0] = f_code_x;
315     pic_param->f_code[1][1] = f_code_y;
316     pic_param->forward_reference_picture =
317         GST_VAAPI_SURFACE_PROXY_SURFACE_ID (encoder->forward);
318     pic_param->backward_reference_picture =
319         GST_VAAPI_SURFACE_PROXY_SURFACE_ID (encoder->backward);
320   } else {
321     g_assert (0);
322   }
323 
324   pic_param->picture_coding_extension.bits.intra_dc_precision = 0;      /* 8bits */
325   pic_param->picture_coding_extension.bits.picture_structure = 3;       /* frame picture */
326   pic_param->picture_coding_extension.bits.top_field_first = 0;
327   pic_param->picture_coding_extension.bits.frame_pred_frame_dct = 1;    /* FIXME */
328   pic_param->picture_coding_extension.bits.concealment_motion_vectors = 0;
329   pic_param->picture_coding_extension.bits.q_scale_type = 0;
330   pic_param->picture_coding_extension.bits.intra_vlc_format = 0;
331   pic_param->picture_coding_extension.bits.alternate_scan = 0;
332   pic_param->picture_coding_extension.bits.repeat_first_field = 0;
333   pic_param->picture_coding_extension.bits.progressive_frame = 1;
334   pic_param->picture_coding_extension.bits.composite_display_flag = 0;
335 
336   return TRUE;
337 }
338 
339 static gboolean
set_sequence_packed_header(GstVaapiEncoderMpeg2 * encoder,GstVaapiEncPicture * picture,GstVaapiEncSequence * sequence)340 set_sequence_packed_header (GstVaapiEncoderMpeg2 * encoder,
341     GstVaapiEncPicture * picture, GstVaapiEncSequence * sequence)
342 {
343   GstVaapiEncPackedHeader *packed_seq;
344   GstBitWriter writer;
345   VAEncPackedHeaderParameterBuffer packed_header_param_buffer = { 0 };
346   const VAEncSequenceParameterBufferMPEG2 *const seq_param = sequence->param;
347   guint32 data_bit_size;
348   guint8 *data;
349 
350   gst_bit_writer_init_with_size (&writer, 128, FALSE);
351   if (encoder->new_gop)
352     gst_bit_writer_write_sps (&writer, seq_param);
353   g_assert (GST_BIT_WRITER_BIT_SIZE (&writer) % 8 == 0);
354   data_bit_size = GST_BIT_WRITER_BIT_SIZE (&writer);
355   data = GST_BIT_WRITER_DATA (&writer);
356 
357   packed_header_param_buffer.type = VAEncPackedHeaderSequence;
358   packed_header_param_buffer.bit_length = data_bit_size;
359   packed_header_param_buffer.has_emulation_bytes = 0;
360 
361   packed_seq = gst_vaapi_enc_packed_header_new (GST_VAAPI_ENCODER (encoder),
362       &packed_header_param_buffer, sizeof (packed_header_param_buffer),
363       data, (data_bit_size + 7) / 8);
364   g_assert (packed_seq);
365 
366   gst_vaapi_enc_picture_add_packed_header (picture, packed_seq);
367   gst_vaapi_codec_object_replace (&packed_seq, NULL);
368   gst_bit_writer_reset (&writer);
369 
370   return TRUE;
371 }
372 
373 static gboolean
set_picture_packed_header(GstVaapiEncoderMpeg2 * encoder,GstVaapiEncPicture * picture)374 set_picture_packed_header (GstVaapiEncoderMpeg2 * encoder,
375     GstVaapiEncPicture * picture)
376 {
377   GstVaapiEncPackedHeader *packed_pic;
378   GstBitWriter writer;
379   VAEncPackedHeaderParameterBuffer packed_header_param_buffer = { 0 };
380   const VAEncPictureParameterBufferMPEG2 *const pic_param = picture->param;
381   guint32 data_bit_size;
382   guint8 *data;
383 
384   gst_bit_writer_init_with_size (&writer, 128, FALSE);
385   gst_bit_writer_write_pps (&writer, pic_param);
386   g_assert (GST_BIT_WRITER_BIT_SIZE (&writer) % 8 == 0);
387   data_bit_size = GST_BIT_WRITER_BIT_SIZE (&writer);
388   data = GST_BIT_WRITER_DATA (&writer);
389 
390   packed_header_param_buffer.type = VAEncPackedHeaderPicture;
391   packed_header_param_buffer.bit_length = data_bit_size;
392   packed_header_param_buffer.has_emulation_bytes = 0;
393 
394   packed_pic = gst_vaapi_enc_packed_header_new (GST_VAAPI_ENCODER (encoder),
395       &packed_header_param_buffer, sizeof (packed_header_param_buffer),
396       data, (data_bit_size + 7) / 8);
397   g_assert (packed_pic);
398 
399   gst_vaapi_enc_picture_add_packed_header (picture, packed_pic);
400   gst_vaapi_codec_object_replace (&packed_pic, NULL);
401   gst_bit_writer_reset (&writer);
402 
403   return TRUE;
404 }
405 
406 static gboolean
ensure_sequence(GstVaapiEncoderMpeg2 * encoder,GstVaapiEncPicture * picture)407 ensure_sequence (GstVaapiEncoderMpeg2 * encoder, GstVaapiEncPicture * picture)
408 {
409   GstVaapiEncSequence *sequence;
410 
411   g_assert (picture);
412   sequence = GST_VAAPI_ENC_SEQUENCE_NEW (MPEG2, encoder);
413   g_assert (sequence);
414   if (!sequence)
415     goto error;
416 
417   if (!fill_sequence (encoder, sequence))
418     goto error;
419 
420   if ((GST_VAAPI_ENCODER_PACKED_HEADERS (encoder) &
421           VA_ENC_PACKED_HEADER_SEQUENCE)
422       && picture->type == GST_VAAPI_PICTURE_TYPE_I
423       && !set_sequence_packed_header (encoder, picture, sequence))
424     goto error;
425   gst_vaapi_enc_picture_set_sequence (picture, sequence);
426   gst_vaapi_codec_object_replace (&sequence, NULL);
427   return TRUE;
428 
429   /* ERRORS */
430 error:
431   {
432     gst_vaapi_codec_object_replace (&sequence, NULL);
433     return FALSE;
434   }
435 }
436 
437 static gboolean
ensure_picture(GstVaapiEncoderMpeg2 * encoder,GstVaapiEncPicture * picture,GstVaapiCodedBufferProxy * codedbuf_proxy,GstVaapiSurfaceProxy * surface)438 ensure_picture (GstVaapiEncoderMpeg2 * encoder, GstVaapiEncPicture * picture,
439     GstVaapiCodedBufferProxy * codedbuf_proxy, GstVaapiSurfaceProxy * surface)
440 {
441   GstVaapiCodedBuffer *const codedbuf =
442       GST_VAAPI_CODED_BUFFER_PROXY_BUFFER (codedbuf_proxy);
443 
444   if (!fill_picture (encoder, picture, codedbuf, surface))
445     return FALSE;
446 
447   if ((GST_VAAPI_ENCODER_PACKED_HEADERS (encoder) &
448           VA_ENC_PACKED_HEADER_PICTURE)
449       && !set_picture_packed_header (encoder, picture)) {
450     GST_ERROR ("set picture packed header failed");
451     return FALSE;
452   }
453   return TRUE;
454 }
455 
456 static gboolean
ensure_control_rate_params(GstVaapiEncoderMpeg2 * encoder)457 ensure_control_rate_params (GstVaapiEncoderMpeg2 * encoder)
458 {
459   GstVaapiEncoder *const base_encoder = GST_VAAPI_ENCODER_CAST (encoder);
460 
461   if (GST_VAAPI_ENCODER_RATE_CONTROL (encoder) == GST_VAAPI_RATECONTROL_CQP)
462     return TRUE;
463 
464   /* RateControl params */
465   GST_VAAPI_ENCODER_VA_RATE_CONTROL (encoder).initial_qp = encoder->cqp;
466 
467   /* *INDENT-OFF* */
468   /* HRD params */
469   GST_VAAPI_ENCODER_VA_HRD (encoder) = (VAEncMiscParameterHRD) {
470     .buffer_size = base_encoder->bitrate * 1000 * 8,
471     .initial_buffer_fullness = base_encoder->bitrate * 1000 * 4,
472   };
473   /* *INDENT-ON* */
474 
475   return TRUE;
476 }
477 
478 static gboolean
set_misc_parameters(GstVaapiEncoderMpeg2 * encoder,GstVaapiEncPicture * picture)479 set_misc_parameters (GstVaapiEncoderMpeg2 * encoder,
480     GstVaapiEncPicture * picture)
481 {
482   GstVaapiEncoder *const base_encoder = GST_VAAPI_ENCODER_CAST (encoder);
483 
484   if (!gst_vaapi_encoder_ensure_param_control_rate (base_encoder, picture))
485     return FALSE;
486   if (!gst_vaapi_encoder_ensure_param_quality_level (base_encoder, picture))
487     return FALSE;
488   return TRUE;
489 }
490 
491 static gboolean
fill_slices(GstVaapiEncoderMpeg2 * encoder,GstVaapiEncPicture * picture)492 fill_slices (GstVaapiEncoderMpeg2 * encoder, GstVaapiEncPicture * picture)
493 {
494   VAEncSliceParameterBufferMPEG2 *slice_param;
495   GstVaapiEncSlice *slice;
496   guint width_in_mbs, height_in_mbs;
497   guint i_slice;
498 
499   g_assert (picture);
500 
501   width_in_mbs = (GST_VAAPI_ENCODER_WIDTH (encoder) + 15) / 16;
502   height_in_mbs = (GST_VAAPI_ENCODER_HEIGHT (encoder) + 15) / 16;
503 
504   for (i_slice = 0; i_slice < height_in_mbs; ++i_slice) {
505     slice = GST_VAAPI_ENC_SLICE_NEW (MPEG2, encoder);
506     g_assert (slice && slice->param_id != VA_INVALID_ID);
507     slice_param = slice->param;
508 
509     memset (slice_param, 0, sizeof (VAEncSliceParameterBufferMPEG2));
510 
511     slice_param->macroblock_address = i_slice * width_in_mbs;
512     slice_param->num_macroblocks = width_in_mbs;
513     slice_param->is_intra_slice = (picture->type == GST_VAAPI_PICTURE_TYPE_I);
514     slice_param->quantiser_scale_code = encoder->cqp / 2;
515 
516     gst_vaapi_enc_picture_add_slice (picture, slice);
517     gst_vaapi_codec_object_replace (&slice, NULL);
518   }
519   return TRUE;
520 }
521 
522 static gboolean
ensure_slices(GstVaapiEncoderMpeg2 * encoder,GstVaapiEncPicture * picture)523 ensure_slices (GstVaapiEncoderMpeg2 * encoder, GstVaapiEncPicture * picture)
524 {
525   g_assert (picture);
526 
527   if (!fill_slices (encoder, picture))
528     return FALSE;
529 
530   return TRUE;
531 }
532 
533 static GstVaapiEncoderStatus
gst_vaapi_encoder_mpeg2_encode(GstVaapiEncoder * base_encoder,GstVaapiEncPicture * picture,GstVaapiCodedBufferProxy * codedbuf)534 gst_vaapi_encoder_mpeg2_encode (GstVaapiEncoder * base_encoder,
535     GstVaapiEncPicture * picture, GstVaapiCodedBufferProxy * codedbuf)
536 {
537   GstVaapiEncoderMpeg2 *const encoder =
538       GST_VAAPI_ENCODER_MPEG2_CAST (base_encoder);
539   GstVaapiEncoderStatus ret = GST_VAAPI_ENCODER_STATUS_ERROR_UNKNOWN;
540   GstVaapiSurfaceProxy *reconstruct = NULL;
541 
542   reconstruct = gst_vaapi_encoder_create_surface (base_encoder);
543 
544   g_assert (GST_VAAPI_SURFACE_PROXY_SURFACE (reconstruct));
545 
546   if (!ensure_sequence (encoder, picture))
547     goto error;
548   if (!ensure_picture (encoder, picture, codedbuf, reconstruct))
549     goto error;
550   if (!set_misc_parameters (encoder, picture))
551     goto error;
552   if (!ensure_slices (encoder, picture))
553     goto error;
554   if (!gst_vaapi_enc_picture_encode (picture))
555     goto error;
556   if (picture->type != GST_VAAPI_PICTURE_TYPE_B) {
557     if (encoder->new_gop)
558       clear_references (encoder);
559     push_reference (encoder, reconstruct);
560   } else if (reconstruct)
561     gst_vaapi_encoder_release_surface (GST_VAAPI_ENCODER (encoder),
562         reconstruct);
563 
564   return GST_VAAPI_ENCODER_STATUS_SUCCESS;
565 
566   /* ERRORS */
567 error:
568   {
569     if (reconstruct)
570       gst_vaapi_encoder_release_surface (GST_VAAPI_ENCODER (encoder),
571           reconstruct);
572     return ret;
573   }
574 }
575 
576 static GstVaapiEncoderStatus
gst_vaapi_encoder_mpeg2_flush(GstVaapiEncoder * base_encoder)577 gst_vaapi_encoder_mpeg2_flush (GstVaapiEncoder * base_encoder)
578 {
579   GstVaapiEncoderMpeg2 *const encoder =
580       GST_VAAPI_ENCODER_MPEG2_CAST (base_encoder);
581   GstVaapiEncPicture *pic;
582 
583   while (!g_queue_is_empty (&encoder->b_frames)) {
584     pic = g_queue_pop_head (&encoder->b_frames);
585     gst_vaapi_enc_picture_unref (pic);
586   }
587   g_queue_clear (&encoder->b_frames);
588 
589   return GST_VAAPI_ENCODER_STATUS_SUCCESS;
590 }
591 
592 static GstVaapiEncoderStatus
gst_vaapi_encoder_mpeg2_reordering(GstVaapiEncoder * base_encoder,GstVideoCodecFrame * frame,GstVaapiEncPicture ** output)593 gst_vaapi_encoder_mpeg2_reordering (GstVaapiEncoder * base_encoder,
594     GstVideoCodecFrame * frame, GstVaapiEncPicture ** output)
595 {
596   GstVaapiEncoderMpeg2 *const encoder =
597       GST_VAAPI_ENCODER_MPEG2_CAST (base_encoder);
598   GstVaapiEncPicture *picture = NULL;
599   GstVaapiEncoderStatus status = GST_VAAPI_ENCODER_STATUS_SUCCESS;
600 
601   if (!frame) {
602     if (g_queue_is_empty (&encoder->b_frames) && encoder->dump_frames) {
603       push_reference (encoder, NULL);
604       encoder->dump_frames = FALSE;
605     }
606     if (!encoder->dump_frames) {
607       return GST_VAAPI_ENCODER_STATUS_NO_SURFACE;
608     }
609     picture = g_queue_pop_head (&encoder->b_frames);
610     g_assert (picture);
611     goto end;
612   }
613 
614   picture = GST_VAAPI_ENC_PICTURE_NEW (MPEG2, encoder, frame);
615   if (!picture) {
616     GST_WARNING ("create MPEG2 picture failed, frame timestamp:%"
617         GST_TIME_FORMAT, GST_TIME_ARGS (frame->pts));
618     return GST_VAAPI_ENCODER_STATUS_ERROR_ALLOCATION_FAILED;
619   }
620 
621   if (encoder->frame_num >= base_encoder->keyframe_period) {
622     encoder->frame_num = 0;
623     clear_references (encoder);
624   }
625   if (encoder->frame_num == 0) {
626     picture->type = GST_VAAPI_PICTURE_TYPE_I;
627     GST_VIDEO_CODEC_FRAME_SET_SYNC_POINT (frame);
628     encoder->new_gop = TRUE;
629   } else {
630     encoder->new_gop = FALSE;
631     if ((encoder->frame_num % (encoder->ip_period + 1)) == 0 ||
632         encoder->frame_num == base_encoder->keyframe_period - 1) {
633       picture->type = GST_VAAPI_PICTURE_TYPE_P;
634       encoder->dump_frames = TRUE;
635     } else {
636       picture->type = GST_VAAPI_PICTURE_TYPE_B;
637       status = GST_VAAPI_ENCODER_STATUS_NO_SURFACE;
638     }
639   }
640   picture->frame_num = encoder->frame_num++;
641 
642   if (picture->type == GST_VAAPI_PICTURE_TYPE_B) {
643     g_queue_push_tail (&encoder->b_frames, picture);
644     picture = NULL;
645   }
646 
647 end:
648   *output = picture;
649   return status;
650 }
651 
652 static GstVaapiEncoderStatus
set_context_info(GstVaapiEncoder * base_encoder)653 set_context_info (GstVaapiEncoder * base_encoder)
654 {
655   GstVaapiEncoderMpeg2 *const encoder =
656       GST_VAAPI_ENCODER_MPEG2_CAST (base_encoder);
657   GstVideoInfo *const vip = GST_VAAPI_ENCODER_VIDEO_INFO (encoder);
658 
659   /* Maximum sizes for common headers (in bytes) */
660   enum
661   {
662     MAX_SEQ_HDR_SIZE = 140,
663     MAX_SEQ_EXT_SIZE = 10,
664     MAX_GOP_SIZE = 8,
665     MAX_PIC_HDR_SIZE = 10,
666     MAX_PIC_EXT_SIZE = 11,
667     MAX_SLICE_HDR_SIZE = 8,
668   };
669 
670   if (!ensure_hw_profile (encoder))
671     return GST_VAAPI_ENCODER_STATUS_ERROR_UNSUPPORTED_PROFILE;
672 
673   base_encoder->num_ref_frames = 2;
674 
675   /* Only YUV 4:2:0 formats are supported for now. This means that we
676      have a limit of 4608 bits per macroblock. */
677   base_encoder->codedbuf_size = (GST_ROUND_UP_16 (vip->width) *
678       GST_ROUND_UP_16 (vip->height) / 256) * 576;
679 
680   /* Account for Sequence, GOP, and Picture headers */
681   /* XXX: exclude unused Sequence Display Extension, Sequence Scalable
682      Extension, Quantization Matrix Extension, Picture Display Extension,
683      Picture Temporal Scalable Extension, Picture Spatial Scalable
684      Extension */
685   base_encoder->codedbuf_size += MAX_SEQ_HDR_SIZE + MAX_SEQ_EXT_SIZE +
686       MAX_GOP_SIZE + MAX_PIC_HDR_SIZE + MAX_PIC_EXT_SIZE;
687 
688   /* Account for Slice headers. We use one slice per line of macroblock */
689   base_encoder->codedbuf_size += (GST_ROUND_UP_16 (vip->height) / 16) *
690       MAX_SLICE_HDR_SIZE;
691 
692   return GST_VAAPI_ENCODER_STATUS_SUCCESS;
693 }
694 
695 static GstVaapiEncoderStatus
gst_vaapi_encoder_mpeg2_reconfigure(GstVaapiEncoder * base_encoder)696 gst_vaapi_encoder_mpeg2_reconfigure (GstVaapiEncoder * base_encoder)
697 {
698   GstVaapiEncoderMpeg2 *const encoder =
699       GST_VAAPI_ENCODER_MPEG2_CAST (base_encoder);
700   GstVaapiEncoderStatus status;
701 
702   if (encoder->ip_period > base_encoder->keyframe_period) {
703     encoder->ip_period = base_encoder->keyframe_period - 1;
704   }
705 
706   status = ensure_profile_and_level (encoder);
707   if (status != GST_VAAPI_ENCODER_STATUS_SUCCESS)
708     return status;
709 
710   if (!ensure_bitrate (encoder))
711     goto error;
712   ensure_control_rate_params (encoder);
713   return set_context_info (base_encoder);
714 
715   /* ERRORS */
716 error:
717   {
718     return GST_VAAPI_ENCODER_STATUS_ERROR_OPERATION_FAILED;
719   }
720 }
721 
722 static gboolean
gst_vaapi_encoder_mpeg2_init(GstVaapiEncoder * base_encoder)723 gst_vaapi_encoder_mpeg2_init (GstVaapiEncoder * base_encoder)
724 {
725   GstVaapiEncoderMpeg2 *const encoder =
726       GST_VAAPI_ENCODER_MPEG2_CAST (base_encoder);
727 
728   /* re-ordering */
729   g_queue_init (&encoder->b_frames);
730 
731   return TRUE;
732 }
733 
734 static void
clear_ref(GstVaapiEncoderMpeg2 * encoder,GstVaapiSurfaceProxy ** ref)735 clear_ref (GstVaapiEncoderMpeg2 * encoder, GstVaapiSurfaceProxy ** ref)
736 {
737   if (*ref) {
738     gst_vaapi_encoder_release_surface (GST_VAAPI_ENCODER (encoder), *ref);
739     *ref = NULL;
740   }
741 }
742 
743 static void
clear_references(GstVaapiEncoderMpeg2 * encoder)744 clear_references (GstVaapiEncoderMpeg2 * encoder)
745 {
746   clear_ref (encoder, &encoder->forward);
747   clear_ref (encoder, &encoder->backward);
748 }
749 
750 static void
push_reference(GstVaapiEncoderMpeg2 * encoder,GstVaapiSurfaceProxy * ref)751 push_reference (GstVaapiEncoderMpeg2 * encoder, GstVaapiSurfaceProxy * ref)
752 {
753   if (encoder->backward) {
754     clear_ref (encoder, &encoder->forward);
755     encoder->forward = encoder->backward;
756     encoder->backward = NULL;
757   }
758   if (encoder->forward)
759     encoder->backward = ref;
760   else
761     encoder->forward = ref;
762 }
763 
764 static void
gst_vaapi_encoder_mpeg2_finalize(GstVaapiEncoder * base_encoder)765 gst_vaapi_encoder_mpeg2_finalize (GstVaapiEncoder * base_encoder)
766 {
767   /* free private buffers */
768   GstVaapiEncoderMpeg2 *const encoder =
769       GST_VAAPI_ENCODER_MPEG2_CAST (base_encoder);
770   GstVaapiEncPicture *pic;
771 
772   clear_references (encoder);
773 
774   while (!g_queue_is_empty (&encoder->b_frames)) {
775     pic = g_queue_pop_head (&encoder->b_frames);
776     gst_vaapi_enc_picture_unref (pic);
777   }
778   g_queue_clear (&encoder->b_frames);
779 }
780 
781 static GstVaapiEncoderStatus
gst_vaapi_encoder_mpeg2_set_property(GstVaapiEncoder * base_encoder,gint prop_id,const GValue * value)782 gst_vaapi_encoder_mpeg2_set_property (GstVaapiEncoder * base_encoder,
783     gint prop_id, const GValue * value)
784 {
785   GstVaapiEncoderMpeg2 *const encoder =
786       GST_VAAPI_ENCODER_MPEG2_CAST (base_encoder);
787 
788   switch (prop_id) {
789     case GST_VAAPI_ENCODER_MPEG2_PROP_QUANTIZER:
790       encoder->cqp = g_value_get_uint (value);
791       break;
792     case GST_VAAPI_ENCODER_MPEG2_PROP_MAX_BFRAMES:
793       encoder->ip_period = g_value_get_uint (value);
794       break;
795     default:
796       return GST_VAAPI_ENCODER_STATUS_ERROR_INVALID_PARAMETER;
797   }
798   return GST_VAAPI_ENCODER_STATUS_SUCCESS;
799 }
800 
801 GST_VAAPI_ENCODER_DEFINE_CLASS_DATA (MPEG2);
802 
803 static inline const GstVaapiEncoderClass *
gst_vaapi_encoder_mpeg2_class(void)804 gst_vaapi_encoder_mpeg2_class (void)
805 {
806   static const GstVaapiEncoderClass GstVaapiEncoderMpeg2Class = {
807     GST_VAAPI_ENCODER_CLASS_INIT (Mpeg2, mpeg2),
808     .set_property = gst_vaapi_encoder_mpeg2_set_property,
809   };
810   return &GstVaapiEncoderMpeg2Class;
811 }
812 
813 /**
814  * gst_vaapi_encoder_mpeg2_new:
815  * @display: a #GstVaapiDisplay
816  *
817  * Creates a new #GstVaapiEncoder for MPEG-2 encoding.
818  *
819  * Return value: the newly allocated #GstVaapiEncoder object
820  */
821 GstVaapiEncoder *
gst_vaapi_encoder_mpeg2_new(GstVaapiDisplay * display)822 gst_vaapi_encoder_mpeg2_new (GstVaapiDisplay * display)
823 {
824   return gst_vaapi_encoder_new (gst_vaapi_encoder_mpeg2_class (), display);
825 }
826 
827 /**
828  * gst_vaapi_encoder_mpeg2_get_default_properties:
829  *
830  * Determines the set of common and MPEG-2 specific encoder properties.
831  * The caller owns an extra reference to the resulting array of
832  * #GstVaapiEncoderPropInfo elements, so it shall be released with
833  * g_ptr_array_unref() after usage.
834  *
835  * Return value: the set of encoder properties for #GstVaapiEncoderMpeg2,
836  *   or %NULL if an error occurred.
837  */
838 GPtrArray *
gst_vaapi_encoder_mpeg2_get_default_properties(void)839 gst_vaapi_encoder_mpeg2_get_default_properties (void)
840 {
841   const GstVaapiEncoderClass *const klass = gst_vaapi_encoder_mpeg2_class ();
842   GPtrArray *props;
843 
844   props = gst_vaapi_encoder_properties_get_default (klass);
845   if (!props)
846     return NULL;
847 
848   GST_VAAPI_ENCODER_PROPERTIES_APPEND (props,
849       GST_VAAPI_ENCODER_MPEG2_PROP_QUANTIZER,
850       g_param_spec_uint ("quantizer",
851           "Constant Quantizer",
852           "Constant quantizer (if rate-control mode is CQP)",
853           2, 62, 8, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
854 
855   GST_VAAPI_ENCODER_PROPERTIES_APPEND (props,
856       GST_VAAPI_ENCODER_MPEG2_PROP_MAX_BFRAMES,
857       g_param_spec_uint ("max-bframes", "Max B-Frames",
858           "Number of B-frames between I and P",
859           0, 16, 0, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
860 
861   return props;
862 }
863 
864 static struct
865 {
866   int code;
867   float value;
868 } frame_rate_tab[] = {
869   /* *INDENT-OFF* */
870   { 1, 23.976 },
871   { 2, 24.0   },
872   { 3, 25.0   },
873   { 4, 29.97  },
874   { 5, 30     },
875   { 6, 50     },
876   { 7, 59.94  },
877   { 8, 60     }
878   /* *INDENT-ON* */
879 };
880 
881 static int
find_frame_rate_code(const VAEncSequenceParameterBufferMPEG2 * seq_param)882 find_frame_rate_code (const VAEncSequenceParameterBufferMPEG2 * seq_param)
883 {
884   unsigned int ndelta, delta = -1;
885   int code = 1, i;
886   float frame_rate_value = seq_param->frame_rate *
887       (seq_param->sequence_extension.bits.frame_rate_extension_d + 1) /
888       (seq_param->sequence_extension.bits.frame_rate_extension_n + 1);
889 
890   for (i = 0; i < G_N_ELEMENTS (frame_rate_tab); i++) {
891 
892     ndelta = fabsf (1000 * frame_rate_tab[i].value - 1000 * frame_rate_value);
893     if (ndelta < delta) {
894       code = frame_rate_tab[i].code;
895       delta = ndelta;
896     }
897   }
898   return code;
899 }
900 
901 static gboolean
gst_bit_writer_write_sps(GstBitWriter * bitwriter,const VAEncSequenceParameterBufferMPEG2 * seq_param)902 gst_bit_writer_write_sps (GstBitWriter * bitwriter,
903     const VAEncSequenceParameterBufferMPEG2 * seq_param)
904 {
905   gst_bit_writer_put_bits_uint32 (bitwriter, START_CODE_SEQ, 32);
906   gst_bit_writer_put_bits_uint32 (bitwriter, seq_param->picture_width, 12);
907   gst_bit_writer_put_bits_uint32 (bitwriter, seq_param->picture_height, 12);
908   gst_bit_writer_put_bits_uint32 (bitwriter,
909       seq_param->aspect_ratio_information, 4);
910   gst_bit_writer_put_bits_uint32 (bitwriter, find_frame_rate_code (seq_param), 4);      /* frame_rate_code */
911   gst_bit_writer_put_bits_uint32 (bitwriter, (seq_param->bits_per_second + 399) / 400, 18);     /* the low 18 bits of bit_rate */
912   gst_bit_writer_put_bits_uint32 (bitwriter, 1, 1);     /* marker_bit */
913   gst_bit_writer_put_bits_uint32 (bitwriter, seq_param->vbv_buffer_size, 10);
914   gst_bit_writer_put_bits_uint32 (bitwriter, 0, 1);     /* constraint_parameter_flag, always 0 for MPEG-2 */
915   gst_bit_writer_put_bits_uint32 (bitwriter, 0, 1);     /* load_intra_quantiser_matrix */
916   gst_bit_writer_put_bits_uint32 (bitwriter, 0, 1);     /* load_non_intra_quantiser_matrix */
917 
918   gst_bit_writer_align_bytes (bitwriter, 0);
919 
920   gst_bit_writer_put_bits_uint32 (bitwriter, START_CODE_EXT, 32);
921   gst_bit_writer_put_bits_uint32 (bitwriter, 1, 4);     /* sequence_extension id */
922   gst_bit_writer_put_bits_uint32 (bitwriter,
923       seq_param->sequence_extension.bits.profile_and_level_indication, 8);
924   gst_bit_writer_put_bits_uint32 (bitwriter,
925       seq_param->sequence_extension.bits.progressive_sequence, 1);
926   gst_bit_writer_put_bits_uint32 (bitwriter,
927       seq_param->sequence_extension.bits.chroma_format, 2);
928   gst_bit_writer_put_bits_uint32 (bitwriter, seq_param->picture_width >> 12, 2);
929   gst_bit_writer_put_bits_uint32 (bitwriter, seq_param->picture_height >> 12,
930       2);
931   gst_bit_writer_put_bits_uint32 (bitwriter, ((seq_param->bits_per_second + 399) / 400) >> 18, 12);     /* bit_rate_extension */
932   gst_bit_writer_put_bits_uint32 (bitwriter, 1, 1);     /* marker_bit */
933   gst_bit_writer_put_bits_uint32 (bitwriter, seq_param->vbv_buffer_size >> 10,
934       8);
935   gst_bit_writer_put_bits_uint32 (bitwriter,
936       seq_param->sequence_extension.bits.low_delay, 1);
937   gst_bit_writer_put_bits_uint32 (bitwriter,
938       seq_param->sequence_extension.bits.frame_rate_extension_n, 2);
939   gst_bit_writer_put_bits_uint32 (bitwriter,
940       seq_param->sequence_extension.bits.frame_rate_extension_d, 5);
941 
942   gst_bit_writer_align_bytes (bitwriter, 0);
943 
944   /* gop header */
945   gst_bit_writer_put_bits_uint32 (bitwriter, START_CODE_GOP, 32);
946   gst_bit_writer_put_bits_uint32 (bitwriter,
947       seq_param->gop_header.bits.time_code, 25);
948   gst_bit_writer_put_bits_uint32 (bitwriter,
949       seq_param->gop_header.bits.closed_gop, 1);
950   gst_bit_writer_put_bits_uint32 (bitwriter,
951       seq_param->gop_header.bits.broken_link, 1);
952 
953   gst_bit_writer_align_bytes (bitwriter, 0);
954 
955   return TRUE;
956 }
957 
958 static gboolean
gst_bit_writer_write_pps(GstBitWriter * bitwriter,const VAEncPictureParameterBufferMPEG2 * pic_param)959 gst_bit_writer_write_pps (GstBitWriter * bitwriter,
960     const VAEncPictureParameterBufferMPEG2 * pic_param)
961 {
962   gst_bit_writer_put_bits_uint32 (bitwriter, START_CODE_PICUTRE, 32);
963   gst_bit_writer_put_bits_uint32 (bitwriter, pic_param->temporal_reference, 10);
964   gst_bit_writer_put_bits_uint32 (bitwriter,
965       pic_param->picture_type == VAEncPictureTypeIntra ? 1 :
966       pic_param->picture_type == VAEncPictureTypePredictive ? 2 : 3, 3);
967   gst_bit_writer_put_bits_uint32 (bitwriter, pic_param->vbv_delay, 16);
968 
969   if (pic_param->picture_type == VAEncPictureTypePredictive ||
970       pic_param->picture_type == VAEncPictureTypeBidirectional) {
971     gst_bit_writer_put_bits_uint32 (bitwriter, 0, 1);   /* full_pel_forward_vector, always 0 for MPEG-2 */
972     gst_bit_writer_put_bits_uint32 (bitwriter, 7, 3);   /* forward_f_code, always 7 for MPEG-2 */
973   }
974 
975   if (pic_param->picture_type == VAEncPictureTypeBidirectional) {
976     gst_bit_writer_put_bits_uint32 (bitwriter, 0, 1);   /* full_pel_backward_vector, always 0 for MPEG-2 */
977     gst_bit_writer_put_bits_uint32 (bitwriter, 7, 3);   /* backward_f_code, always 7 for MPEG-2 */
978   }
979 
980   gst_bit_writer_put_bits_uint32 (bitwriter, 0, 1);     /* extra_bit_picture, 0 */
981 
982   gst_bit_writer_align_bytes (bitwriter, 0);
983 
984   gst_bit_writer_put_bits_uint32 (bitwriter, START_CODE_EXT, 32);
985   gst_bit_writer_put_bits_uint32 (bitwriter, 8, 4);     /* Picture Coding Extension ID: 8 */
986   gst_bit_writer_put_bits_uint32 (bitwriter, pic_param->f_code[0][0], 4);
987   gst_bit_writer_put_bits_uint32 (bitwriter, pic_param->f_code[0][1], 4);
988   gst_bit_writer_put_bits_uint32 (bitwriter, pic_param->f_code[1][0], 4);
989   gst_bit_writer_put_bits_uint32 (bitwriter, pic_param->f_code[1][1], 4);
990 
991   gst_bit_writer_put_bits_uint32 (bitwriter,
992       pic_param->picture_coding_extension.bits.intra_dc_precision, 2);
993   gst_bit_writer_put_bits_uint32 (bitwriter,
994       pic_param->picture_coding_extension.bits.picture_structure, 2);
995   gst_bit_writer_put_bits_uint32 (bitwriter,
996       pic_param->picture_coding_extension.bits.top_field_first, 1);
997   gst_bit_writer_put_bits_uint32 (bitwriter,
998       pic_param->picture_coding_extension.bits.frame_pred_frame_dct, 1);
999   gst_bit_writer_put_bits_uint32 (bitwriter,
1000       pic_param->picture_coding_extension.bits.concealment_motion_vectors, 1);
1001   gst_bit_writer_put_bits_uint32 (bitwriter,
1002       pic_param->picture_coding_extension.bits.q_scale_type, 1);
1003   gst_bit_writer_put_bits_uint32 (bitwriter,
1004       pic_param->picture_coding_extension.bits.intra_vlc_format, 1);
1005   gst_bit_writer_put_bits_uint32 (bitwriter,
1006       pic_param->picture_coding_extension.bits.alternate_scan, 1);
1007   gst_bit_writer_put_bits_uint32 (bitwriter,
1008       pic_param->picture_coding_extension.bits.repeat_first_field, 1);
1009   gst_bit_writer_put_bits_uint32 (bitwriter, 1, 1);     /* always chroma 420 */
1010   gst_bit_writer_put_bits_uint32 (bitwriter,
1011       pic_param->picture_coding_extension.bits.progressive_frame, 1);
1012   gst_bit_writer_put_bits_uint32 (bitwriter,
1013       pic_param->picture_coding_extension.bits.composite_display_flag, 1);
1014 
1015   gst_bit_writer_align_bytes (bitwriter, 0);
1016 
1017   return TRUE;
1018 }
1019