History

vaapi_mpeg2: Convert to use coded bitstream infrastructure

Mark Thompson committed 9 years ago

Commit 10eb4961 parent b5859e02 files · +424 −216Browse files

Showing the changes to libavcodec/vaapi_encode_mpeg2.c (1 of 2 files). Show all

Unified · Split

libavcodec/vaapi_encode_mpeg2.c+423−215
@@ -20,15 +20,11 @@ · 19 unmodified lines
20#include <va/va_enc_mpeg2.h>20#include <va/va_enc_mpeg2.h>
21 21
22#include "libavutil/avassert.h"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 23
28#include "avcodec.h"24#include "avcodec.h"
29#include "internal.h"25#include "cbs.h"
30#include "mpegvideo.h"26#include "cbs_mpeg2.h"
31#include "put_bits.h"27#include "mpeg12.h"
32#include "vaapi_encode.h"28#include "vaapi_encode.h"
33 29
34typedef struct VAAPIEncodeMPEG2Context {30typedef struct VAAPIEncodeMPEG2Context {
@@ -39,79 +35,104 @@ typedef struct VAAPIEncodeMPEG2Context { · 4 unmodified lines
39 int quant_p;35 int quant_p;
40 int quant_b;36 int quant_b;
41 37
38 MPEG2RawSequenceHeader sequence_header;
39 MPEG2RawExtensionData sequence_extension;
40 MPEG2RawExtensionData sequence_display_extension;
41 MPEG2RawGroupOfPicturesHeader gop_header;
42 MPEG2RawPictureHeader picture_header;
43 MPEG2RawExtensionData picture_coding_extension;
44
42 int64_t last_i_frame;45 int64_t last_i_frame;
43 46
44 unsigned int bit_rate;47 unsigned int bit_rate;
45 unsigned int vbv_buffer_size;48 unsigned int vbv_buffer_size;
49
50 AVRational frame_rate;
51
52 unsigned int f_code_horizontal;
53 unsigned int f_code_vertical;
54
55 CodedBitstreamContext cbc;
56 CodedBitstreamFragment current_fragment;
46} VAAPIEncodeMPEG2Context;57} VAAPIEncodeMPEG2Context;
47 58
48 59
49#define vseq_var(name) vseq->name, name60static int vaapi_encode_mpeg2_write_fragment(AVCodecContext *avctx,
50#define vseqext_field(name) vseq->sequence_extension.bits.name, name61 char *data, size_t *data_len,
51#define vgop_field(name) vseq->gop_header.bits.name, name62 CodedBitstreamFragment *frag)
52#define vpic_var(name) vpic->name, name63{
53#define vpcext_field(name) vpic->picture_coding_extension.bits.name, name64 VAAPIEncodeContext *ctx = avctx->priv_data;
54#define vcomp_field(name) vpic->composite_display.bits.name, name65 VAAPIEncodeMPEG2Context *priv = ctx->priv_data;
66 int err;
67
68 err = ff_cbs_write_fragment_data(&priv->cbc, frag);
69 if (err < 0) {
70 av_log(avctx, AV_LOG_ERROR, "Failed to write packed header.\n");
71 return err;
72 }
73
74 if (*data_len < 8 * frag->data_size - frag->data_bit_padding) {
75 av_log(avctx, AV_LOG_ERROR, "Access unit too large: "
76 "%zu < %zu.\n", *data_len,
77 8 * frag->data_size - frag->data_bit_padding);
78 return AVERROR(ENOSPC);
79 }
80
81 memcpy(data, frag->data, frag->data_size);
82 *data_len = 8 * frag->data_size - frag->data_bit_padding;
83
84 return 0;
85}
86
87static int vaapi_encode_mpeg2_add_header(AVCodecContext *avctx,
88 CodedBitstreamFragment *frag,
89 int type, void *header)
90{
91 VAAPIEncodeContext *ctx = avctx->priv_data;
92 VAAPIEncodeMPEG2Context *priv = ctx->priv_data;
93 int err;
94
95 err = ff_cbs_insert_unit_content(&priv->cbc, frag, -1, type, header);
96 if (err < 0) {
97 av_log(avctx, AV_LOG_ERROR, "Failed to add header: "
98 "type = %d.\n", type);
99 return err;
100 }
55 101
56#define u2(width, value, name) put_bits(&pbc, width, value)102 return 0;
57#define u(width, ...) u2(width, __VA_ARGS__)103}
58 104
59static int vaapi_encode_mpeg2_write_sequence_header(AVCodecContext *avctx,105static int vaapi_encode_mpeg2_write_sequence_header(AVCodecContext *avctx,
60 char *data, size_t *data_len)106 char *data, size_t *data_len)
61{107{
62 VAAPIEncodeContext *ctx = avctx->priv_data;108 VAAPIEncodeContext *ctx = avctx->priv_data;
63 VAEncSequenceParameterBufferMPEG2 *vseq = ctx->codec_sequence_params;109 VAAPIEncodeMPEG2Context *priv = ctx->priv_data;
64 VAAPIEncodeMPEG2Context *priv = ctx->priv_data;110 CodedBitstreamFragment *frag = &priv->current_fragment;
65 PutBitContext pbc;111 int err;
66 112
67 init_put_bits(&pbc, data, 8 * *data_len);113 err = vaapi_encode_mpeg2_add_header(avctx, frag, MPEG2_START_SEQUENCE_HEADER,
68 114 &priv->sequence_header);
69 u(32, SEQ_START_CODE, sequence_header_code);115 if (err < 0)
70 116 goto fail;
71 u(12, vseq->picture_width, horizontal_size_value);117
72 u(12, vseq->picture_height, vertical_size_value);118 err = vaapi_encode_mpeg2_add_header(avctx, frag, MPEG2_START_EXTENSION,
73 u(4, vseq_var(aspect_ratio_information));119 &priv->sequence_extension);
74 u(4, 8, frame_rate_code);120 if (err < 0)
75 u(18, priv->bit_rate & 0x3fff, bit_rate_value);121 goto fail;
76 u(1, 1, marker_bit);122
77 u(10, priv->vbv_buffer_size & 0x3ff, vbv_buffer_size_value);123 err = vaapi_encode_mpeg2_add_header(avctx, frag, MPEG2_START_EXTENSION,
78 u(1, 0, constrained_parameters_flag);124 &priv->sequence_display_extension);
79 u(1, 0, load_intra_quantiser_matrix);125 if (err < 0)
80 // intra_quantiser_matrix[64]126 goto fail;
81 u(1, 0, load_non_intra_quantiser_matrix);127
82 // non_intra_quantiser_matrix[64]128 err = vaapi_encode_mpeg2_add_header(avctx, frag, MPEG2_START_GROUP,
83 129 &priv->gop_header);
84 while (put_bits_count(&pbc) % 8)130 if (err < 0)
85 u(1, 0, zero_bit);131 goto fail;
86 132
87 u(32, EXT_START_CODE, extension_start_code);133 err = vaapi_encode_mpeg2_write_fragment(avctx, data, data_len, frag);
88 u(4, 1, extension_start_code_identifier);134fail:
89 u(8, vseqext_field(profile_and_level_indication));135 ff_cbs_fragment_uninit(&priv->cbc, frag);
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;136 return 0;
116}137}
117 138
@@ -119,139 +140,275 @@ static int vaapi_encode_mpeg2_write_picture_header(AVCodecContext *avctx, · 1 unmodified line
119 VAAPIEncodePicture *pic,140 VAAPIEncodePicture *pic,
120 char *data, size_t *data_len)141 char *data, size_t *data_len)
121{142{
122 VAEncPictureParameterBufferMPEG2 *vpic = pic->codec_picture_params;143 VAAPIEncodeContext *ctx = avctx->priv_data;
123 int picture_coding_type;144 VAAPIEncodeMPEG2Context *priv = ctx->priv_data;
124 PutBitContext pbc;145 CodedBitstreamFragment *frag = &priv->current_fragment;
146 int err;
147
148 err = vaapi_encode_mpeg2_add_header(avctx, frag, MPEG2_START_PICTURE,
149 &priv->picture_header);
150 if (err < 0)
151 goto fail;
152
153 err = vaapi_encode_mpeg2_add_header(avctx, frag, MPEG2_START_EXTENSION,
154 &priv->picture_coding_extension);
155 if (err < 0)
156 goto fail;
157
158 err = vaapi_encode_mpeg2_write_fragment(avctx, data, data_len, frag);
159fail:
160 ff_cbs_fragment_uninit(&priv->cbc, frag);
161 return 0;
162}
125 163
126 init_put_bits(&pbc, data, 8 * *data_len);164static int vaapi_encode_mpeg2_init_sequence_params(AVCodecContext *avctx)
165{
166 VAAPIEncodeContext *ctx = avctx->priv_data;
167 VAAPIEncodeMPEG2Context *priv = ctx->priv_data;
168 MPEG2RawSequenceHeader *sh = &priv->sequence_header;
169 MPEG2RawSequenceExtension *se = &priv->sequence_extension.data.sequence;
170 MPEG2RawSequenceDisplayExtension *sde = &priv->sequence_display_extension.data.sequence_display;
171 MPEG2RawGroupOfPicturesHeader *goph = &priv->gop_header;
172 MPEG2RawPictureHeader *ph = &priv->picture_header;
173 MPEG2RawPictureCodingExtension *pce = &priv->picture_coding_extension.data.picture_coding;
174 VAEncSequenceParameterBufferMPEG2 *vseq = ctx->codec_sequence_params;
175 VAEncPictureParameterBufferMPEG2 *vpic = ctx->codec_picture_params;
176 int code, ext_n, ext_d;
127 177
128 u(32, PICTURE_START_CODE, picture_start_code);178 memset(sh, 0, sizeof(*sh));
129 u(10, vpic_var(temporal_reference));179 memset(se, 0, sizeof(*se));
180 memset(sde, 0, sizeof(*sde));
181 memset(goph, 0, sizeof(*goph));
182 memset(ph, 0, sizeof(*ph));
183 memset(pce, 0, sizeof(*pce));
130 184
131 switch (vpic->picture_type) {185
132 case VAEncPictureTypeIntra:186 if (avctx->bit_rate > 0) {
133 picture_coding_type = AV_PICTURE_TYPE_I;187 priv->bit_rate = (avctx->bit_rate + 399) / 400;
134 break;188 } else {
135 case VAEncPictureTypePredictive:189 // Unknown (not a bitrate-targetting mode), so just use the
136 picture_coding_type = AV_PICTURE_TYPE_P;190 // highest value.
191 priv->bit_rate = 0x3fffffff;
192 }
193 if (avctx->rc_buffer_size > 0) {
194 priv->vbv_buffer_size = (avctx->rc_buffer_size + (1 << 14) - 1) >> 14;
195 } else {
196 // Unknown, so guess a value from the bitrate.
197 priv->vbv_buffer_size = priv->bit_rate >> 14;
198 }
199
200 switch (avctx->level) {
201 case 4: // High.
202 case 6: // High 1440.
203 priv->f_code_horizontal = 9;
204 priv->f_code_vertical = 5;
137 break;205 break;
138 case VAEncPictureTypeBidirectional:206 case 8: // Main.
139 picture_coding_type = AV_PICTURE_TYPE_B;207 priv->f_code_horizontal = 8;
208 priv->f_code_vertical = 5;
140 break;209 break;
210 case 10: // Low.
141 default:211 default:
142 av_assert0(0 && "invalid picture_coding_type");212 priv->f_code_horizontal = 7;
143 }213 priv->f_code_vertical = 4;
144 u(3, picture_coding_type, picture_coding_type);214 break;
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 }215 }
154 u(1, 0, extra_bit_picture);216
155 217
156 while (put_bits_count(&pbc) % 8)218 // Sequence header
157 u(1, 0, zero_bit);219
158 220 sh->sequence_header_code = MPEG2_START_SEQUENCE_HEADER;
159 u(32, EXT_START_CODE, extension_start_code);221
160 u(4, 8, extension_start_code_identifier);222 sh->horizontal_size_value = avctx->width & 0xfff;
161 u(4, vpic_var(f_code[0][0]));223 sh->vertical_size_value = avctx->height & 0xfff;
162 u(4, vpic_var(f_code[0][1]));224
163 u(4, vpic_var(f_code[1][0]));225 if (avctx->sample_aspect_ratio.num != 0 &&
164 u(4, vpic_var(f_code[1][1]));226 avctx->sample_aspect_ratio.den != 0) {
165 u(2, vpcext_field(intra_dc_precision));227 AVRational dar = av_div_q(avctx->sample_aspect_ratio,
166 u(2, vpcext_field(picture_structure));228 (AVRational) { avctx->width, avctx->height });
167 u(1, vpcext_field(top_field_first));229
168 u(1, vpcext_field(frame_pred_frame_dct));230 if (av_cmp_q(avctx->sample_aspect_ratio, (AVRational) { 1, 1 }) == 0) {
169 u(1, vpcext_field(concealment_motion_vectors));231 sh->aspect_ratio_information = 1;
170 u(1, vpcext_field(q_scale_type));232 } else if (av_cmp_q(dar, (AVRational) { 3, 4 }) == 0) {
171 u(1, vpcext_field(intra_vlc_format));233 sh->aspect_ratio_information = 2;
172 u(1, vpcext_field(alternate_scan));234 } else if (av_cmp_q(dar, (AVRational) { 9, 16 }) == 0) {
173 u(1, vpcext_field(repeat_first_field));235 sh->aspect_ratio_information = 3;
174 u(1, 1, chroma_420_type);236 } else if (av_cmp_q(dar, (AVRational) { 100, 221 }) == 0) {
175 u(1, vpcext_field(progressive_frame));237 sh->aspect_ratio_information = 4;
176 u(1, vpcext_field(composite_display_flag));238 } else {
177 if (vpic->picture_coding_extension.bits.composite_display_flag) {239 av_log(avctx, AV_LOG_WARNING, "Sample aspect ratio %d:%d is not "
178 u(1, vcomp_field(v_axis));240 "representable, signalling square pixels instead.\n",
179 u(3, vcomp_field(field_sequence));241 avctx->sample_aspect_ratio.num,
180 u(1, vcomp_field(sub_carrier));242 avctx->sample_aspect_ratio.den);
181 u(7, vcomp_field(burst_amplitude));243 sh->aspect_ratio_information = 1;
182 u(8, vcomp_field(sub_carrier_phase));244 }
245 } else {
246 // Unknown - assume square pixels.
247 sh->aspect_ratio_information = 1;
183 }248 }
184 249
185 while (put_bits_count(&pbc) % 8)250 if (avctx->framerate.num > 0 && avctx->framerate.den > 0)
186 u(1, 0, zero_bit);251 priv->frame_rate = avctx->framerate;
252 else
253 priv->frame_rate = av_inv_q(avctx->time_base);
254 ff_mpeg12_find_best_frame_rate(priv->frame_rate,
255 &code, &ext_n, &ext_d, 0);
256 sh->frame_rate_code = code;
187 257
188 *data_len = put_bits_count(&pbc);258 sh->bit_rate_value = priv->bit_rate & 0x3ffff;
189 flush_put_bits(&pbc);259 sh->vbv_buffer_size_value = priv->vbv_buffer_size & 0x3ff;
190 260
191 return 0;261 sh->constrained_parameters_flag = 0;
192}262 sh->load_intra_quantiser_matrix = 0;
263 sh->load_non_intra_quantiser_matrix = 0;
193 264
194static 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 265
201 vseq->intra_period = avctx->gop_size;266 // Sequence extension
202 vseq->ip_period = ctx->b_per_p + 1;
203 267
204 vseq->picture_width = avctx->width;268 priv->sequence_extension.extension_start_code = MPEG2_START_EXTENSION;
205 vseq->picture_height = avctx->height;269 priv->sequence_extension.extension_start_code_identifier =
270 MPEG2_EXTENSION_SEQUENCE;
206 271
207 vseq->bits_per_second = avctx->bit_rate;272 se->profile_and_level_indication = avctx->profile << 4 | avctx->level;
208 if (avctx->framerate.num > 0 && avctx->framerate.den > 0)273 se->progressive_sequence = 1;
209 vseq->frame_rate = (float)avctx->framerate.num / avctx->framerate.den;274 se->chroma_format = 1;
210 else275
211 vseq->frame_rate = (float)avctx->time_base.num / avctx->time_base.den;276 se->horizontal_size_extension = avctx->width >> 12;
212 277 se->vertical_size_extension = avctx->height >> 12;
213 vseq->aspect_ratio_information = 1;278
214 vseq->vbv_buffer_size = avctx->rc_buffer_size / (16 * 1024);279 se->bit_rate_extension = priv->bit_rate >> 18;
215 280 se->vbv_buffer_size_extension = priv->vbv_buffer_size >> 10;
216 vseq->sequence_extension.bits.profile_and_level_indication =281 se->low_delay = ctx->b_per_p == 0;
217 avctx->profile << 4 | avctx->level;282
218 vseq->sequence_extension.bits.progressive_sequence = 1;283 se->frame_rate_extension_n = ext_n;
219 vseq->sequence_extension.bits.chroma_format = 1;284 se->frame_rate_extension_d = ext_d;
220 vseq->sequence_extension.bits.low_delay = 0;285
221 vseq->sequence_extension.bits.frame_rate_extension_n = 0;286
222 vseq->sequence_extension.bits.frame_rate_extension_d = 0;287 // Sequence display extension
223 288
224 vseq->new_gop_header = 0;289 priv->sequence_display_extension.extension_start_code =
225 vseq->gop_header.bits.time_code = 0;290 MPEG2_START_EXTENSION;
226 vseq->gop_header.bits.closed_gop = 1;291 priv->sequence_display_extension.extension_start_code_identifier =
227 vseq->gop_header.bits.broken_link = 0;292 MPEG2_EXTENSION_SEQUENCE_DISPLAY;
228 293
229 vpic->forward_reference_picture = VA_INVALID_ID;294 sde->video_format = 5;
230 vpic->backward_reference_picture = VA_INVALID_ID;295 if (avctx->color_primaries != AVCOL_PRI_UNSPECIFIED ||
231 vpic->reconstructed_picture = VA_INVALID_ID;296 avctx->color_trc != AVCOL_TRC_UNSPECIFIED ||
232 297 avctx->colorspace != AVCOL_SPC_UNSPECIFIED) {
233 vpic->coded_buf = VA_INVALID_ID;298 sde->colour_description = 1;
234 299 sde->colour_primaries = avctx->color_primaries;
235 vpic->temporal_reference = 0;300 sde->transfer_characteristics = avctx->color_trc;
236 vpic->f_code[0][0] = 15;301 sde->matrix_coefficients = avctx->colorspace;
237 vpic->f_code[0][1] = 15;302 } else {
238 vpic->f_code[1][0] = 15;303 sde->colour_description = 0;
239 vpic->f_code[1][1] = 15;304 }
240 305
241 vpic->picture_coding_extension.bits.intra_dc_precision = 0;306 sde->display_horizontal_size = avctx->width;
242 vpic->picture_coding_extension.bits.picture_structure = 3;307 sde->display_vertical_size = avctx->height;
243 vpic->picture_coding_extension.bits.top_field_first = 0;308
244 vpic->picture_coding_extension.bits.frame_pred_frame_dct = 1;309
245 vpic->picture_coding_extension.bits.concealment_motion_vectors = 0;310 // GOP header
246 vpic->picture_coding_extension.bits.q_scale_type = 0;311
247 vpic->picture_coding_extension.bits.intra_vlc_format = 0;312 goph->group_start_code = MPEG2_START_GROUP;
248 vpic->picture_coding_extension.bits.alternate_scan = 0;313
249 vpic->picture_coding_extension.bits.repeat_first_field = 0;314 goph->time_code = 0;
250 vpic->picture_coding_extension.bits.progressive_frame = 1;315 goph->closed_gop = 1;
251 vpic->picture_coding_extension.bits.composite_display_flag = 0;316 goph->broken_link = 0;
252 317
253 priv->bit_rate = (avctx->bit_rate + 399) / 400;318
254 priv->vbv_buffer_size = avctx->rc_buffer_size / (16 * 1024);319 // Defaults for picture header
320
321 ph->picture_start_code = MPEG2_START_PICTURE;
322
323 ph->vbv_delay = 0xffff; // Not currently calculated.
324
325 ph->full_pel_forward_vector = 0;
326 ph->forward_f_code = 7;
327 ph->full_pel_backward_vector = 0;
328 ph->forward_f_code = 7;
329
330
331 // Defaults for picture coding extension
332
333 priv->picture_coding_extension.extension_start_code =
334 MPEG2_START_EXTENSION;
335 priv->picture_coding_extension.extension_start_code_identifier =
336 MPEG2_EXTENSION_PICTURE_CODING;
337
338 pce->intra_dc_precision = 0;
339 pce->picture_structure = 3;
340 pce->top_field_first = 0;
341 pce->frame_pred_frame_dct = 1;
342 pce->concealment_motion_vectors = 0;
343 pce->q_scale_type = 0;
344 pce->intra_vlc_format = 0;
345 pce->alternate_scan = 0;
346 pce->repeat_first_field = 0;
347 pce->progressive_frame = 1;
348 pce->composite_display_flag = 0;
349
350
351
352 *vseq = (VAEncSequenceParameterBufferMPEG2) {
353 .intra_period = avctx->gop_size,
354 .ip_period = ctx->b_per_p + 1,
355
356 .picture_width = avctx->width,
357 .picture_height = avctx->height,
358
359 .bits_per_second = avctx->bit_rate,
360 .frame_rate = av_q2d(priv->frame_rate),
361 .aspect_ratio_information = sh->aspect_ratio_information,
362 .vbv_buffer_size = priv->vbv_buffer_size,
363
364 .sequence_extension.bits = {
365 .profile_and_level_indication = se->profile_and_level_indication,
366 .progressive_sequence = se->progressive_sequence,
367 .chroma_format = se->chroma_format,
368 .low_delay = se->low_delay,
369 .frame_rate_extension_n = se->frame_rate_extension_n,
370 .frame_rate_extension_d = se->frame_rate_extension_d,
371 },
372
373 .new_gop_header = 1,
374 .gop_header.bits = {
375 .time_code = goph->time_code,
376 .closed_gop = goph->closed_gop,
377 .broken_link = goph->broken_link,
378 },
379 };
380
381 *vpic = (VAEncPictureParameterBufferMPEG2) {
382 .forward_reference_picture = VA_INVALID_ID,
383 .backward_reference_picture = VA_INVALID_ID,
384 .reconstructed_picture = VA_INVALID_ID,
385 .coded_buf = VA_INVALID_ID,
386
387 .vbv_delay = 0xffff,
388 .f_code = { { 15, 15 }, { 15, 15 } },
389
390 .picture_coding_extension.bits = {
391 .intra_dc_precision = pce->intra_dc_precision,
392 .picture_structure = pce->picture_structure,
393 .top_field_first = pce->top_field_first,
394 .frame_pred_frame_dct = pce->frame_pred_frame_dct,
395 .concealment_motion_vectors = pce->concealment_motion_vectors,
396 .q_scale_type = pce->q_scale_type,
397 .intra_vlc_format = pce->intra_vlc_format,
398 .alternate_scan = pce->alternate_scan,
399 .repeat_first_field = pce->repeat_first_field,
400 .progressive_frame = pce->progressive_frame,
401 .composite_display_flag = pce->composite_display_flag,
402 },
403
404 .composite_display.bits = {
405 .v_axis = pce->v_axis,
406 .field_sequence = pce->field_sequence,
407 .sub_carrier = pce->sub_carrier,
408 .burst_amplitude = pce->burst_amplitude,
409 .sub_carrier_phase = pce->sub_carrier_phase,
410 },
411 };
255 412
256 return 0;413 return 0;
257}414}
@@ -260,56 +417,61 @@ static int vaapi_encode_mpeg2_init_picture_params(AVCodecContext *avctx, · 2 unmodified lines
260 VAAPIEncodePicture *pic)417 VAAPIEncodePicture *pic)
261{418{
262 VAAPIEncodeContext *ctx = avctx->priv_data;419 VAAPIEncodeContext *ctx = avctx->priv_data;
263 VAEncPictureParameterBufferMPEG2 *vpic = pic->codec_picture_params;
264 VAAPIEncodeMPEG2Context *priv = ctx->priv_data;420 VAAPIEncodeMPEG2Context *priv = ctx->priv_data;
265 int fch, fcv;421 MPEG2RawPictureHeader *ph = &priv->picture_header;
422 MPEG2RawPictureCodingExtension *pce = &priv->picture_coding_extension.data.picture_coding;
423 VAEncPictureParameterBufferMPEG2 *vpic = pic->codec_picture_params;
266 424
267 switch (avctx->level) {425 if (pic->type == PICTURE_TYPE_IDR || pic->type == PICTURE_TYPE_I) {
268 case 4: // High.426 ph->temporal_reference = 0;
269 case 6: // High 1440.427 ph->picture_coding_type = 1;
270 fch = 9;428 priv->last_i_frame = pic->display_order;
271 fcv = 5;429 } else {
272 break;430 ph->temporal_reference = pic->display_order - priv->last_i_frame;
273 case 8: // Main.431 ph->picture_coding_type = pic->type == PICTURE_TYPE_B ? 3 : 2;
274 fch = 8;432 }
275 fcv = 5;433
276 break;434 if (pic->type == PICTURE_TYPE_P || pic->type == PICTURE_TYPE_B) {
277 case 10: // Low.435 pce->f_code[0][0] = priv->f_code_horizontal;
278 default:436 pce->f_code[0][1] = priv->f_code_vertical;
279 fch = 7;437 } else {
280 fcv = 4;438 pce->f_code[0][0] = 15;
281 break;439 pce->f_code[0][1] = 15;
440 }
441 if (pic->type == PICTURE_TYPE_B) {
442 pce->f_code[1][0] = priv->f_code_horizontal;
443 pce->f_code[1][1] = priv->f_code_vertical;
444 } else {
445 pce->f_code[1][0] = 15;
446 pce->f_code[1][1] = 15;
282 }447 }
283 448
449 vpic->reconstructed_picture = pic->recon_surface;
450 vpic->coded_buf = pic->output_buffer;
451
284 switch (pic->type) {452 switch (pic->type) {
285 case PICTURE_TYPE_IDR:453 case PICTURE_TYPE_IDR:
286 case PICTURE_TYPE_I:454 case PICTURE_TYPE_I:
287 vpic->picture_type = VAEncPictureTypeIntra;455 vpic->picture_type = VAEncPictureTypeIntra;
288 priv->last_i_frame = pic->display_order;
289 break;456 break;
290 case PICTURE_TYPE_P:457 case PICTURE_TYPE_P:
291 vpic->picture_type = VAEncPictureTypePredictive;458 vpic->picture_type = VAEncPictureTypePredictive;
292 vpic->forward_reference_picture = pic->refs[0]->recon_surface;459 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;460 break;
296 case PICTURE_TYPE_B:461 case PICTURE_TYPE_B:
297 vpic->picture_type = VAEncPictureTypeBidirectional;462 vpic->picture_type = VAEncPictureTypeBidirectional;
298 vpic->forward_reference_picture = pic->refs[0]->recon_surface;463 vpic->forward_reference_picture = pic->refs[0]->recon_surface;
299 vpic->backward_reference_picture = pic->refs[1]->recon_surface;464 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;465 break;
305 default:466 default:
306 av_assert0(0 && "invalid picture type");467 av_assert0(0 && "invalid picture type");
307 }468 }
308 469
309 vpic->reconstructed_picture = pic->recon_surface;470 vpic->temporal_reference = ph->temporal_reference;
310 vpic->coded_buf = pic->output_buffer;471 vpic->f_code[0][0] = pce->f_code[0][0];
311 472 vpic->f_code[0][1] = pce->f_code[0][1];
312 vpic->temporal_reference = pic->display_order - priv->last_i_frame;473 vpic->f_code[1][0] = pce->f_code[1][0];
474 vpic->f_code[1][1] = pce->f_code[1][1];
313 475
314 pic->nb_slices = priv->mb_height;476 pic->nb_slices = priv->mb_height;
315 477
@@ -354,6 +516,11 @@ static av_cold int vaapi_encode_mpeg2_configure(AVCodecContext *avctx) · 38 unmodified lines
354{516{
355 VAAPIEncodeContext *ctx = avctx->priv_data;517 VAAPIEncodeContext *ctx = avctx->priv_data;
356 VAAPIEncodeMPEG2Context *priv = ctx->priv_data;518 VAAPIEncodeMPEG2Context *priv = ctx->priv_data;
519 int err;
520
521 err = ff_cbs_init(&priv->cbc, AV_CODEC_ID_MPEG2VIDEO, avctx);
522 if (err < 0)
523 return err;
357 524
358 priv->mb_width = FFALIGN(avctx->width, 16) / 16;525 priv->mb_width = FFALIGN(avctx->width, 16) / 16;
359 priv->mb_height = FFALIGN(avctx->height, 16) / 16;526 priv->mb_height = FFALIGN(avctx->height, 16) / 16;
@@ -420,11 +587,41 @@ static av_cold int vaapi_encode_mpeg2_init(AVCodecContext *avctx) · 60 unmodified lines
420 case FF_PROFILE_MPEG2_MAIN:587 case FF_PROFILE_MPEG2_MAIN:
421 ctx->va_profile = VAProfileMPEG2Main;588 ctx->va_profile = VAProfileMPEG2Main;
422 break;589 break;
590 case FF_PROFILE_MPEG2_422:
591 av_log(avctx, AV_LOG_ERROR, "MPEG-2 4:2:2 profile "
592 "is not supported.\n");
593 return AVERROR_PATCHWELCOME;
594 case FF_PROFILE_MPEG2_HIGH:
595 av_log(avctx, AV_LOG_ERROR, "MPEG-2 high profile "
596 "is not supported.\n");
597 return AVERROR_PATCHWELCOME;
598 case FF_PROFILE_MPEG2_SS:
599 case FF_PROFILE_MPEG2_SNR_SCALABLE:
600 av_log(avctx, AV_LOG_ERROR, "MPEG-2 scalable profiles "
601 "are not supported.\n");
602 return AVERROR_PATCHWELCOME;
423 default:603 default:
424 av_log(avctx, AV_LOG_ERROR, "Unknown MPEG-2 profile %d.\n",604 av_log(avctx, AV_LOG_ERROR, "Unknown MPEG-2 profile %d.\n",
425 avctx->profile);605 avctx->profile);
426 return AVERROR(EINVAL);606 return AVERROR(EINVAL);
427 }607 }
608 switch (avctx->level) {
609 case 4: // High
610 case 6: // High 1440
611 case 8: // Main
612 case 10: // Low
613 break;
614 default:
615 av_log(avctx, AV_LOG_ERROR, "Unknown MPEG-2 level %d.\n",
616 avctx->level);
617 return AVERROR(EINVAL);
618 }
619
620 if (avctx->height % 4096 == 0 || avctx->width % 4096 == 0) {
621 av_log(avctx, AV_LOG_ERROR, "MPEG-2 does not support picture "
622 "height or width divisible by 4096.\n");
623 return AVERROR(EINVAL);
624 }
428 625
429 ctx->va_entrypoint = VAEntrypointEncSlice;626 ctx->va_entrypoint = VAEntrypointEncSlice;
430 ctx->va_rt_format = VA_RT_FORMAT_YUV420;627 ctx->va_rt_format = VA_RT_FORMAT_YUV420;
@@ -439,6 +636,17 @@ static av_cold int vaapi_encode_mpeg2_init(AVCodecContext *avctx) · 8 unmodified lines
439 return ff_vaapi_encode_init(avctx);636 return ff_vaapi_encode_init(avctx);
440}637}
441 638
639static av_cold int vaapi_encode_mpeg2_close(AVCodecContext *avctx)
640{
641 VAAPIEncodeContext *ctx = avctx->priv_data;
642 VAAPIEncodeMPEG2Context *priv = ctx->priv_data;
643
644 if (priv)
645 ff_cbs_close(&priv->cbc);
646
647 return ff_vaapi_encode_close(avctx);
648}
649
442static const AVCodecDefault vaapi_encode_mpeg2_defaults[] = {650static const AVCodecDefault vaapi_encode_mpeg2_defaults[] = {
443 { "profile", "4" },651 { "profile", "4" },
444 { "level", "4" },652 { "level", "4" },
@@ -460,7 +668,7 @@ AVCodec ff_mpeg2_vaapi_encoder = { · 15 unmodified lines
460 .priv_data_size = sizeof(VAAPIEncodeContext),668 .priv_data_size = sizeof(VAAPIEncodeContext),
461 .init = &vaapi_encode_mpeg2_init,669 .init = &vaapi_encode_mpeg2_init,
462 .encode2 = &ff_vaapi_encode2,670 .encode2 = &ff_vaapi_encode2,
463 .close = &ff_vaapi_encode_close,671 .close = &vaapi_encode_mpeg2_close,
464 .capabilities = AV_CODEC_CAP_DELAY,672 .capabilities = AV_CODEC_CAP_DELAY,
465 .defaults = vaapi_encode_mpeg2_defaults,673 .defaults = vaapi_encode_mpeg2_defaults,
466 .pix_fmts = (const enum AVPixelFormat[]) {674 .pix_fmts = (const enum AVPixelFormat[]) {

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t