FFmpeg
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Modules Pages
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 "mpegutils.h"
25 #include "mpegvideo.h"
26 #include "mpegvideodec.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 
43  av_unused const AVBufferRef *buffer_ref,
44  av_unused const uint8_t *buffer,
45  av_unused uint32_t size)
46 {
47  const MpegEncContext *s = avctx->priv_data;
48  VAAPIDecodePicture *pic = s->cur_pic.ptr->hwaccel_picture_private;
49  VAPictureParameterBufferMPEG2 pic_param;
50  VAIQMatrixBufferMPEG2 iq_matrix;
51  int i, err;
52 
53  pic->output_surface = ff_vaapi_get_surface_id(s->cur_pic.ptr->f);
54 
55  pic_param = (VAPictureParameterBufferMPEG2) {
56  .horizontal_size = s->width,
57  .vertical_size = s->height,
58  .forward_reference_picture = VA_INVALID_ID,
59  .backward_reference_picture = VA_INVALID_ID,
60  .picture_coding_type = s->pict_type,
61  .f_code = mpeg2_get_f_code(s),
62  .picture_coding_extension.bits = {
63  .intra_dc_precision = s->intra_dc_precision,
64  .picture_structure = s->picture_structure,
65  .top_field_first = s->top_field_first,
66  .frame_pred_frame_dct = s->frame_pred_frame_dct,
67  .concealment_motion_vectors = s->concealment_motion_vectors,
68  .q_scale_type = s->q_scale_type,
69  .intra_vlc_format = s->intra_vlc_format,
70  .alternate_scan = s->alternate_scan,
71  .repeat_first_field = s->repeat_first_field,
72  .progressive_frame = s->progressive_frame,
73  .is_first_field = mpeg2_get_is_frame_start(s),
74  },
75  };
76 
77  switch (s->pict_type) {
78  case AV_PICTURE_TYPE_B:
79  pic_param.backward_reference_picture = ff_vaapi_get_surface_id(s->next_pic.ptr->f);
80  // fall-through
81  case AV_PICTURE_TYPE_P:
82  pic_param.forward_reference_picture = ff_vaapi_get_surface_id(s->last_pic.ptr->f);
83  break;
84  }
85 
86  err = ff_vaapi_decode_make_param_buffer(avctx, pic,
87  VAPictureParameterBufferType,
88  &pic_param, sizeof(pic_param));
89  if (err < 0)
90  goto fail;
91 
92  iq_matrix.load_intra_quantiser_matrix = 1;
93  iq_matrix.load_non_intra_quantiser_matrix = 1;
94  iq_matrix.load_chroma_intra_quantiser_matrix = 1;
95  iq_matrix.load_chroma_non_intra_quantiser_matrix = 1;
96 
97  for (i = 0; i < 64; i++) {
98  int n = s->idsp.idct_permutation[ff_zigzag_direct[i]];
99  iq_matrix.intra_quantiser_matrix[i] = s->intra_matrix[n];
100  iq_matrix.non_intra_quantiser_matrix[i] = s->inter_matrix[n];
101  iq_matrix.chroma_intra_quantiser_matrix[i] = s->chroma_intra_matrix[n];
102  iq_matrix.chroma_non_intra_quantiser_matrix[i] = s->chroma_inter_matrix[n];
103  }
104 
105  err = ff_vaapi_decode_make_param_buffer(avctx, pic,
106  VAIQMatrixBufferType,
107  &iq_matrix, sizeof(iq_matrix));
108  if (err < 0)
109  goto fail;
110 
111  return 0;
112 
113 fail:
114  ff_vaapi_decode_cancel(avctx, pic);
115  return err;
116 }
117 
119 {
120  MpegEncContext *s = avctx->priv_data;
121  VAAPIDecodePicture *pic = s->cur_pic.ptr->hwaccel_picture_private;
122  int ret;
123 
124  ret = ff_vaapi_decode_issue(avctx, pic);
125  if (ret < 0)
126  goto fail;
127 
128  ff_mpeg_draw_horiz_band(s, 0, s->avctx->height);
129 
130 fail:
131  return ret;
132 }
133 
134 static int vaapi_mpeg2_decode_slice(AVCodecContext *avctx, const uint8_t *buffer, uint32_t size)
135 {
136  const MpegEncContext *s = avctx->priv_data;
137  VAAPIDecodePicture *pic = s->cur_pic.ptr->hwaccel_picture_private;
138  VASliceParameterBufferMPEG2 slice_param;
139  GetBitContext gb;
140  uint32_t quantiser_scale_code, intra_slice_flag, macroblock_offset;
141  int err;
142 
143  /* Determine macroblock_offset */
144  init_get_bits(&gb, buffer, 8 * size);
145  if (get_bits_long(&gb, 32) >> 8 != 1) /* start code */
146  return AVERROR_INVALIDDATA;
147  quantiser_scale_code = get_bits(&gb, 5);
148  intra_slice_flag = get_bits1(&gb);
149  if (intra_slice_flag) {
150  skip_bits(&gb, 8);
151  if (skip_1stop_8data_bits(&gb) < 0)
152  return AVERROR_INVALIDDATA;
153  }
154  macroblock_offset = get_bits_count(&gb);
155 
156  slice_param = (VASliceParameterBufferMPEG2) {
157  .slice_data_size = size,
158  .slice_data_offset = 0,
159  .slice_data_flag = VA_SLICE_DATA_FLAG_ALL,
160  .macroblock_offset = macroblock_offset,
161  .slice_horizontal_position = s->mb_x,
162  .slice_vertical_position = s->mb_y >> (s->picture_structure != PICT_FRAME),
163  .quantiser_scale_code = quantiser_scale_code,
164  .intra_slice_flag = intra_slice_flag,
165  };
166 
167  err = ff_vaapi_decode_make_slice_buffer(avctx, pic,
168  &slice_param, 1, sizeof(slice_param),
169  buffer, size);
170  if (err < 0) {
171  ff_vaapi_decode_cancel(avctx, pic);
172  return err;
173  }
174 
175  return 0;
176 }
177 
179  .p.name = "mpeg2_vaapi",
180  .p.type = AVMEDIA_TYPE_VIDEO,
181  .p.id = AV_CODEC_ID_MPEG2VIDEO,
182  .p.pix_fmt = AV_PIX_FMT_VAAPI,
183  .start_frame = &vaapi_mpeg2_start_frame,
184  .end_frame = &vaapi_mpeg2_end_frame,
185  .decode_slice = &vaapi_mpeg2_decode_slice,
186  .frame_priv_data_size = sizeof(VAAPIDecodePicture),
189  .frame_params = &ff_vaapi_common_frame_params,
190  .priv_data_size = sizeof(VAAPIDecodeContext),
191  .caps_internal = HWACCEL_CAP_ASYNC_SAFE,
192 };
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:404
get_bits_count
static int get_bits_count(const GetBitContext *s)
Definition: get_bits.h:249
av_unused
#define av_unused
Definition: attributes.h:131
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:497
skip_bits
static void skip_bits(GetBitContext *s, int n)
Definition: get_bits.h:364
get_bits
static unsigned int get_bits(GetBitContext *s, int n)
Read 1-25 bits.
Definition: get_bits.h:318
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:193
GetBitContext
Definition: get_bits.h:108
ff_mpeg2_vaapi_hwaccel
const FFHWAccel ff_mpeg2_vaapi_hwaccel
Definition: vaapi_mpeg2.c:178
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:42
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
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:371
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
init
int(* init)(AVBSFContext *ctx)
Definition: dts2pts.c:368
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:422
ff_vaapi_decode_cancel
int ff_vaapi_decode_cancel(AVCodecContext *avctx, VAAPIDecodePicture *pic)
Definition: vaapi_decode.c:247
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:134
AVHWAccel::name
const char * name
Name of the hardware accelerated codec.
Definition: avcodec.h:2124
uninit
static void uninit(AVBSFContext *ctx)
Definition: pcm_rechunk.c:68
i
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:256
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:683
AVCodecContext
main external API structure.
Definition: avcodec.h:451
AV_PICTURE_TYPE_B
@ AV_PICTURE_TYPE_B
Bi-dir predicted.
Definition: avutil.h:281
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:118
AV_PICTURE_TYPE_P
@ AV_PICTURE_TYPE_P
Predicted.
Definition: avutil.h:280
AVMEDIA_TYPE_VIDEO
@ AVMEDIA_TYPE_VIDEO
Definition: avutil.h:201
AVBufferRef
A reference to a data buffer.
Definition: buffer.h:82
AVCodecContext::priv_data
void * priv_data
Definition: avcodec.h:478
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:73
mpeg2_get_f_code
static int mpeg2_get_f_code(const MpegEncContext *s)
Reconstruct bitstream f_code.
Definition: vaapi_mpeg2.c:30