Showing the changes to libavcodec/vaapi_encode_mpeg2.c (1 of 2 files). Show all
Unified · Split
| @@ -20,15 +20,11 @@ · 19 unmodified lines | ||
| 20 | 20 | #include <va/va_enc_mpeg2.h> |
| 21 | 21 | |
| 22 | 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 | 24 | #include "avcodec.h" |
| 29 | −#include "internal.h" | |
| 30 | −#include "mpegvideo.h" | |
| 31 | −#include "put_bits.h" | |
| 25 | +#include "cbs.h" | |
| 26 | +#include "cbs_mpeg2.h" | |
| 27 | +#include "mpeg12.h" | |
| 32 | 28 | #include "vaapi_encode.h" |
| 33 | 29 | |
| 34 | 30 | typedef struct VAAPIEncodeMPEG2Context { |
| @@ -39,79 +35,104 @@ typedef struct VAAPIEncodeMPEG2Context { · 4 unmodified lines | ||
| 39 | 35 | int quant_p; |
| 40 | 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 | 45 | int64_t last_i_frame; |
| 43 | 46 | |
| 44 | 47 | unsigned int bit_rate; |
| 45 | 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 | 57 | } VAAPIEncodeMPEG2Context; |
| 47 | 58 | |
| 48 | 59 | |
| 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 | |
| 60 | +static int vaapi_encode_mpeg2_write_fragment(AVCodecContext *avctx, | |
| 61 | + char *data, size_t *data_len, | |
| 62 | + CodedBitstreamFragment *frag) | |
| 63 | +{ | |
| 64 | + VAAPIEncodeContext *ctx = avctx->priv_data; | |
| 65 | + 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 | + | |
| 87 | +static 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) | |
| 57 | −#define u(width, ...) u2(width, __VA_ARGS__) | |
| 102 | + return 0; | |
| 103 | +} | |
| 58 | 104 | |
| 59 | 105 | static int vaapi_encode_mpeg2_write_sequence_header(AVCodecContext *avctx, |
| 60 | 106 | char *data, size_t *data_len) |
| 61 | 107 | { |
| 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 | − | |
| 108 | + VAAPIEncodeContext *ctx = avctx->priv_data; | |
| 109 | + VAAPIEncodeMPEG2Context *priv = ctx->priv_data; | |
| 110 | + CodedBitstreamFragment *frag = &priv->current_fragment; | |
| 111 | + int err; | |
| 112 | + | |
| 113 | + err = vaapi_encode_mpeg2_add_header(avctx, frag, MPEG2_START_SEQUENCE_HEADER, | |
| 114 | + &priv->sequence_header); | |
| 115 | + if (err < 0) | |
| 116 | + goto fail; | |
| 117 | + | |
| 118 | + err = vaapi_encode_mpeg2_add_header(avctx, frag, MPEG2_START_EXTENSION, | |
| 119 | + &priv->sequence_extension); | |
| 120 | + if (err < 0) | |
| 121 | + goto fail; | |
| 122 | + | |
| 123 | + err = vaapi_encode_mpeg2_add_header(avctx, frag, MPEG2_START_EXTENSION, | |
| 124 | + &priv->sequence_display_extension); | |
| 125 | + if (err < 0) | |
| 126 | + goto fail; | |
| 127 | + | |
| 128 | + err = vaapi_encode_mpeg2_add_header(avctx, frag, MPEG2_START_GROUP, | |
| 129 | + &priv->gop_header); | |
| 130 | + if (err < 0) | |
| 131 | + goto fail; | |
| 132 | + | |
| 133 | + err = vaapi_encode_mpeg2_write_fragment(avctx, data, data_len, frag); | |
| 134 | +fail: | |
| 135 | + ff_cbs_fragment_uninit(&priv->cbc, frag); | |
| 115 | 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 | 140 | VAAPIEncodePicture *pic, |
| 120 | 141 | char *data, size_t *data_len) |
| 121 | 142 | { |
| 122 | − VAEncPictureParameterBufferMPEG2 *vpic = pic->codec_picture_params; | |
| 123 | − int picture_coding_type; | |
| 124 | − PutBitContext pbc; | |
| 143 | + VAAPIEncodeContext *ctx = avctx->priv_data; | |
| 144 | + VAAPIEncodeMPEG2Context *priv = ctx->priv_data; | |
| 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); | |
| 159 | +fail: | |
| 160 | + ff_cbs_fragment_uninit(&priv->cbc, frag); | |
| 161 | + return 0; | |
| 162 | +} | |
| 125 | 163 | |
| 126 | − init_put_bits(&pbc, data, 8 * *data_len); | |
| 164 | +static 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); | |
| 129 | − u(10, vpic_var(temporal_reference)); | |
| 178 | + memset(sh, 0, sizeof(*sh)); | |
| 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) { | |
| 132 | − case VAEncPictureTypeIntra: | |
| 133 | − picture_coding_type = AV_PICTURE_TYPE_I; | |
| 134 | − break; | |
| 135 | − case VAEncPictureTypePredictive: | |
| 136 | − picture_coding_type = AV_PICTURE_TYPE_P; | |
| 185 | + | |
| 186 | + if (avctx->bit_rate > 0) { | |
| 187 | + priv->bit_rate = (avctx->bit_rate + 399) / 400; | |
| 188 | + } else { | |
| 189 | + // Unknown (not a bitrate-targetting mode), so just use the | |
| 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 | 205 | break; |
| 138 | − case VAEncPictureTypeBidirectional: | |
| 139 | − picture_coding_type = AV_PICTURE_TYPE_B; | |
| 206 | + case 8: // Main. | |
| 207 | + priv->f_code_horizontal = 8; | |
| 208 | + priv->f_code_vertical = 5; | |
| 140 | 209 | break; |
| 210 | + case 10: // Low. | |
| 141 | 211 | 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); | |
| 212 | + priv->f_code_horizontal = 7; | |
| 213 | + priv->f_code_vertical = 4; | |
| 214 | + break; | |
| 153 | 215 | } |
| 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)); | |
| 216 | + | |
| 217 | + | |
| 218 | + // Sequence header | |
| 219 | + | |
| 220 | + sh->sequence_header_code = MPEG2_START_SEQUENCE_HEADER; | |
| 221 | + | |
| 222 | + sh->horizontal_size_value = avctx->width & 0xfff; | |
| 223 | + sh->vertical_size_value = avctx->height & 0xfff; | |
| 224 | + | |
| 225 | + if (avctx->sample_aspect_ratio.num != 0 && | |
| 226 | + avctx->sample_aspect_ratio.den != 0) { | |
| 227 | + AVRational dar = av_div_q(avctx->sample_aspect_ratio, | |
| 228 | + (AVRational) { avctx->width, avctx->height }); | |
| 229 | + | |
| 230 | + if (av_cmp_q(avctx->sample_aspect_ratio, (AVRational) { 1, 1 }) == 0) { | |
| 231 | + sh->aspect_ratio_information = 1; | |
| 232 | + } else if (av_cmp_q(dar, (AVRational) { 3, 4 }) == 0) { | |
| 233 | + sh->aspect_ratio_information = 2; | |
| 234 | + } else if (av_cmp_q(dar, (AVRational) { 9, 16 }) == 0) { | |
| 235 | + sh->aspect_ratio_information = 3; | |
| 236 | + } else if (av_cmp_q(dar, (AVRational) { 100, 221 }) == 0) { | |
| 237 | + sh->aspect_ratio_information = 4; | |
| 238 | + } else { | |
| 239 | + av_log(avctx, AV_LOG_WARNING, "Sample aspect ratio %d:%d is not " | |
| 240 | + "representable, signalling square pixels instead.\n", | |
| 241 | + avctx->sample_aspect_ratio.num, | |
| 242 | + avctx->sample_aspect_ratio.den); | |
| 243 | + sh->aspect_ratio_information = 1; | |
| 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) | |
| 186 | − u(1, 0, zero_bit); | |
| 250 | + if (avctx->framerate.num > 0 && avctx->framerate.den > 0) | |
| 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); | |
| 189 | − flush_put_bits(&pbc); | |
| 258 | + sh->bit_rate_value = priv->bit_rate & 0x3ffff; | |
| 259 | + sh->vbv_buffer_size_value = priv->vbv_buffer_size & 0x3ff; | |
| 190 | 260 | |
| 191 | − return 0; | |
| 192 | −} | |
| 261 | + sh->constrained_parameters_flag = 0; | |
| 262 | + sh->load_intra_quantiser_matrix = 0; | |
| 263 | + sh->load_non_intra_quantiser_matrix = 0; | |
| 193 | 264 | |
| 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 | 265 | |
| 201 | − vseq->intra_period = avctx->gop_size; | |
| 202 | − vseq->ip_period = ctx->b_per_p + 1; | |
| 266 | + // Sequence extension | |
| 203 | 267 | |
| 204 | − vseq->picture_width = avctx->width; | |
| 205 | − vseq->picture_height = avctx->height; | |
| 268 | + priv->sequence_extension.extension_start_code = MPEG2_START_EXTENSION; | |
| 269 | + priv->sequence_extension.extension_start_code_identifier = | |
| 270 | + MPEG2_EXTENSION_SEQUENCE; | |
| 206 | 271 | |
| 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); | |
| 272 | + se->profile_and_level_indication = avctx->profile << 4 | avctx->level; | |
| 273 | + se->progressive_sequence = 1; | |
| 274 | + se->chroma_format = 1; | |
| 275 | + | |
| 276 | + se->horizontal_size_extension = avctx->width >> 12; | |
| 277 | + se->vertical_size_extension = avctx->height >> 12; | |
| 278 | + | |
| 279 | + se->bit_rate_extension = priv->bit_rate >> 18; | |
| 280 | + se->vbv_buffer_size_extension = priv->vbv_buffer_size >> 10; | |
| 281 | + se->low_delay = ctx->b_per_p == 0; | |
| 282 | + | |
| 283 | + se->frame_rate_extension_n = ext_n; | |
| 284 | + se->frame_rate_extension_d = ext_d; | |
| 285 | + | |
| 286 | + | |
| 287 | + // Sequence display extension | |
| 288 | + | |
| 289 | + priv->sequence_display_extension.extension_start_code = | |
| 290 | + MPEG2_START_EXTENSION; | |
| 291 | + priv->sequence_display_extension.extension_start_code_identifier = | |
| 292 | + MPEG2_EXTENSION_SEQUENCE_DISPLAY; | |
| 293 | + | |
| 294 | + sde->video_format = 5; | |
| 295 | + if (avctx->color_primaries != AVCOL_PRI_UNSPECIFIED || | |
| 296 | + avctx->color_trc != AVCOL_TRC_UNSPECIFIED || | |
| 297 | + avctx->colorspace != AVCOL_SPC_UNSPECIFIED) { | |
| 298 | + sde->colour_description = 1; | |
| 299 | + sde->colour_primaries = avctx->color_primaries; | |
| 300 | + sde->transfer_characteristics = avctx->color_trc; | |
| 301 | + sde->matrix_coefficients = avctx->colorspace; | |
| 302 | + } else { | |
| 303 | + sde->colour_description = 0; | |
| 304 | + } | |
| 305 | + | |
| 306 | + sde->display_horizontal_size = avctx->width; | |
| 307 | + sde->display_vertical_size = avctx->height; | |
| 308 | + | |
| 309 | + | |
| 310 | + // GOP header | |
| 311 | + | |
| 312 | + goph->group_start_code = MPEG2_START_GROUP; | |
| 313 | + | |
| 314 | + goph->time_code = 0; | |
| 315 | + goph->closed_gop = 1; | |
| 316 | + goph->broken_link = 0; | |
| 317 | + | |
| 318 | + | |
| 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 | 413 | return 0; |
| 257 | 414 | } |
| @@ -260,56 +417,61 @@ static int vaapi_encode_mpeg2_init_picture_params(AVCodecContext *avctx, · 2 unmodified lines | ||
| 260 | 417 | VAAPIEncodePicture *pic) |
| 261 | 418 | { |
| 262 | 419 | VAAPIEncodeContext *ctx = avctx->priv_data; |
| 263 | − VAEncPictureParameterBufferMPEG2 *vpic = pic->codec_picture_params; | |
| 264 | 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) { | |
| 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; | |
| 425 | + if (pic->type == PICTURE_TYPE_IDR || pic->type == PICTURE_TYPE_I) { | |
| 426 | + ph->temporal_reference = 0; | |
| 427 | + ph->picture_coding_type = 1; | |
| 428 | + priv->last_i_frame = pic->display_order; | |
| 429 | + } else { | |
| 430 | + ph->temporal_reference = pic->display_order - priv->last_i_frame; | |
| 431 | + ph->picture_coding_type = pic->type == PICTURE_TYPE_B ? 3 : 2; | |
| 432 | + } | |
| 433 | + | |
| 434 | + if (pic->type == PICTURE_TYPE_P || pic->type == PICTURE_TYPE_B) { | |
| 435 | + pce->f_code[0][0] = priv->f_code_horizontal; | |
| 436 | + pce->f_code[0][1] = priv->f_code_vertical; | |
| 437 | + } else { | |
| 438 | + pce->f_code[0][0] = 15; | |
| 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 | 452 | switch (pic->type) { |
| 285 | 453 | case PICTURE_TYPE_IDR: |
| 286 | 454 | case PICTURE_TYPE_I: |
| 287 | 455 | vpic->picture_type = VAEncPictureTypeIntra; |
| 288 | − priv->last_i_frame = pic->display_order; | |
| 289 | 456 | break; |
| 290 | 457 | case PICTURE_TYPE_P: |
| 291 | 458 | vpic->picture_type = VAEncPictureTypePredictive; |
| 292 | 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 | 460 | break; |
| 296 | 461 | case PICTURE_TYPE_B: |
| 297 | 462 | vpic->picture_type = VAEncPictureTypeBidirectional; |
| 298 | 463 | vpic->forward_reference_picture = pic->refs[0]->recon_surface; |
| 299 | 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 | 465 | break; |
| 305 | 466 | default: |
| 306 | 467 | av_assert0(0 && "invalid picture type"); |
| 307 | 468 | } |
| 308 | 469 | |
| 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; | |
| 470 | + vpic->temporal_reference = ph->temporal_reference; | |
| 471 | + vpic->f_code[0][0] = pce->f_code[0][0]; | |
| 472 | + vpic->f_code[0][1] = pce->f_code[0][1]; | |
| 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 | 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 | 517 | VAAPIEncodeContext *ctx = avctx->priv_data; |
| 356 | 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 | 525 | priv->mb_width = FFALIGN(avctx->width, 16) / 16; |
| 359 | 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 | 587 | case FF_PROFILE_MPEG2_MAIN: |
| 421 | 588 | ctx->va_profile = VAProfileMPEG2Main; |
| 422 | 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 | 603 | default: |
| 424 | 604 | av_log(avctx, AV_LOG_ERROR, "Unknown MPEG-2 profile %d.\n", |
| 425 | 605 | avctx->profile); |
| 426 | 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 | 626 | ctx->va_entrypoint = VAEntrypointEncSlice; |
| 430 | 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 | 636 | return ff_vaapi_encode_init(avctx); |
| 440 | 637 | } |
| 441 | 638 | |
| 639 | +static 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 | + | |
| 442 | 650 | static const AVCodecDefault vaapi_encode_mpeg2_defaults[] = { |
| 443 | 651 | { "profile", "4" }, |
| 444 | 652 | { "level", "4" }, |
| @@ -460,7 +668,7 @@ AVCodec ff_mpeg2_vaapi_encoder = { · 15 unmodified lines | ||
| 460 | 668 | .priv_data_size = sizeof(VAAPIEncodeContext), |
| 461 | 669 | .init = &vaapi_encode_mpeg2_init, |
| 462 | 670 | .encode2 = &ff_vaapi_encode2, |
| 463 | − .close = &ff_vaapi_encode_close, | |
| 671 | + .close = &vaapi_encode_mpeg2_close, | |
| 464 | 672 | .capabilities = AV_CODEC_CAP_DELAY, |
| 465 | 673 | .defaults = vaapi_encode_mpeg2_defaults, |
| 466 | 674 | .pix_fmts = (const enum AVPixelFormat[]) { |