Mercurial > libavcodec.hg
annotate vaapi_mpeg2.c @ 12494:94eaea836bf4 libavcodec
Check avctx width/height more thoroughly (e.g. all values 0 except width would
have been accepted before).
Also do not fail if they are invalid but instead override them to 0.
This allows decoding e.g. MPEG video when only the container values are corrupted.
For encoding a value of 0,0 of course makes no sense, but was allowed
through before and will be caught by an extra check in the encode function.
author | reimar |
---|---|
date | Wed, 15 Sep 2010 04:46:55 +0000 |
parents | 8a4984c5cacc |
children |
rev | line source |
---|---|
9253 | 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 "vaapi_internal.h" | |
24 #include "dsputil.h" | |
25 | |
26 /** Reconstruct bitstream f_code */ | |
27 static inline int mpeg2_get_f_code(MpegEncContext *s) | |
28 { | |
29 return ((s->mpeg_f_code[0][0] << 12) | (s->mpeg_f_code[0][1] << 8) | | |
30 (s->mpeg_f_code[1][0] << 4) | s->mpeg_f_code[1][1]); | |
31 } | |
32 | |
33 /** Determine frame start: first field for field picture or frame picture */ | |
34 static inline int mpeg2_get_is_frame_start(MpegEncContext *s) | |
35 { | |
36 return s->first_field || s->picture_structure == PICT_FRAME; | |
37 } | |
38 | |
39 static int vaapi_mpeg2_start_frame(AVCodecContext *avctx, av_unused const uint8_t *buffer, av_unused uint32_t size) | |
40 { | |
41 struct MpegEncContext * const s = avctx->priv_data; | |
42 struct vaapi_context * const vactx = avctx->hwaccel_context; | |
43 VAPictureParameterBufferMPEG2 *pic_param; | |
44 VAIQMatrixBufferMPEG2 *iq_matrix; | |
45 int i; | |
46 | |
47 dprintf(avctx, "vaapi_mpeg2_start_frame()\n"); | |
48 | |
49 vactx->slice_param_size = sizeof(VASliceParameterBufferMPEG2); | |
50 | |
51 /* Fill in VAPictureParameterBufferMPEG2 */ | |
10724
de8d07d87c45
Rename ff_vaapi_alloc_picture() to ff_vaapi_alloc_pic_param().
gb
parents:
10723
diff
changeset
|
52 pic_param = ff_vaapi_alloc_pic_param(vactx, sizeof(VAPictureParameterBufferMPEG2)); |
9292
f0732d44f655
Improve VA API buffers allocation logic. This also reduces struct vaapi_context
gb
parents:
9253
diff
changeset
|
53 if (!pic_param) |
f0732d44f655
Improve VA API buffers allocation logic. This also reduces struct vaapi_context
gb
parents:
9253
diff
changeset
|
54 return -1; |
9253 | 55 pic_param->horizontal_size = s->width; |
56 pic_param->vertical_size = s->height; | |
10725 | 57 pic_param->forward_reference_picture = VA_INVALID_ID; |
58 pic_param->backward_reference_picture = VA_INVALID_ID; | |
9253 | 59 pic_param->picture_coding_type = s->pict_type; |
60 pic_param->f_code = mpeg2_get_f_code(s); | |
61 pic_param->picture_coding_extension.value = 0; /* reset all bits */ | |
62 pic_param->picture_coding_extension.bits.intra_dc_precision = s->intra_dc_precision; | |
63 pic_param->picture_coding_extension.bits.picture_structure = s->picture_structure; | |
64 pic_param->picture_coding_extension.bits.top_field_first = s->top_field_first; | |
65 pic_param->picture_coding_extension.bits.frame_pred_frame_dct = s->frame_pred_frame_dct; | |
66 pic_param->picture_coding_extension.bits.concealment_motion_vectors = s->concealment_motion_vectors; | |
67 pic_param->picture_coding_extension.bits.q_scale_type = s->q_scale_type; | |
68 pic_param->picture_coding_extension.bits.intra_vlc_format = s->intra_vlc_format; | |
69 pic_param->picture_coding_extension.bits.alternate_scan = s->alternate_scan; | |
70 pic_param->picture_coding_extension.bits.repeat_first_field = s->repeat_first_field; | |
71 pic_param->picture_coding_extension.bits.progressive_frame = s->progressive_frame; | |
72 pic_param->picture_coding_extension.bits.is_first_field = mpeg2_get_is_frame_start(s); | |
73 | |
74 switch (s->pict_type) { | |
75 case FF_B_TYPE: | |
10723
3f08c340020f
Rename ff_vaapi_get_surface() to ff_vaapi_get_surface_id().
gb
parents:
10178
diff
changeset
|
76 pic_param->backward_reference_picture = ff_vaapi_get_surface_id(&s->next_picture); |
9253 | 77 // fall-through |
78 case FF_P_TYPE: | |
10723
3f08c340020f
Rename ff_vaapi_get_surface() to ff_vaapi_get_surface_id().
gb
parents:
10178
diff
changeset
|
79 pic_param->forward_reference_picture = ff_vaapi_get_surface_id(&s->last_picture); |
9253 | 80 break; |
81 } | |
82 | |
83 /* Fill in VAIQMatrixBufferMPEG2 */ | |
9292
f0732d44f655
Improve VA API buffers allocation logic. This also reduces struct vaapi_context
gb
parents:
9253
diff
changeset
|
84 iq_matrix = ff_vaapi_alloc_iq_matrix(vactx, sizeof(VAIQMatrixBufferMPEG2)); |
f0732d44f655
Improve VA API buffers allocation logic. This also reduces struct vaapi_context
gb
parents:
9253
diff
changeset
|
85 if (!iq_matrix) |
f0732d44f655
Improve VA API buffers allocation logic. This also reduces struct vaapi_context
gb
parents:
9253
diff
changeset
|
86 return -1; |
9253 | 87 iq_matrix->load_intra_quantiser_matrix = 1; |
88 iq_matrix->load_non_intra_quantiser_matrix = 1; | |
89 iq_matrix->load_chroma_intra_quantiser_matrix = 1; | |
90 iq_matrix->load_chroma_non_intra_quantiser_matrix = 1; | |
91 | |
92 for (i = 0; i < 64; i++) { | |
93 int n = s->dsp.idct_permutation[ff_zigzag_direct[i]]; | |
94 iq_matrix->intra_quantiser_matrix[i] = s->intra_matrix[n]; | |
95 iq_matrix->non_intra_quantiser_matrix[i] = s->inter_matrix[n]; | |
96 iq_matrix->chroma_intra_quantiser_matrix[i] = s->chroma_intra_matrix[n]; | |
97 iq_matrix->chroma_non_intra_quantiser_matrix[i] = s->chroma_inter_matrix[n]; | |
98 } | |
99 return 0; | |
100 } | |
101 | |
102 static int vaapi_mpeg2_end_frame(AVCodecContext *avctx) | |
103 { | |
104 return ff_vaapi_common_end_frame(avctx->priv_data); | |
105 } | |
106 | |
107 static int vaapi_mpeg2_decode_slice(AVCodecContext *avctx, const uint8_t *buffer, uint32_t size) | |
108 { | |
109 MpegEncContext * const s = avctx->priv_data; | |
110 VASliceParameterBufferMPEG2 *slice_param; | |
111 GetBitContext gb; | |
112 uint32_t start_code, quantiser_scale_code, intra_slice_flag, macroblock_offset; | |
113 | |
114 dprintf(avctx, "vaapi_mpeg2_decode_slice(): buffer %p, size %d\n", buffer, size); | |
115 | |
116 /* Determine macroblock_offset */ | |
117 init_get_bits(&gb, buffer, 8 * size); | |
118 start_code = get_bits(&gb, 32); | |
119 assert((start_code & 0xffffff00) == 0x00000100); | |
120 quantiser_scale_code = get_bits(&gb, 5); | |
121 intra_slice_flag = get_bits1(&gb); | |
122 if (intra_slice_flag) { | |
123 skip_bits(&gb, 8); | |
124 while (get_bits1(&gb) != 0) | |
125 skip_bits(&gb, 8); | |
126 } | |
127 macroblock_offset = get_bits_count(&gb); | |
128 | |
129 /* Fill in VASliceParameterBufferMPEG2 */ | |
130 slice_param = (VASliceParameterBufferMPEG2 *)ff_vaapi_alloc_slice(avctx->hwaccel_context, buffer, size); | |
131 if (!slice_param) | |
132 return -1; | |
133 slice_param->macroblock_offset = macroblock_offset; | |
10178
140aa1e7328b
Fill in new VASliceParameterBufferMPEG2.slice_horizontal_position field.
gb
parents:
9292
diff
changeset
|
134 slice_param->slice_horizontal_position = s->mb_x; |
9253 | 135 slice_param->slice_vertical_position = s->mb_y; |
136 slice_param->quantiser_scale_code = quantiser_scale_code; | |
137 slice_param->intra_slice_flag = intra_slice_flag; | |
138 return 0; | |
139 } | |
140 | |
141 AVHWAccel mpeg2_vaapi_hwaccel = { | |
142 .name = "mpeg2_vaapi", | |
11560
8a4984c5cacc
Define AVMediaType enum, and use it instead of enum CodecType, which
stefano
parents:
10725
diff
changeset
|
143 .type = AVMEDIA_TYPE_VIDEO, |
9253 | 144 .id = CODEC_ID_MPEG2VIDEO, |
145 .pix_fmt = PIX_FMT_VAAPI_VLD, | |
146 .capabilities = 0, | |
147 .start_frame = vaapi_mpeg2_start_frame, | |
148 .end_frame = vaapi_mpeg2_end_frame, | |
149 .decode_slice = vaapi_mpeg2_decode_slice, | |
150 .priv_data_size = 0, | |
151 }; |