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 "hwconfig.h"
24 #include "mpegutils.h"
25 #include "mpegvideo.h"
26 #include "internal.h"
27 #include "vaapi_decode.h"
28 
29 /** Reconstruct bitstream f_code */
30 static inline int mpeg2_get_f_code(const MpegEncContext *s)
31 {
32  return (s->mpeg_f_code[0][0] << 12) | (s->mpeg_f_code[0][1] << 8) |
33  (s->mpeg_f_code[1][0] << 4) | s->mpeg_f_code[1][1];
34 }
35 
36 /** Determine frame start: first field for field picture or frame picture */
37 static inline int mpeg2_get_is_frame_start(const MpegEncContext *s)
38 {
39  return s->first_field || s->picture_structure == PICT_FRAME;
40 }
41 
42 static int vaapi_mpeg2_start_frame(AVCodecContext *avctx, av_unused const uint8_t *buffer, av_unused uint32_t size)
43 {
44  const MpegEncContext *s = avctx->priv_data;
45  VAAPIDecodePicture *pic = s->current_picture_ptr->hwaccel_picture_private;
46  VAPictureParameterBufferMPEG2 pic_param;
47  VAIQMatrixBufferMPEG2 iq_matrix;
48  int i, err;
49 
50  pic->output_surface = ff_vaapi_get_surface_id(s->current_picture_ptr->f);
51 
52  pic_param = (VAPictureParameterBufferMPEG2) {
53  .horizontal_size = s->width,
54  .vertical_size = s->height,
55  .forward_reference_picture = VA_INVALID_ID,
56  .backward_reference_picture = VA_INVALID_ID,
57  .picture_coding_type = s->pict_type,
58  .f_code = mpeg2_get_f_code(s),
59  .picture_coding_extension.bits = {
60  .intra_dc_precision = s->intra_dc_precision,
61  .picture_structure = s->picture_structure,
62  .top_field_first = s->top_field_first,
63  .frame_pred_frame_dct = s->frame_pred_frame_dct,
64  .concealment_motion_vectors = s->concealment_motion_vectors,
65  .q_scale_type = s->q_scale_type,
66  .intra_vlc_format = s->intra_vlc_format,
67  .alternate_scan = s->alternate_scan,
68  .repeat_first_field = s->repeat_first_field,
69  .progressive_frame = s->progressive_frame,
70  .is_first_field = mpeg2_get_is_frame_start(s),
71  },
72  };
73 
74  switch (s->pict_type) {
75  case AV_PICTURE_TYPE_B:
76  pic_param.backward_reference_picture = ff_vaapi_get_surface_id(s->next_picture.f);
77  // fall-through
78  case AV_PICTURE_TYPE_P:
79  pic_param.forward_reference_picture = ff_vaapi_get_surface_id(s->last_picture.f);
80  break;
81  }
82 
83  err = ff_vaapi_decode_make_param_buffer(avctx, pic,
84  VAPictureParameterBufferType,
85  &pic_param, sizeof(pic_param));
86  if (err < 0)
87  goto fail;
88 
89  iq_matrix.load_intra_quantiser_matrix = 1;
90  iq_matrix.load_non_intra_quantiser_matrix = 1;
91  iq_matrix.load_chroma_intra_quantiser_matrix = 1;
92  iq_matrix.load_chroma_non_intra_quantiser_matrix = 1;
93 
94  for (i = 0; i < 64; i++) {
95  int n = s->idsp.idct_permutation[ff_zigzag_direct[i]];
96  iq_matrix.intra_quantiser_matrix[i] = s->intra_matrix[n];
97  iq_matrix.non_intra_quantiser_matrix[i] = s->inter_matrix[n];
98  iq_matrix.chroma_intra_quantiser_matrix[i] = s->chroma_intra_matrix[n];
99  iq_matrix.chroma_non_intra_quantiser_matrix[i] = s->chroma_inter_matrix[n];
100  }
101 
102  err = ff_vaapi_decode_make_param_buffer(avctx, pic,
103  VAIQMatrixBufferType,
104  &iq_matrix, sizeof(iq_matrix));
105  if (err < 0)
106  goto fail;
107 
108  return 0;
109 
110 fail:
111  ff_vaapi_decode_cancel(avctx, pic);
112  return err;
113 }
114 
116 {
117  MpegEncContext *s = avctx->priv_data;
118  VAAPIDecodePicture *pic = s->current_picture_ptr->hwaccel_picture_private;
119  int ret;
120 
121  ret = ff_vaapi_decode_issue(avctx, pic);
122  if (ret < 0)
123  goto fail;
124 
125  ff_mpeg_draw_horiz_band(s, 0, s->avctx->height);
126 
127 fail:
128  return ret;
129 }
130 
131 static int vaapi_mpeg2_decode_slice(AVCodecContext *avctx, const uint8_t *buffer, uint32_t size)
132 {
133  const MpegEncContext *s = avctx->priv_data;
134  VAAPIDecodePicture *pic = s->current_picture_ptr->hwaccel_picture_private;
135  VASliceParameterBufferMPEG2 slice_param;
136  GetBitContext gb;
137  uint32_t quantiser_scale_code, intra_slice_flag, macroblock_offset;
138  int err;
139 
140  /* Determine macroblock_offset */
141  init_get_bits(&gb, buffer, 8 * size);
142  if (get_bits_long(&gb, 32) >> 8 != 1) /* start code */
143  return AVERROR_INVALIDDATA;
144  quantiser_scale_code = get_bits(&gb, 5);
145  intra_slice_flag = get_bits1(&gb);
146  if (intra_slice_flag) {
147  skip_bits(&gb, 8);
148  if (skip_1stop_8data_bits(&gb) < 0)
149  return AVERROR_INVALIDDATA;
150  }
151  macroblock_offset = get_bits_count(&gb);
152 
153  slice_param = (VASliceParameterBufferMPEG2) {
154  .slice_data_size = size,
155  .slice_data_offset = 0,
156  .slice_data_flag = VA_SLICE_DATA_FLAG_ALL,
157  .macroblock_offset = macroblock_offset,
158  .slice_horizontal_position = s->mb_x,
159  .slice_vertical_position = s->mb_y >> (s->picture_structure != PICT_FRAME),
160  .quantiser_scale_code = quantiser_scale_code,
161  .intra_slice_flag = intra_slice_flag,
162  };
163 
164  err = ff_vaapi_decode_make_slice_buffer(avctx, pic,
165  &slice_param, sizeof(slice_param),
166  buffer, size);
167  if (err < 0) {
168  ff_vaapi_decode_cancel(avctx, pic);
169  return err;
170  }
171 
172  return 0;
173 }
174 
176  .name = "mpeg2_vaapi",
177  .type = AVMEDIA_TYPE_VIDEO,
179  .pix_fmt = AV_PIX_FMT_VAAPI,
180  .start_frame = &vaapi_mpeg2_start_frame,
181  .end_frame = &vaapi_mpeg2_end_frame,
182  .decode_slice = &vaapi_mpeg2_decode_slice,
183  .frame_priv_data_size = sizeof(VAAPIDecodePicture),
186  .frame_params = &ff_vaapi_common_frame_params,
187  .priv_data_size = sizeof(VAAPIDecodeContext),
188  .caps_internal = HWACCEL_CAP_ASYNC_SAFE,
189 };
PICT_FRAME
#define PICT_FRAME
Definition: mpegutils.h:38
hwconfig.h
init
static av_cold int init(AVCodecContext *avctx)
Definition: avrndec.c:31
ff_vaapi_get_surface_id
static VASurfaceID ff_vaapi_get_surface_id(AVFrame *pic)
Definition: vaapi_decode.h:30
VAAPIDecodeContext
Definition: vaapi_decode.h:50
vaapi_decode.h
get_bits_long
static unsigned int get_bits_long(GetBitContext *s, int n)
Read 0-32 bits.
Definition: get_bits.h:547
get_bits_count
static int get_bits_count(const GetBitContext *s)
Definition: get_bits.h:220
av_unused
#define av_unused
Definition: attributes.h:131
VAAPIDecodePicture
Definition: vaapi_decode.h:39
ff_vaapi_decode_make_slice_buffer
int ff_vaapi_decode_make_slice_buffer(AVCodecContext *avctx, VAAPIDecodePicture *pic, const void *params_data, size_t params_size, const void *slice_data, size_t slice_size)
Definition: vaapi_decode.c:59
internal.h
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:660
skip_bits
static void skip_bits(GetBitContext *s, int n)
Definition: get_bits.h:468
get_bits
static unsigned int get_bits(GetBitContext *s, int n)
Read 1-25 bits.
Definition: get_bits.h:380
AVHWAccel
Definition: avcodec.h:2039
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:30
fail
#define fail()
Definition: checkasm.h:127
GetBitContext
Definition: get_bits.h:62
ff_mpeg_draw_horiz_band
void ff_mpeg_draw_horiz_band(MpegEncContext *s, int y, int h)
Definition: mpegvideo.c:2264
VAAPIDecodePicture::output_surface
VASurfaceID output_surface
Definition: vaapi_decode.h:40
s
#define s(width, name)
Definition: cbs_vp9.c:257
ff_vaapi_decode_init
int ff_vaapi_decode_init(AVCodecContext *avctx)
Definition: vaapi_decode.c:634
ff_vaapi_common_frame_params
int ff_vaapi_common_frame_params(AVCodecContext *avctx, AVBufferRef *hw_frames_ctx)
Definition: vaapi_decode.c:610
ff_vaapi_decode_uninit
int ff_vaapi_decode_uninit(AVCodecContext *avctx)
Definition: vaapi_decode.c:680
ff_vaapi_decode_issue
int ff_vaapi_decode_issue(AVCodecContext *avctx, VAAPIDecodePicture *pic)
Definition: vaapi_decode.c:151
ff_mpeg2_vaapi_hwaccel
const AVHWAccel ff_mpeg2_vaapi_hwaccel
Definition: vaapi_mpeg2.c:175
vaapi_mpeg2_start_frame
static int vaapi_mpeg2_start_frame(AVCodecContext *avctx, av_unused const uint8_t *buffer, av_unused uint32_t size)
Definition: vaapi_mpeg2.c:42
get_bits1
static unsigned int get_bits1(GetBitContext *s)
Definition: get_bits.h:499
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:37
size
int size
Definition: twinvq_data.h:10344
ff_vaapi_decode_cancel
int ff_vaapi_decode_cancel(AVCodecContext *avctx, VAAPIDecodePicture *pic)
Definition: vaapi_decode.c:225
AV_PIX_FMT_VAAPI
@ AV_PIX_FMT_VAAPI
Hardware acceleration through VA-API, data[3] contains a VASurfaceID.
Definition: pixfmt.h:119
vaapi_mpeg2_decode_slice
static int vaapi_mpeg2_decode_slice(AVCodecContext *avctx, const uint8_t *buffer, uint32_t size)
Definition: vaapi_mpeg2.c:131
AVHWAccel::name
const char * name
Name of the hardware accelerated codec.
Definition: avcodec.h:2045
i
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:271
HWACCEL_CAP_ASYNC_SAFE
#define HWACCEL_CAP_ASYNC_SAFE
Definition: hwconfig.h:26
ff_zigzag_direct
const uint8_t ff_zigzag_direct[64]
Definition: mathtables.c:98
ret
ret
Definition: filter_design.txt:187
skip_1stop_8data_bits
static int skip_1stop_8data_bits(GetBitContext *gb)
Definition: get_bits.h:855
AVCodecContext
main external API structure.
Definition: avcodec.h:383
AV_PICTURE_TYPE_B
@ AV_PICTURE_TYPE_B
Bi-dir predicted.
Definition: avutil.h:276
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
vaapi_mpeg2_end_frame
static int vaapi_mpeg2_end_frame(AVCodecContext *avctx)
Definition: vaapi_mpeg2.c:115
AV_PICTURE_TYPE_P
@ AV_PICTURE_TYPE_P
Predicted.
Definition: avutil.h:275
AVMEDIA_TYPE_VIDEO
@ AVMEDIA_TYPE_VIDEO
Definition: avutil.h:201
AVCodecContext::priv_data
void * priv_data
Definition: avcodec.h:410
AVERROR_INVALIDDATA
#define AVERROR_INVALIDDATA
Invalid data found when processing input.
Definition: error.h:61
uninit
static av_cold int uninit(AVCodecContext *avctx)
Definition: crystalhd.c:282
AV_CODEC_ID_MPEG2VIDEO
@ AV_CODEC_ID_MPEG2VIDEO
preferred ID for MPEG-1/2 video decoding
Definition: codec_id.h:52
MpegEncContext
MpegEncContext.
Definition: mpegvideo.h:71
mpeg2_get_f_code
static int mpeg2_get_f_code(const MpegEncContext *s)
Reconstruct bitstream f_code.
Definition: vaapi_mpeg2.c:30