annotate vaapi_mpeg2.c @ 12530:63edd10ad4bc libavcodec tip

Try to fix crashes introduced by r25218 r25218 made assumptions about the existence of past reference frames that weren't necessarily true.
author darkshikari
date Tue, 28 Sep 2010 09:06:22 +0000
parents 8a4984c5cacc
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
9253
60a0739a0f0e Add MPEG-2 bitstream decoding through VA API.
gb
parents:
diff changeset
1 /*
60a0739a0f0e Add MPEG-2 bitstream decoding through VA API.
gb
parents:
diff changeset
2 * MPEG-2 HW decode acceleration through VA API
60a0739a0f0e Add MPEG-2 bitstream decoding through VA API.
gb
parents:
diff changeset
3 *
60a0739a0f0e Add MPEG-2 bitstream decoding through VA API.
gb
parents:
diff changeset
4 * Copyright (C) 2008-2009 Splitted-Desktop Systems
60a0739a0f0e Add MPEG-2 bitstream decoding through VA API.
gb
parents:
diff changeset
5 *
60a0739a0f0e Add MPEG-2 bitstream decoding through VA API.
gb
parents:
diff changeset
6 * This file is part of FFmpeg.
60a0739a0f0e Add MPEG-2 bitstream decoding through VA API.
gb
parents:
diff changeset
7 *
60a0739a0f0e Add MPEG-2 bitstream decoding through VA API.
gb
parents:
diff changeset
8 * FFmpeg is free software; you can redistribute it and/or
60a0739a0f0e Add MPEG-2 bitstream decoding through VA API.
gb
parents:
diff changeset
9 * modify it under the terms of the GNU Lesser General Public
60a0739a0f0e Add MPEG-2 bitstream decoding through VA API.
gb
parents:
diff changeset
10 * License as published by the Free Software Foundation; either
60a0739a0f0e Add MPEG-2 bitstream decoding through VA API.
gb
parents:
diff changeset
11 * version 2.1 of the License, or (at your option) any later version.
60a0739a0f0e Add MPEG-2 bitstream decoding through VA API.
gb
parents:
diff changeset
12 *
60a0739a0f0e Add MPEG-2 bitstream decoding through VA API.
gb
parents:
diff changeset
13 * FFmpeg is distributed in the hope that it will be useful,
60a0739a0f0e Add MPEG-2 bitstream decoding through VA API.
gb
parents:
diff changeset
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
60a0739a0f0e Add MPEG-2 bitstream decoding through VA API.
gb
parents:
diff changeset
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
60a0739a0f0e Add MPEG-2 bitstream decoding through VA API.
gb
parents:
diff changeset
16 * Lesser General Public License for more details.
60a0739a0f0e Add MPEG-2 bitstream decoding through VA API.
gb
parents:
diff changeset
17 *
60a0739a0f0e Add MPEG-2 bitstream decoding through VA API.
gb
parents:
diff changeset
18 * You should have received a copy of the GNU Lesser General Public
60a0739a0f0e Add MPEG-2 bitstream decoding through VA API.
gb
parents:
diff changeset
19 * License along with FFmpeg; if not, write to the Free Software
60a0739a0f0e Add MPEG-2 bitstream decoding through VA API.
gb
parents:
diff changeset
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
60a0739a0f0e Add MPEG-2 bitstream decoding through VA API.
gb
parents:
diff changeset
21 */
60a0739a0f0e Add MPEG-2 bitstream decoding through VA API.
gb
parents:
diff changeset
22
60a0739a0f0e Add MPEG-2 bitstream decoding through VA API.
gb
parents:
diff changeset
23 #include "vaapi_internal.h"
60a0739a0f0e Add MPEG-2 bitstream decoding through VA API.
gb
parents:
diff changeset
24 #include "dsputil.h"
60a0739a0f0e Add MPEG-2 bitstream decoding through VA API.
gb
parents:
diff changeset
25
60a0739a0f0e Add MPEG-2 bitstream decoding through VA API.
gb
parents:
diff changeset
26 /** Reconstruct bitstream f_code */
60a0739a0f0e Add MPEG-2 bitstream decoding through VA API.
gb
parents:
diff changeset
27 static inline int mpeg2_get_f_code(MpegEncContext *s)
60a0739a0f0e Add MPEG-2 bitstream decoding through VA API.
gb
parents:
diff changeset
28 {
60a0739a0f0e Add MPEG-2 bitstream decoding through VA API.
gb
parents:
diff changeset
29 return ((s->mpeg_f_code[0][0] << 12) | (s->mpeg_f_code[0][1] << 8) |
60a0739a0f0e Add MPEG-2 bitstream decoding through VA API.
gb
parents:
diff changeset
30 (s->mpeg_f_code[1][0] << 4) | s->mpeg_f_code[1][1]);
60a0739a0f0e Add MPEG-2 bitstream decoding through VA API.
gb
parents:
diff changeset
31 }
60a0739a0f0e Add MPEG-2 bitstream decoding through VA API.
gb
parents:
diff changeset
32
60a0739a0f0e Add MPEG-2 bitstream decoding through VA API.
gb
parents:
diff changeset
33 /** Determine frame start: first field for field picture or frame picture */
60a0739a0f0e Add MPEG-2 bitstream decoding through VA API.
gb
parents:
diff changeset
34 static inline int mpeg2_get_is_frame_start(MpegEncContext *s)
60a0739a0f0e Add MPEG-2 bitstream decoding through VA API.
gb
parents:
diff changeset
35 {
60a0739a0f0e Add MPEG-2 bitstream decoding through VA API.
gb
parents:
diff changeset
36 return s->first_field || s->picture_structure == PICT_FRAME;
60a0739a0f0e Add MPEG-2 bitstream decoding through VA API.
gb
parents:
diff changeset
37 }
60a0739a0f0e Add MPEG-2 bitstream decoding through VA API.
gb
parents:
diff changeset
38
60a0739a0f0e Add MPEG-2 bitstream decoding through VA API.
gb
parents:
diff changeset
39 static int vaapi_mpeg2_start_frame(AVCodecContext *avctx, av_unused const uint8_t *buffer, av_unused uint32_t size)
60a0739a0f0e Add MPEG-2 bitstream decoding through VA API.
gb
parents:
diff changeset
40 {
60a0739a0f0e Add MPEG-2 bitstream decoding through VA API.
gb
parents:
diff changeset
41 struct MpegEncContext * const s = avctx->priv_data;
60a0739a0f0e Add MPEG-2 bitstream decoding through VA API.
gb
parents:
diff changeset
42 struct vaapi_context * const vactx = avctx->hwaccel_context;
60a0739a0f0e Add MPEG-2 bitstream decoding through VA API.
gb
parents:
diff changeset
43 VAPictureParameterBufferMPEG2 *pic_param;
60a0739a0f0e Add MPEG-2 bitstream decoding through VA API.
gb
parents:
diff changeset
44 VAIQMatrixBufferMPEG2 *iq_matrix;
60a0739a0f0e Add MPEG-2 bitstream decoding through VA API.
gb
parents:
diff changeset
45 int i;
60a0739a0f0e Add MPEG-2 bitstream decoding through VA API.
gb
parents:
diff changeset
46
60a0739a0f0e Add MPEG-2 bitstream decoding through VA API.
gb
parents:
diff changeset
47 dprintf(avctx, "vaapi_mpeg2_start_frame()\n");
60a0739a0f0e Add MPEG-2 bitstream decoding through VA API.
gb
parents:
diff changeset
48
60a0739a0f0e Add MPEG-2 bitstream decoding through VA API.
gb
parents:
diff changeset
49 vactx->slice_param_size = sizeof(VASliceParameterBufferMPEG2);
60a0739a0f0e Add MPEG-2 bitstream decoding through VA API.
gb
parents:
diff changeset
50
60a0739a0f0e Add MPEG-2 bitstream decoding through VA API.
gb
parents:
diff changeset
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
60a0739a0f0e Add MPEG-2 bitstream decoding through VA API.
gb
parents:
diff changeset
55 pic_param->horizontal_size = s->width;
60a0739a0f0e Add MPEG-2 bitstream decoding through VA API.
gb
parents:
diff changeset
56 pic_param->vertical_size = s->height;
10725
3b6b7fe1c27c Use VA_INVALID_ID instead of hard coded values.
gb
parents: 10724
diff changeset
57 pic_param->forward_reference_picture = VA_INVALID_ID;
3b6b7fe1c27c Use VA_INVALID_ID instead of hard coded values.
gb
parents: 10724
diff changeset
58 pic_param->backward_reference_picture = VA_INVALID_ID;
9253
60a0739a0f0e Add MPEG-2 bitstream decoding through VA API.
gb
parents:
diff changeset
59 pic_param->picture_coding_type = s->pict_type;
60a0739a0f0e Add MPEG-2 bitstream decoding through VA API.
gb
parents:
diff changeset
60 pic_param->f_code = mpeg2_get_f_code(s);
60a0739a0f0e Add MPEG-2 bitstream decoding through VA API.
gb
parents:
diff changeset
61 pic_param->picture_coding_extension.value = 0; /* reset all bits */
60a0739a0f0e Add MPEG-2 bitstream decoding through VA API.
gb
parents:
diff changeset
62 pic_param->picture_coding_extension.bits.intra_dc_precision = s->intra_dc_precision;
60a0739a0f0e Add MPEG-2 bitstream decoding through VA API.
gb
parents:
diff changeset
63 pic_param->picture_coding_extension.bits.picture_structure = s->picture_structure;
60a0739a0f0e Add MPEG-2 bitstream decoding through VA API.
gb
parents:
diff changeset
64 pic_param->picture_coding_extension.bits.top_field_first = s->top_field_first;
60a0739a0f0e Add MPEG-2 bitstream decoding through VA API.
gb
parents:
diff changeset
65 pic_param->picture_coding_extension.bits.frame_pred_frame_dct = s->frame_pred_frame_dct;
60a0739a0f0e Add MPEG-2 bitstream decoding through VA API.
gb
parents:
diff changeset
66 pic_param->picture_coding_extension.bits.concealment_motion_vectors = s->concealment_motion_vectors;
60a0739a0f0e Add MPEG-2 bitstream decoding through VA API.
gb
parents:
diff changeset
67 pic_param->picture_coding_extension.bits.q_scale_type = s->q_scale_type;
60a0739a0f0e Add MPEG-2 bitstream decoding through VA API.
gb
parents:
diff changeset
68 pic_param->picture_coding_extension.bits.intra_vlc_format = s->intra_vlc_format;
60a0739a0f0e Add MPEG-2 bitstream decoding through VA API.
gb
parents:
diff changeset
69 pic_param->picture_coding_extension.bits.alternate_scan = s->alternate_scan;
60a0739a0f0e Add MPEG-2 bitstream decoding through VA API.
gb
parents:
diff changeset
70 pic_param->picture_coding_extension.bits.repeat_first_field = s->repeat_first_field;
60a0739a0f0e Add MPEG-2 bitstream decoding through VA API.
gb
parents:
diff changeset
71 pic_param->picture_coding_extension.bits.progressive_frame = s->progressive_frame;
60a0739a0f0e Add MPEG-2 bitstream decoding through VA API.
gb
parents:
diff changeset
72 pic_param->picture_coding_extension.bits.is_first_field = mpeg2_get_is_frame_start(s);
60a0739a0f0e Add MPEG-2 bitstream decoding through VA API.
gb
parents:
diff changeset
73
60a0739a0f0e Add MPEG-2 bitstream decoding through VA API.
gb
parents:
diff changeset
74 switch (s->pict_type) {
60a0739a0f0e Add MPEG-2 bitstream decoding through VA API.
gb
parents:
diff changeset
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
60a0739a0f0e Add MPEG-2 bitstream decoding through VA API.
gb
parents:
diff changeset
77 // fall-through
60a0739a0f0e Add MPEG-2 bitstream decoding through VA API.
gb
parents:
diff changeset
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
60a0739a0f0e Add MPEG-2 bitstream decoding through VA API.
gb
parents:
diff changeset
80 break;
60a0739a0f0e Add MPEG-2 bitstream decoding through VA API.
gb
parents:
diff changeset
81 }
60a0739a0f0e Add MPEG-2 bitstream decoding through VA API.
gb
parents:
diff changeset
82
60a0739a0f0e Add MPEG-2 bitstream decoding through VA API.
gb
parents:
diff changeset
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
60a0739a0f0e Add MPEG-2 bitstream decoding through VA API.
gb
parents:
diff changeset
87 iq_matrix->load_intra_quantiser_matrix = 1;
60a0739a0f0e Add MPEG-2 bitstream decoding through VA API.
gb
parents:
diff changeset
88 iq_matrix->load_non_intra_quantiser_matrix = 1;
60a0739a0f0e Add MPEG-2 bitstream decoding through VA API.
gb
parents:
diff changeset
89 iq_matrix->load_chroma_intra_quantiser_matrix = 1;
60a0739a0f0e Add MPEG-2 bitstream decoding through VA API.
gb
parents:
diff changeset
90 iq_matrix->load_chroma_non_intra_quantiser_matrix = 1;
60a0739a0f0e Add MPEG-2 bitstream decoding through VA API.
gb
parents:
diff changeset
91
60a0739a0f0e Add MPEG-2 bitstream decoding through VA API.
gb
parents:
diff changeset
92 for (i = 0; i < 64; i++) {
60a0739a0f0e Add MPEG-2 bitstream decoding through VA API.
gb
parents:
diff changeset
93 int n = s->dsp.idct_permutation[ff_zigzag_direct[i]];
60a0739a0f0e Add MPEG-2 bitstream decoding through VA API.
gb
parents:
diff changeset
94 iq_matrix->intra_quantiser_matrix[i] = s->intra_matrix[n];
60a0739a0f0e Add MPEG-2 bitstream decoding through VA API.
gb
parents:
diff changeset
95 iq_matrix->non_intra_quantiser_matrix[i] = s->inter_matrix[n];
60a0739a0f0e Add MPEG-2 bitstream decoding through VA API.
gb
parents:
diff changeset
96 iq_matrix->chroma_intra_quantiser_matrix[i] = s->chroma_intra_matrix[n];
60a0739a0f0e Add MPEG-2 bitstream decoding through VA API.
gb
parents:
diff changeset
97 iq_matrix->chroma_non_intra_quantiser_matrix[i] = s->chroma_inter_matrix[n];
60a0739a0f0e Add MPEG-2 bitstream decoding through VA API.
gb
parents:
diff changeset
98 }
60a0739a0f0e Add MPEG-2 bitstream decoding through VA API.
gb
parents:
diff changeset
99 return 0;
60a0739a0f0e Add MPEG-2 bitstream decoding through VA API.
gb
parents:
diff changeset
100 }
60a0739a0f0e Add MPEG-2 bitstream decoding through VA API.
gb
parents:
diff changeset
101
60a0739a0f0e Add MPEG-2 bitstream decoding through VA API.
gb
parents:
diff changeset
102 static int vaapi_mpeg2_end_frame(AVCodecContext *avctx)
60a0739a0f0e Add MPEG-2 bitstream decoding through VA API.
gb
parents:
diff changeset
103 {
60a0739a0f0e Add MPEG-2 bitstream decoding through VA API.
gb
parents:
diff changeset
104 return ff_vaapi_common_end_frame(avctx->priv_data);
60a0739a0f0e Add MPEG-2 bitstream decoding through VA API.
gb
parents:
diff changeset
105 }
60a0739a0f0e Add MPEG-2 bitstream decoding through VA API.
gb
parents:
diff changeset
106
60a0739a0f0e Add MPEG-2 bitstream decoding through VA API.
gb
parents:
diff changeset
107 static int vaapi_mpeg2_decode_slice(AVCodecContext *avctx, const uint8_t *buffer, uint32_t size)
60a0739a0f0e Add MPEG-2 bitstream decoding through VA API.
gb
parents:
diff changeset
108 {
60a0739a0f0e Add MPEG-2 bitstream decoding through VA API.
gb
parents:
diff changeset
109 MpegEncContext * const s = avctx->priv_data;
60a0739a0f0e Add MPEG-2 bitstream decoding through VA API.
gb
parents:
diff changeset
110 VASliceParameterBufferMPEG2 *slice_param;
60a0739a0f0e Add MPEG-2 bitstream decoding through VA API.
gb
parents:
diff changeset
111 GetBitContext gb;
60a0739a0f0e Add MPEG-2 bitstream decoding through VA API.
gb
parents:
diff changeset
112 uint32_t start_code, quantiser_scale_code, intra_slice_flag, macroblock_offset;
60a0739a0f0e Add MPEG-2 bitstream decoding through VA API.
gb
parents:
diff changeset
113
60a0739a0f0e Add MPEG-2 bitstream decoding through VA API.
gb
parents:
diff changeset
114 dprintf(avctx, "vaapi_mpeg2_decode_slice(): buffer %p, size %d\n", buffer, size);
60a0739a0f0e Add MPEG-2 bitstream decoding through VA API.
gb
parents:
diff changeset
115
60a0739a0f0e Add MPEG-2 bitstream decoding through VA API.
gb
parents:
diff changeset
116 /* Determine macroblock_offset */
60a0739a0f0e Add MPEG-2 bitstream decoding through VA API.
gb
parents:
diff changeset
117 init_get_bits(&gb, buffer, 8 * size);
60a0739a0f0e Add MPEG-2 bitstream decoding through VA API.
gb
parents:
diff changeset
118 start_code = get_bits(&gb, 32);
60a0739a0f0e Add MPEG-2 bitstream decoding through VA API.
gb
parents:
diff changeset
119 assert((start_code & 0xffffff00) == 0x00000100);
60a0739a0f0e Add MPEG-2 bitstream decoding through VA API.
gb
parents:
diff changeset
120 quantiser_scale_code = get_bits(&gb, 5);
60a0739a0f0e Add MPEG-2 bitstream decoding through VA API.
gb
parents:
diff changeset
121 intra_slice_flag = get_bits1(&gb);
60a0739a0f0e Add MPEG-2 bitstream decoding through VA API.
gb
parents:
diff changeset
122 if (intra_slice_flag) {
60a0739a0f0e Add MPEG-2 bitstream decoding through VA API.
gb
parents:
diff changeset
123 skip_bits(&gb, 8);
60a0739a0f0e Add MPEG-2 bitstream decoding through VA API.
gb
parents:
diff changeset
124 while (get_bits1(&gb) != 0)
60a0739a0f0e Add MPEG-2 bitstream decoding through VA API.
gb
parents:
diff changeset
125 skip_bits(&gb, 8);
60a0739a0f0e Add MPEG-2 bitstream decoding through VA API.
gb
parents:
diff changeset
126 }
60a0739a0f0e Add MPEG-2 bitstream decoding through VA API.
gb
parents:
diff changeset
127 macroblock_offset = get_bits_count(&gb);
60a0739a0f0e Add MPEG-2 bitstream decoding through VA API.
gb
parents:
diff changeset
128
60a0739a0f0e Add MPEG-2 bitstream decoding through VA API.
gb
parents:
diff changeset
129 /* Fill in VASliceParameterBufferMPEG2 */
60a0739a0f0e Add MPEG-2 bitstream decoding through VA API.
gb
parents:
diff changeset
130 slice_param = (VASliceParameterBufferMPEG2 *)ff_vaapi_alloc_slice(avctx->hwaccel_context, buffer, size);
60a0739a0f0e Add MPEG-2 bitstream decoding through VA API.
gb
parents:
diff changeset
131 if (!slice_param)
60a0739a0f0e Add MPEG-2 bitstream decoding through VA API.
gb
parents:
diff changeset
132 return -1;
60a0739a0f0e Add MPEG-2 bitstream decoding through VA API.
gb
parents:
diff changeset
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
60a0739a0f0e Add MPEG-2 bitstream decoding through VA API.
gb
parents:
diff changeset
135 slice_param->slice_vertical_position = s->mb_y;
60a0739a0f0e Add MPEG-2 bitstream decoding through VA API.
gb
parents:
diff changeset
136 slice_param->quantiser_scale_code = quantiser_scale_code;
60a0739a0f0e Add MPEG-2 bitstream decoding through VA API.
gb
parents:
diff changeset
137 slice_param->intra_slice_flag = intra_slice_flag;
60a0739a0f0e Add MPEG-2 bitstream decoding through VA API.
gb
parents:
diff changeset
138 return 0;
60a0739a0f0e Add MPEG-2 bitstream decoding through VA API.
gb
parents:
diff changeset
139 }
60a0739a0f0e Add MPEG-2 bitstream decoding through VA API.
gb
parents:
diff changeset
140
60a0739a0f0e Add MPEG-2 bitstream decoding through VA API.
gb
parents:
diff changeset
141 AVHWAccel mpeg2_vaapi_hwaccel = {
60a0739a0f0e Add MPEG-2 bitstream decoding through VA API.
gb
parents:
diff changeset
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
60a0739a0f0e Add MPEG-2 bitstream decoding through VA API.
gb
parents:
diff changeset
144 .id = CODEC_ID_MPEG2VIDEO,
60a0739a0f0e Add MPEG-2 bitstream decoding through VA API.
gb
parents:
diff changeset
145 .pix_fmt = PIX_FMT_VAAPI_VLD,
60a0739a0f0e Add MPEG-2 bitstream decoding through VA API.
gb
parents:
diff changeset
146 .capabilities = 0,
60a0739a0f0e Add MPEG-2 bitstream decoding through VA API.
gb
parents:
diff changeset
147 .start_frame = vaapi_mpeg2_start_frame,
60a0739a0f0e Add MPEG-2 bitstream decoding through VA API.
gb
parents:
diff changeset
148 .end_frame = vaapi_mpeg2_end_frame,
60a0739a0f0e Add MPEG-2 bitstream decoding through VA API.
gb
parents:
diff changeset
149 .decode_slice = vaapi_mpeg2_decode_slice,
60a0739a0f0e Add MPEG-2 bitstream decoding through VA API.
gb
parents:
diff changeset
150 .priv_data_size = 0,
60a0739a0f0e Add MPEG-2 bitstream decoding through VA API.
gb
parents:
diff changeset
151 };