FFmpeg
vaapi_mpeg2.c
Go to the documentation of this file.
1 /*
2  * MPEG-2 HW decode acceleration through VA API
3  *
4  * Copyright (C) 2008-2009 Splitted-Desktop Systems
5  *
6  * This file is part of FFmpeg.
7  *
8  * FFmpeg is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU Lesser General Public
10  * License as published by the Free Software Foundation; either
11  * version 2.1 of the License, or (at your option) any later version.
12  *
13  * FFmpeg 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 FFmpeg; if not, write to the Free Software
20  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21  */
22 
23 #include "hwaccel_internal.h"
24 #include "libavutil/attributes.h"
25 #include "mpegutils.h"
26 #include "mpegvideo.h"
27 #include "mpegvideodec.h"
28 #include "vaapi_decode.h"
29 
30 /** Reconstruct bitstream f_code */
31 static inline int mpeg2_get_f_code(const MpegEncContext *s)
32 {
33  return (s->mpeg_f_code[0][0] << 12) | (s->mpeg_f_code[0][1] << 8) |
34  (s->mpeg_f_code[1][0] << 4) | s->mpeg_f_code[1][1];
35 }
36 
37 /** Determine frame start: first field for field picture or frame picture */
38 static inline int mpeg2_get_is_frame_start(const MpegEncContext *s)
39 {
40  return s->first_field || s->picture_structure == PICT_FRAME;
41 }
42 
44  av_unused const AVBufferRef *buffer_ref,
45  av_unused const uint8_t *buffer,
46  av_unused uint32_t size)
47 {
48  const MpegEncContext *s = avctx->priv_data;
49  VAAPIDecodePicture *pic = s->cur_pic.ptr->hwaccel_picture_private;
50  VAPictureParameterBufferMPEG2 pic_param;
51  VAIQMatrixBufferMPEG2 iq_matrix;
52  int i, err;
53 
54  pic->output_surface = ff_vaapi_get_surface_id(s->cur_pic.ptr->f);
55 
56  pic_param = (VAPictureParameterBufferMPEG2) {
57  .horizontal_size = s->width,
58  .vertical_size = s->height,
59  .forward_reference_picture = VA_INVALID_ID,
60  .backward_reference_picture = VA_INVALID_ID,
61  .picture_coding_type = s->pict_type,
62  .f_code = mpeg2_get_f_code(s),
63  .picture_coding_extension.bits = {
64  .intra_dc_precision = s->intra_dc_precision,
65  .picture_structure = s->picture_structure,
66  .top_field_first = s->top_field_first,
67  .frame_pred_frame_dct = s->frame_pred_frame_dct,
68  .concealment_motion_vectors = s->concealment_motion_vectors,
69  .q_scale_type = s->q_scale_type,
70  .intra_vlc_format = s->intra_vlc_format,
71  .alternate_scan = s->alternate_scan,
72  .repeat_first_field = s->repeat_first_field,
73  .progressive_frame = s->progressive_frame,
74  .is_first_field = mpeg2_get_is_frame_start(s),
75  },
76  };
77 
78  switch (s->pict_type) {
79  case AV_PICTURE_TYPE_B:
80  pic_param.backward_reference_picture = ff_vaapi_get_surface_id(s->next_pic.ptr->f);
82  case AV_PICTURE_TYPE_P:
83  pic_param.forward_reference_picture = ff_vaapi_get_surface_id(s->last_pic.ptr->f);
84  break;
85  }
86 
87  err = ff_vaapi_decode_make_param_buffer(avctx, pic,
88  VAPictureParameterBufferType,
89  &pic_param, sizeof(pic_param));
90  if (err < 0)
91  goto fail;
92 
93  iq_matrix.load_intra_quantiser_matrix = 1;
94  iq_matrix.load_non_intra_quantiser_matrix = 1;
95  iq_matrix.load_chroma_intra_quantiser_matrix = 1;
96  iq_matrix.load_chroma_non_intra_quantiser_matrix = 1;
97 
98  for (i = 0; i < 64; i++) {
99  int n = s->idsp.idct_permutation[ff_zigzag_direct[i]];
100  iq_matrix.intra_quantiser_matrix[i] = s->intra_matrix[n];
101  iq_matrix.non_intra_quantiser_matrix[i] = s->inter_matrix[n];
102  iq_matrix.chroma_intra_quantiser_matrix[i] = s->chroma_intra_matrix[n];
103  iq_matrix.chroma_non_intra_quantiser_matrix[i] = s->chroma_inter_matrix[n];
104  }
105 
106  err = ff_vaapi_decode_make_param_buffer(avctx, pic,
107  VAIQMatrixBufferType,
108  &iq_matrix, sizeof(iq_matrix));
109  if (err < 0)
110  goto fail;
111 
112  return 0;
113 
114 fail:
115  ff_vaapi_decode_cancel(avctx, pic);
116  return err;
117 }
118 
120 {
121  MpegEncContext *s = avctx->priv_data;
122  VAAPIDecodePicture *pic = s->cur_pic.ptr->hwaccel_picture_private;
123  int ret;
124 
125  ret = ff_vaapi_decode_issue(avctx, pic);
126  if (ret < 0)
127  goto fail;
128 
129  ff_mpeg_draw_horiz_band(s, 0, s->avctx->height);
130 
131 fail:
132  return ret;
133 }
134 
135 static int vaapi_mpeg2_decode_slice(AVCodecContext *avctx, const uint8_t *buffer, uint32_t size)
136 {
137  const MpegEncContext *s = avctx->priv_data;
138  VAAPIDecodePicture *pic = s->cur_pic.ptr->hwaccel_picture_private;
139  VASliceParameterBufferMPEG2 slice_param;
140  GetBitContext gb;
141  uint32_t quantiser_scale_code, intra_slice_flag, macroblock_offset;
142  int err;
143 
144  /* Determine macroblock_offset */
145  init_get_bits(&gb, buffer, 8 * size);
146  if (get_bits_long(&gb, 32) >> 8 != 1) /* start code */
147  return AVERROR_INVALIDDATA;
148  quantiser_scale_code = get_bits(&gb, 5);
149  intra_slice_flag = get_bits1(&gb);
150  if (intra_slice_flag) {
151  skip_bits(&gb, 8);
152  if (skip_1stop_8data_bits(&gb) < 0)
153  return AVERROR_INVALIDDATA;
154  }
155  macroblock_offset = get_bits_count(&gb);
156 
157  slice_param = (VASliceParameterBufferMPEG2) {
158  .slice_data_size = size,
159  .slice_data_offset = 0,
160  .slice_data_flag = VA_SLICE_DATA_FLAG_ALL,
161  .macroblock_offset = macroblock_offset,
162  .slice_horizontal_position = s->mb_x,
163  .slice_vertical_position = s->mb_y >> (s->picture_structure != PICT_FRAME),
164  .quantiser_scale_code = quantiser_scale_code,
165  .intra_slice_flag = intra_slice_flag,
166  };
167 
168  err = ff_vaapi_decode_make_slice_buffer(avctx, pic,
169  &slice_param, 1, sizeof(slice_param),
170  buffer, size);
171  if (err < 0) {
172  ff_vaapi_decode_cancel(avctx, pic);
173  return err;
174  }
175 
176  return 0;
177 }
178 
180  .p.name = "mpeg2_vaapi",
181  .p.type = AVMEDIA_TYPE_VIDEO,
182  .p.id = AV_CODEC_ID_MPEG2VIDEO,
183  .p.pix_fmt = AV_PIX_FMT_VAAPI,
184  .start_frame = &vaapi_mpeg2_start_frame,
185  .end_frame = &vaapi_mpeg2_end_frame,
186  .decode_slice = &vaapi_mpeg2_decode_slice,
187  .frame_priv_data_size = sizeof(VAAPIDecodePicture),
190  .frame_params = &ff_vaapi_common_frame_params,
191  .priv_data_size = sizeof(VAAPIDecodeContext),
192  .caps_internal = HWACCEL_CAP_ASYNC_SAFE,
193 };
PICT_FRAME
#define PICT_FRAME
Definition: mpegutils.h:33
ff_vaapi_get_surface_id
static VASurfaceID ff_vaapi_get_surface_id(AVFrame *pic)
Definition: vaapi_decode.h:30
VAAPIDecodeContext
Definition: vaapi_decode.h:47
vaapi_decode.h
get_bits_long
static unsigned int get_bits_long(GetBitContext *s, int n)
Read 0-32 bits.
Definition: get_bits.h:424
get_bits_count
static int get_bits_count(const GetBitContext *s)
Definition: get_bits.h:254
av_unused
#define av_unused
Definition: attributes.h:164
FFHWAccel::p
AVHWAccel p
The public AVHWAccel.
Definition: hwaccel_internal.h:38
VAAPIDecodePicture
Definition: vaapi_decode.h:35
mpegvideo.h
mpegutils.h
init_get_bits
static int init_get_bits(GetBitContext *s, const uint8_t *buffer, int bit_size)
Initialize GetBitContext.
Definition: get_bits.h:517
skip_bits
static void skip_bits(GetBitContext *s, int n)
Definition: get_bits.h:383
get_bits
static unsigned int get_bits(GetBitContext *s, int n)
Read 1-25 bits.
Definition: get_bits.h:337
ff_vaapi_decode_make_param_buffer
int ff_vaapi_decode_make_param_buffer(AVCodecContext *avctx, VAAPIDecodePicture *pic, int type, const void *data, size_t size)
Definition: vaapi_decode.c:34
FFHWAccel
Definition: hwaccel_internal.h:34
fail
#define fail()
Definition: checkasm.h:224
GetBitContext
Definition: get_bits.h:109
ff_mpeg2_vaapi_hwaccel
const FFHWAccel ff_mpeg2_vaapi_hwaccel
Definition: vaapi_mpeg2.c:179
VAAPIDecodePicture::output_surface
VASurfaceID output_surface
Definition: vaapi_decode.h:36
mpegvideodec.h
vaapi_mpeg2_start_frame
static int vaapi_mpeg2_start_frame(AVCodecContext *avctx, av_unused const AVBufferRef *buffer_ref, av_unused const uint8_t *buffer, av_unused uint32_t size)
Definition: vaapi_mpeg2.c:43
s
#define s(width, name)
Definition: cbs_vp9.c:198
ff_vaapi_decode_init
int ff_vaapi_decode_init(AVCodecContext *avctx)
Definition: vaapi_decode.c:692
ff_vaapi_common_frame_params
int ff_vaapi_common_frame_params(AVCodecContext *avctx, AVBufferRef *hw_frames_ctx)
Definition: vaapi_decode.c:668
ff_vaapi_decode_uninit
int ff_vaapi_decode_uninit(AVCodecContext *avctx)
Definition: vaapi_decode.c:738
av_fallthrough
#define av_fallthrough
Definition: attributes.h:67
ff_vaapi_decode_issue
int ff_vaapi_decode_issue(AVCodecContext *avctx, VAAPIDecodePicture *pic)
Definition: vaapi_decode.c:166
HWACCEL_CAP_ASYNC_SAFE
#define HWACCEL_CAP_ASYNC_SAFE
Header providing the internals of AVHWAccel.
Definition: hwaccel_internal.h:31
hwaccel_internal.h
get_bits1
static unsigned int get_bits1(GetBitContext *s)
Definition: get_bits.h:391
mpeg2_get_is_frame_start
static int mpeg2_get_is_frame_start(const MpegEncContext *s)
Determine frame start: first field for field picture or frame picture.
Definition: vaapi_mpeg2.c:38
init
int(* init)(AVBSFContext *ctx)
Definition: dts2pts.c:551
i
#define i(width, name, range_min, range_max)
Definition: cbs_h264.c:63
size
int size
Definition: twinvq_data.h:10344
ff_mpeg_draw_horiz_band
void ff_mpeg_draw_horiz_band(MpegEncContext *s, int y, int h)
Definition: mpegvideo_dec.c:450
ff_vaapi_decode_cancel
int ff_vaapi_decode_cancel(AVCodecContext *avctx, VAAPIDecodePicture *pic)
Definition: vaapi_decode.c:247
attributes.h
AV_PIX_FMT_VAAPI
@ AV_PIX_FMT_VAAPI
Hardware acceleration through VA-API, data[3] contains a VASurfaceID.
Definition: pixfmt.h:126
vaapi_mpeg2_decode_slice
static int vaapi_mpeg2_decode_slice(AVCodecContext *avctx, const uint8_t *buffer, uint32_t size)
Definition: vaapi_mpeg2.c:135
AVHWAccel::name
const char * name
Name of the hardware accelerated codec.
Definition: avcodec.h:1961
uninit
static void uninit(AVBSFContext *ctx)
Definition: pcm_rechunk.c:68
ff_zigzag_direct
const uint8_t ff_zigzag_direct[64]
Definition: mathtables.c:137
ret
ret
Definition: filter_design.txt:187
skip_1stop_8data_bits
static int skip_1stop_8data_bits(GetBitContext *gb)
Definition: get_bits.h:693
AVCodecContext
main external API structure.
Definition: avcodec.h:439
AV_PICTURE_TYPE_B
@ AV_PICTURE_TYPE_B
Bi-dir predicted.
Definition: avutil.h:280
buffer
the frame and frame reference mechanism is intended to as much as expensive copies of that data while still allowing the filters to produce correct results The data is stored in buffers represented by AVFrame structures Several references can point to the same frame buffer
Definition: filter_design.txt:49
ff_vaapi_decode_make_slice_buffer
int ff_vaapi_decode_make_slice_buffer(AVCodecContext *avctx, VAAPIDecodePicture *pic, const void *params_data, int nb_params, size_t params_size, const void *slice_data, size_t slice_size)
Definition: vaapi_decode.c:75
vaapi_mpeg2_end_frame
static int vaapi_mpeg2_end_frame(AVCodecContext *avctx)
Definition: vaapi_mpeg2.c:119
AV_PICTURE_TYPE_P
@ AV_PICTURE_TYPE_P
Predicted.
Definition: avutil.h:279
AVMEDIA_TYPE_VIDEO
@ AVMEDIA_TYPE_VIDEO
Definition: avutil.h:200
AVBufferRef
A reference to a data buffer.
Definition: buffer.h:82
AVCodecContext::priv_data
void * priv_data
Definition: avcodec.h:466
AVERROR_INVALIDDATA
#define AVERROR_INVALIDDATA
Invalid data found when processing input.
Definition: error.h:61
AV_CODEC_ID_MPEG2VIDEO
@ AV_CODEC_ID_MPEG2VIDEO
preferred ID for MPEG-1/2 video decoding
Definition: codec_id.h:54
MpegEncContext
MpegEncContext.
Definition: mpegvideo.h:67
mpeg2_get_f_code
static int mpeg2_get_f_code(const MpegEncContext *s)
Reconstruct bitstream f_code.
Definition: vaapi_mpeg2.c:31