OSDN Git Service

avcodec/vp9block: fix runtime error: signed integer overflow: 196675 * 20670 cannot...
[android-x86/external-ffmpeg.git] / libavcodec / vaapi_encode_mpeg2.c
1 /*
2  * This file is part of FFmpeg.
3  *
4  * FFmpeg is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2.1 of the License, or (at your option) any later version.
8  *
9  * FFmpeg is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with FFmpeg; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17  */
18
19 #include <va/va.h>
20 #include <va/va_enc_mpeg2.h>
21
22 #include "libavutil/avassert.h"
23 #include "libavutil/common.h"
24 #include "libavutil/internal.h"
25 #include "libavutil/opt.h"
26 #include "libavutil/pixfmt.h"
27
28 #include "avcodec.h"
29 #include "internal.h"
30 #include "mpegvideo.h"
31 #include "put_bits.h"
32 #include "vaapi_encode.h"
33
34 typedef struct VAAPIEncodeMPEG2Context {
35     int mb_width;
36     int mb_height;
37
38     int quant_i;
39     int quant_p;
40     int quant_b;
41
42     int64_t last_i_frame;
43
44     unsigned int bit_rate;
45     unsigned int vbv_buffer_size;
46 } VAAPIEncodeMPEG2Context;
47
48
49 #define vseq_var(name)      vseq->name, name
50 #define vseqext_field(name) vseq->sequence_extension.bits.name, name
51 #define vgop_field(name)    vseq->gop_header.bits.name, name
52 #define vpic_var(name)      vpic->name, name
53 #define vpcext_field(name)  vpic->picture_coding_extension.bits.name, name
54 #define vcomp_field(name)   vpic->composite_display.bits.name, name
55
56 #define u2(width, value, name) put_bits(&pbc, width, value)
57 #define u(width, ...) u2(width, __VA_ARGS__)
58
59 static int vaapi_encode_mpeg2_write_sequence_header(AVCodecContext *avctx,
60                                                     char *data, size_t *data_len)
61 {
62     VAAPIEncodeContext                 *ctx = avctx->priv_data;
63     VAEncSequenceParameterBufferMPEG2 *vseq = ctx->codec_sequence_params;
64     VAAPIEncodeMPEG2Context           *priv = ctx->priv_data;
65     PutBitContext pbc;
66
67     init_put_bits(&pbc, data, 8 * *data_len);
68
69     u(32, SEQ_START_CODE, sequence_header_code);
70
71     u(12, vseq->picture_width,  horizontal_size_value);
72     u(12, vseq->picture_height, vertical_size_value);
73     u(4, vseq_var(aspect_ratio_information));
74     u(4, 8, frame_rate_code);
75     u(18, priv->bit_rate & 0x3fff, bit_rate_value);
76     u(1, 1, marker_bit);
77     u(10, priv->vbv_buffer_size & 0x3ff, vbv_buffer_size_value);
78     u(1, 0, constrained_parameters_flag);
79     u(1, 0, load_intra_quantiser_matrix);
80     // intra_quantiser_matrix[64]
81     u(1, 0, load_non_intra_quantiser_matrix);
82     // non_intra_quantiser_matrix[64]
83
84     while (put_bits_count(&pbc) % 8)
85         u(1, 0, zero_bit);
86
87     u(32, EXT_START_CODE, extension_start_code);
88     u(4, 1, extension_start_code_identifier);
89     u(8, vseqext_field(profile_and_level_indication));
90     u(1, vseqext_field(progressive_sequence));
91     u(2, vseqext_field(chroma_format));
92     u(2, 0, horizontal_size_extension);
93     u(2, 0, vertical_size_extension);
94     u(12, priv->bit_rate >> 18, bit_rate_extension);
95     u(1, 1, marker_bit);
96     u(8, priv->vbv_buffer_size >> 10, vbv_buffer_size_extension);
97     u(1, vseqext_field(low_delay));
98     u(2, vseqext_field(frame_rate_extension_n));
99     u(2, vseqext_field(frame_rate_extension_d));
100
101     while (put_bits_count(&pbc) % 8)
102         u(1, 0, zero_bit);
103
104     u(32, GOP_START_CODE, group_start_code);
105     u(25, vgop_field(time_code));
106     u(1, vgop_field(closed_gop));
107     u(1, vgop_field(broken_link));
108
109     while (put_bits_count(&pbc) % 8)
110         u(1, 0, zero_bit);
111
112     *data_len = put_bits_count(&pbc);
113     flush_put_bits(&pbc);
114
115     return 0;
116 }
117
118 static int vaapi_encode_mpeg2_write_picture_header(AVCodecContext *avctx,
119                                                    VAAPIEncodePicture *pic,
120                                                    char *data, size_t *data_len)
121 {
122     VAEncPictureParameterBufferMPEG2 *vpic = pic->codec_picture_params;
123     int picture_coding_type;
124     PutBitContext pbc;
125
126     init_put_bits(&pbc, data, 8 * *data_len);
127
128     u(32, PICTURE_START_CODE, picture_start_code);
129     u(10, vpic_var(temporal_reference));
130
131     switch (vpic->picture_type) {
132     case VAEncPictureTypeIntra:
133         picture_coding_type = AV_PICTURE_TYPE_I;
134         break;
135     case VAEncPictureTypePredictive:
136         picture_coding_type = AV_PICTURE_TYPE_P;
137         break;
138     case VAEncPictureTypeBidirectional:
139         picture_coding_type = AV_PICTURE_TYPE_B;
140         break;
141     default:
142         av_assert0(0 && "invalid picture_coding_type");
143     }
144     u(3, picture_coding_type, picture_coding_type);
145     u(16, 0xffff, vbv_delay);
146     if (picture_coding_type == 2 || picture_coding_type == 3) {
147         u(1, 0, full_pel_forward_vector);
148         u(3, 7, forward_f_code);
149     }
150     if (picture_coding_type == 3) {
151         u(1, 0, full_pel_backward_vector);
152         u(3, 7, backward_f_code);
153     }
154     u(1, 0, extra_bit_picture);
155
156     while (put_bits_count(&pbc) % 8)
157         u(1, 0, zero_bit);
158
159     u(32, EXT_START_CODE, extension_start_code);
160     u(4, 8, extension_start_code_identifier);
161     u(4, vpic_var(f_code[0][0]));
162     u(4, vpic_var(f_code[0][1]));
163     u(4, vpic_var(f_code[1][0]));
164     u(4, vpic_var(f_code[1][1]));
165     u(2, vpcext_field(intra_dc_precision));
166     u(2, vpcext_field(picture_structure));
167     u(1, vpcext_field(top_field_first));
168     u(1, vpcext_field(frame_pred_frame_dct));
169     u(1, vpcext_field(concealment_motion_vectors));
170     u(1, vpcext_field(q_scale_type));
171     u(1, vpcext_field(intra_vlc_format));
172     u(1, vpcext_field(alternate_scan));
173     u(1, vpcext_field(repeat_first_field));
174     u(1, 1, chroma_420_type);
175     u(1, vpcext_field(progressive_frame));
176     u(1, vpcext_field(composite_display_flag));
177     if (vpic->picture_coding_extension.bits.composite_display_flag) {
178         u(1, vcomp_field(v_axis));
179         u(3, vcomp_field(field_sequence));
180         u(1, vcomp_field(sub_carrier));
181         u(7, vcomp_field(burst_amplitude));
182         u(8, vcomp_field(sub_carrier_phase));
183     }
184
185     while (put_bits_count(&pbc) % 8)
186         u(1, 0, zero_bit);
187
188     *data_len = put_bits_count(&pbc);
189     flush_put_bits(&pbc);
190
191     return 0;
192 }
193
194 static int vaapi_encode_mpeg2_init_sequence_params(AVCodecContext *avctx)
195 {
196     VAAPIEncodeContext                 *ctx = avctx->priv_data;
197     VAEncSequenceParameterBufferMPEG2 *vseq = ctx->codec_sequence_params;
198     VAEncPictureParameterBufferMPEG2  *vpic = ctx->codec_picture_params;
199     VAAPIEncodeMPEG2Context           *priv = ctx->priv_data;
200
201     vseq->intra_period   = avctx->gop_size;
202     vseq->ip_period      = ctx->b_per_p + 1;
203
204     vseq->picture_width  = avctx->width;
205     vseq->picture_height = avctx->height;
206
207     vseq->bits_per_second = avctx->bit_rate;
208     if (avctx->framerate.num > 0 && avctx->framerate.den > 0)
209         vseq->frame_rate = (float)avctx->framerate.num / avctx->framerate.den;
210     else
211         vseq->frame_rate = (float)avctx->time_base.num / avctx->time_base.den;
212
213     vseq->aspect_ratio_information = 1;
214     vseq->vbv_buffer_size = avctx->rc_buffer_size / (16 * 1024);
215
216     vseq->sequence_extension.bits.profile_and_level_indication =
217         avctx->profile << 4 | avctx->level;
218     vseq->sequence_extension.bits.progressive_sequence   = 1;
219     vseq->sequence_extension.bits.chroma_format          = 1;
220     vseq->sequence_extension.bits.low_delay              = 0;
221     vseq->sequence_extension.bits.frame_rate_extension_n = 0;
222     vseq->sequence_extension.bits.frame_rate_extension_d = 0;
223
224     vseq->new_gop_header              = 0;
225     vseq->gop_header.bits.time_code   = 0;
226     vseq->gop_header.bits.closed_gop  = 1;
227     vseq->gop_header.bits.broken_link = 0;
228
229     vpic->forward_reference_picture  = VA_INVALID_ID;
230     vpic->backward_reference_picture = VA_INVALID_ID;
231     vpic->reconstructed_picture      = VA_INVALID_ID;
232
233     vpic->coded_buf = VA_INVALID_ID;
234
235     vpic->temporal_reference = 0;
236     vpic->f_code[0][0] = 15;
237     vpic->f_code[0][1] = 15;
238     vpic->f_code[1][0] = 15;
239     vpic->f_code[1][1] = 15;
240
241     vpic->picture_coding_extension.bits.intra_dc_precision     = 0;
242     vpic->picture_coding_extension.bits.picture_structure      = 3;
243     vpic->picture_coding_extension.bits.top_field_first        = 0;
244     vpic->picture_coding_extension.bits.frame_pred_frame_dct   = 1;
245     vpic->picture_coding_extension.bits.concealment_motion_vectors = 0;
246     vpic->picture_coding_extension.bits.q_scale_type           = 0;
247     vpic->picture_coding_extension.bits.intra_vlc_format       = 0;
248     vpic->picture_coding_extension.bits.alternate_scan         = 0;
249     vpic->picture_coding_extension.bits.repeat_first_field     = 0;
250     vpic->picture_coding_extension.bits.progressive_frame      = 1;
251     vpic->picture_coding_extension.bits.composite_display_flag = 0;
252
253     priv->bit_rate = (avctx->bit_rate + 399) / 400;
254     priv->vbv_buffer_size = avctx->rc_buffer_size / (16 * 1024);
255
256     return 0;
257 }
258
259 static int vaapi_encode_mpeg2_init_picture_params(AVCodecContext *avctx,
260                                                  VAAPIEncodePicture *pic)
261 {
262     VAAPIEncodeContext                *ctx = avctx->priv_data;
263     VAEncPictureParameterBufferMPEG2 *vpic = pic->codec_picture_params;
264     VAAPIEncodeMPEG2Context          *priv = ctx->priv_data;
265     int fch, fcv;
266
267     switch (avctx->level) {
268     case 4: // High.
269     case 6: // High 1440.
270         fch = 9;
271         fcv = 5;
272         break;
273     case 8: // Main.
274         fch = 8;
275         fcv = 5;
276         break;
277     case 10: // Low.
278     default:
279         fch = 7;
280         fcv = 4;
281         break;
282     }
283
284     switch (pic->type) {
285     case PICTURE_TYPE_IDR:
286     case PICTURE_TYPE_I:
287         vpic->picture_type = VAEncPictureTypeIntra;
288         priv->last_i_frame = pic->display_order;
289         break;
290     case PICTURE_TYPE_P:
291         vpic->picture_type = VAEncPictureTypePredictive;
292         vpic->forward_reference_picture = pic->refs[0]->recon_surface;
293         vpic->f_code[0][0] = fch;
294         vpic->f_code[0][1] = fcv;
295         break;
296     case PICTURE_TYPE_B:
297         vpic->picture_type = VAEncPictureTypeBidirectional;
298         vpic->forward_reference_picture  = pic->refs[0]->recon_surface;
299         vpic->backward_reference_picture = pic->refs[1]->recon_surface;
300         vpic->f_code[0][0] = fch;
301         vpic->f_code[0][1] = fcv;
302         vpic->f_code[1][0] = fch;
303         vpic->f_code[1][1] = fcv;
304         break;
305     default:
306         av_assert0(0 && "invalid picture type");
307     }
308
309     vpic->reconstructed_picture = pic->recon_surface;
310     vpic->coded_buf = pic->output_buffer;
311
312     vpic->temporal_reference = pic->display_order - priv->last_i_frame;
313
314     pic->nb_slices = priv->mb_height;
315
316     return 0;
317 }
318
319 static int vaapi_encode_mpeg2_init_slice_params(AVCodecContext *avctx,
320                                                VAAPIEncodePicture *pic,
321                                                VAAPIEncodeSlice *slice)
322 {
323     VAAPIEncodeContext                  *ctx = avctx->priv_data;
324     VAEncSliceParameterBufferMPEG2   *vslice = slice->codec_slice_params;
325     VAAPIEncodeMPEG2Context            *priv = ctx->priv_data;
326     int qp;
327
328     vslice->macroblock_address = priv->mb_width * slice->index;
329     vslice->num_macroblocks    = priv->mb_width;
330
331     switch (pic->type) {
332     case PICTURE_TYPE_IDR:
333     case PICTURE_TYPE_I:
334         qp = priv->quant_i;
335         break;
336     case PICTURE_TYPE_P:
337         qp = priv->quant_p;
338         break;
339     case PICTURE_TYPE_B:
340         qp = priv->quant_b;
341         break;
342     default:
343         av_assert0(0 && "invalid picture type");
344     }
345
346     vslice->quantiser_scale_code = qp;
347     vslice->is_intra_slice = (pic->type == PICTURE_TYPE_IDR ||
348                               pic->type == PICTURE_TYPE_I);
349
350     return 0;
351 }
352
353 static av_cold int vaapi_encode_mpeg2_configure(AVCodecContext *avctx)
354 {
355     VAAPIEncodeContext       *ctx = avctx->priv_data;
356     VAAPIEncodeMPEG2Context *priv = ctx->priv_data;
357
358     priv->mb_width  = FFALIGN(avctx->width,  16) / 16;
359     priv->mb_height = FFALIGN(avctx->height, 16) / 16;
360
361     if (ctx->va_rc_mode == VA_RC_CQP) {
362         priv->quant_p = av_clip(avctx->global_quality, 1, 31);
363         if (avctx->i_quant_factor > 0.0)
364             priv->quant_i = av_clip((avctx->global_quality *
365                                      avctx->i_quant_factor +
366                                      avctx->i_quant_offset) + 0.5,
367                                     1, 31);
368         else
369             priv->quant_i = priv->quant_p;
370         if (avctx->b_quant_factor > 0.0)
371             priv->quant_b = av_clip((avctx->global_quality *
372                                      avctx->b_quant_factor +
373                                      avctx->b_quant_offset) + 0.5,
374                                     1, 31);
375         else
376             priv->quant_b = priv->quant_p;
377
378         av_log(avctx, AV_LOG_DEBUG, "Using fixed quantiser "
379                "%d / %d / %d for I- / P- / B-frames.\n",
380                priv->quant_i, priv->quant_p, priv->quant_b);
381
382     } else {
383         av_assert0(0 && "Invalid RC mode.");
384     }
385
386     return 0;
387 }
388
389 static const VAAPIEncodeType vaapi_encode_type_mpeg2 = {
390     .priv_data_size        = sizeof(VAAPIEncodeMPEG2Context),
391
392     .configure             = &vaapi_encode_mpeg2_configure,
393
394     .sequence_params_size  = sizeof(VAEncSequenceParameterBufferMPEG2),
395     .init_sequence_params  = &vaapi_encode_mpeg2_init_sequence_params,
396
397     .picture_params_size   = sizeof(VAEncPictureParameterBufferMPEG2),
398     .init_picture_params   = &vaapi_encode_mpeg2_init_picture_params,
399
400     .slice_params_size     = sizeof(VAEncSliceParameterBufferMPEG2),
401     .init_slice_params     = &vaapi_encode_mpeg2_init_slice_params,
402
403     .sequence_header_type  = VAEncPackedHeaderSequence,
404     .write_sequence_header = &vaapi_encode_mpeg2_write_sequence_header,
405
406     .picture_header_type   = VAEncPackedHeaderPicture,
407     .write_picture_header  = &vaapi_encode_mpeg2_write_picture_header,
408 };
409
410 static av_cold int vaapi_encode_mpeg2_init(AVCodecContext *avctx)
411 {
412     VAAPIEncodeContext *ctx = avctx->priv_data;
413
414     ctx->codec = &vaapi_encode_type_mpeg2;
415
416     switch (avctx->profile) {
417     case FF_PROFILE_MPEG2_SIMPLE:
418         ctx->va_profile = VAProfileMPEG2Simple;
419         break;
420     case FF_PROFILE_MPEG2_MAIN:
421         ctx->va_profile = VAProfileMPEG2Main;
422         break;
423     default:
424         av_log(avctx, AV_LOG_ERROR, "Unknown MPEG-2 profile %d.\n",
425                avctx->profile);
426         return AVERROR(EINVAL);
427     }
428
429     ctx->va_entrypoint = VAEntrypointEncSlice;
430     ctx->va_rt_format  = VA_RT_FORMAT_YUV420;
431     ctx->va_rc_mode    = VA_RC_CQP;
432
433     ctx->va_packed_headers = VA_ENC_PACKED_HEADER_SEQUENCE |
434                              VA_ENC_PACKED_HEADER_PICTURE;
435
436     ctx->surface_width  = FFALIGN(avctx->width,  16);
437     ctx->surface_height = FFALIGN(avctx->height, 16);
438
439     return ff_vaapi_encode_init(avctx);
440 }
441
442 static const AVCodecDefault vaapi_encode_mpeg2_defaults[] = {
443     { "profile",        "4"   },
444     { "level",          "4"   },
445     { "bf",             "1"   },
446     { "g",              "120" },
447     { "i_qfactor",      "1"   },
448     { "i_qoffset",      "0"   },
449     { "b_qfactor",      "6/5" },
450     { "b_qoffset",      "0"   },
451     { "global_quality", "10"  },
452     { NULL },
453 };
454
455 AVCodec ff_mpeg2_vaapi_encoder = {
456     .name           = "mpeg2_vaapi",
457     .long_name      = NULL_IF_CONFIG_SMALL("MPEG-2 (VAAPI)"),
458     .type           = AVMEDIA_TYPE_VIDEO,
459     .id             = AV_CODEC_ID_MPEG2VIDEO,
460     .priv_data_size = sizeof(VAAPIEncodeContext),
461     .init           = &vaapi_encode_mpeg2_init,
462     .encode2        = &ff_vaapi_encode2,
463     .close          = &ff_vaapi_encode_close,
464     .capabilities   = AV_CODEC_CAP_DELAY,
465     .defaults       = vaapi_encode_mpeg2_defaults,
466     .pix_fmts = (const enum AVPixelFormat[]) {
467         AV_PIX_FMT_VAAPI,
468         AV_PIX_FMT_NONE,
469     },
470 };