annotate dxva2_h264.c @ 10952:ea8f891d997d libavcodec

H264 DXVA2 implementation It allows VLD H264 decoding using DXVA2 (GPU assisted decoding API under VISTA and Windows 7). It is implemented by using AVHWAccel API. It has been tested successfully for some time in VLC using an nvidia card on Windows 7. To compile it, you need to have the system header dxva2api.h (either from microsoft or using http://downloads.videolan.org/pub/videolan/testing/contrib/dxva2api.h) The generated libavcodec.dll does not depend directly on any new lib as the necessary objects are given by the application using FFmpeg.
author fenrir
date Wed, 20 Jan 2010 18:54:51 +0000
parents
children b1ccfdc1b409
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
10952
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
1 /*
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
2 * DXVA2 H264 HW acceleration.
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
3 *
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
4 * copyright (c) 2009 Laurent Aimar
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
5 *
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
6 * This file is part of FFmpeg.
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
7 *
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
8 * FFmpeg is free software; you can redistribute it and/or
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
9 * modify it under the terms of the GNU Lesser General Public
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
10 * License as published by the Free Software Foundation; either
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
11 * version 2.1 of the License, or (at your option) any later version.
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
12 *
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
13 * FFmpeg is distributed in the hope that it will be useful,
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
16 * Lesser General Public License for more details.
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
17 *
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
18 * You should have received a copy of the GNU Lesser General Public
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
19 * License along with FFmpeg; if not, write to the Free Software
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
21 */
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
22
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
23 #include "dxva2.h"
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
24 #include "avcodec.h"
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
25
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
26 #include "mpegvideo.h"
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
27 #include "h264.h"
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
28 #include "h264data.h"
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
29
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
30 struct dxva2_picture_context {
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
31 DXVA_PicParams_H264 pp;
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
32 DXVA_Qmatrix_H264 qm;
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
33 unsigned slice_count;
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
34 DXVA_Slice_H264_Short slice_short[MAX_SLICES];
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
35 DXVA_Slice_H264_Long slice_long[MAX_SLICES];
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
36 const uint8_t *bitstream;
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
37 unsigned bitstream_size;
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
38 };
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
39
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
40 static void *get_surface(const Picture *picture)
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
41 {
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
42 return picture->data[3];
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
43 }
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
44 static unsigned get_surface_index(const struct dxva_context *ctx,
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
45 const Picture *picture)
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
46 {
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
47 void *surface = get_surface(picture);
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
48 unsigned i;
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
49
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
50 for (i = 0; i < ctx->surface_count; i++)
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
51 if (ctx->surface[i] == surface)
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
52 return i;
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
53
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
54 assert(0);
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
55 return 0;
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
56 }
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
57
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
58 static void fill_picture_entry(DXVA_PicEntry_H264 *pic,
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
59 unsigned index, unsigned flag)
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
60 {
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
61 assert((index&0x7f) == index && (flag&0x01) == flag);
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
62 pic->bPicEntry = index | (flag << 7);
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
63 }
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
64
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
65 static void fill_picture_parameters(struct dxva_context *ctx, const H264Context *h,
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
66 DXVA_PicParams_H264 *pp)
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
67 {
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
68 const MpegEncContext *s = &h->s;
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
69 const Picture *current_picture = s->current_picture_ptr;
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
70 int i;
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
71
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
72 memset(pp, 0, sizeof(*pp));
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
73 /* Configure current picture */
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
74 fill_picture_entry(&pp->CurrPic,
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
75 get_surface_index(ctx, current_picture),
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
76 s->picture_structure == PICT_BOTTOM_FIELD);
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
77 /* Configure the set of references */
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
78 pp->UsedForReferenceFlags = 0;
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
79 pp->NonExistingFrameFlags = 0;
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
80 for (i = 0; i < FF_ARRAY_ELEMS(pp->RefFrameList); i++) {
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
81 if (i < h->short_ref_count + h->long_ref_count) {
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
82 const Picture *r;
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
83 if (i < h->short_ref_count) {
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
84 r = h->short_ref[i];
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
85 assert(!r->long_ref);
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
86 } else {
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
87 r = h->long_ref[i - h->short_ref_count];
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
88 assert(r->long_ref);
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
89 }
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
90 fill_picture_entry(&pp->RefFrameList[i],
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
91 get_surface_index(ctx, r),
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
92 r->long_ref != 0);
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
93
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
94 if ((r->reference & PICT_TOP_FIELD) && r->field_poc[0] != INT_MAX)
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
95 pp->FieldOrderCntList[i][0] = r->field_poc[0];
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
96 if ((r->reference & PICT_BOTTOM_FIELD) && r->field_poc[1] != INT_MAX)
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
97 pp->FieldOrderCntList[i][1] = r->field_poc[1];
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
98
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
99 pp->FrameNumList[i] = r->long_ref ? r->pic_id : r->frame_num;
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
100 if (r->reference & PICT_TOP_FIELD)
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
101 pp->UsedForReferenceFlags |= 1 << (2*i + 0);
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
102 if (r->reference & PICT_BOTTOM_FIELD)
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
103 pp->UsedForReferenceFlags |= 1 << (2*i + 1);
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
104 } else {
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
105 pp->RefFrameList[i].bPicEntry = 0xff;
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
106 pp->FieldOrderCntList[i][0] = 0;
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
107 pp->FieldOrderCntList[i][1] = 0;
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
108 pp->FrameNumList[i] = 0;
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
109 }
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
110 }
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
111
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
112 pp->wFrameWidthInMbsMinus1 = s->mb_width - 1;
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
113 pp->wFrameHeightInMbsMinus1 = s->mb_height - 1;
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
114 pp->num_ref_frames = h->sps.ref_frame_count;
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
115
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
116 pp->wBitFields = ((s->picture_structure != PICT_FRAME) << 0) |
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
117 (h->sps.mb_aff << 1) |
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
118 (h->sps.residual_color_transform_flag << 2) |
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
119 /* sp_for_switch_flag (not implemented by FFmpeg) */
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
120 (0 << 3) |
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
121 (h->sps.chroma_format_idc << 4) |
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
122 ((h->nal_ref_idc != 0) << 6) |
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
123 (h->pps.constrained_intra_pred << 7) |
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
124 (h->pps.weighted_pred << 8) |
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
125 (h->pps.weighted_bipred_idc << 9) |
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
126 /* MbsConsecutiveFlag */
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
127 (1 << 11) |
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
128 (h->sps.frame_mbs_only_flag << 12) |
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
129 (h->pps.transform_8x8_mode << 13) |
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
130 ((h->sps.level_idc >= 31) << 14) |
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
131 /* IntraPicFlag (Modified if we detect a non
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
132 * intra slice in decode_slice) */
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
133 (1 << 15);
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
134
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
135 pp->bit_depth_luma_minus8 = h->sps.bit_depth_luma - 8;
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
136 pp->bit_depth_chroma_minus8 = h->sps.bit_depth_chroma - 8;
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
137 pp->Reserved16Bits = 3; /* FIXME is there a way to detect the right mode ? */
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
138 pp->StatusReportFeedbackNumber = 1 + ctx->report_id++;
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
139 pp->CurrFieldOrderCnt[0] = 0;
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
140 if ((s->picture_structure & PICT_TOP_FIELD) &&
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
141 current_picture->field_poc[0] != INT_MAX)
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
142 pp->CurrFieldOrderCnt[0] = current_picture->field_poc[0];
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
143 pp->CurrFieldOrderCnt[1] = 0;
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
144 if ((s->picture_structure & PICT_BOTTOM_FIELD) &&
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
145 current_picture->field_poc[1] != INT_MAX)
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
146 pp->CurrFieldOrderCnt[1] = current_picture->field_poc[1];
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
147 pp->pic_init_qs_minus26 = h->pps.init_qs - 26;
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
148 pp->chroma_qp_index_offset = h->pps.chroma_qp_index_offset[0];
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
149 pp->second_chroma_qp_index_offset = h->pps.chroma_qp_index_offset[1];
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
150 pp->ContinuationFlag = 1;
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
151 pp->pic_init_qp_minus26 = h->pps.init_qp - 26;
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
152 pp->num_ref_idx_l0_active_minus1 = h->pps.ref_count[0] - 1;
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
153 pp->num_ref_idx_l1_active_minus1 = h->pps.ref_count[1] - 1;
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
154 pp->Reserved8BitsA = 0;
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
155 pp->frame_num = h->frame_num;
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
156 pp->log2_max_frame_num_minus4 = h->sps.log2_max_frame_num - 4;
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
157 pp->pic_order_cnt_type = h->sps.poc_type;
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
158 if (h->sps.poc_type == 0)
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
159 pp->log2_max_pic_order_cnt_lsb_minus4 = h->sps.log2_max_poc_lsb - 4;
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
160 else if (h->sps.poc_type == 1)
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
161 pp->delta_pic_order_always_zero_flag = h->sps.delta_pic_order_always_zero_flag;
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
162 pp->direct_8x8_inference_flag = h->sps.direct_8x8_inference_flag;
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
163 pp->entropy_coding_mode_flag = h->pps.cabac;
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
164 pp->pic_order_present_flag = h->pps.pic_order_present;
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
165 pp->num_slice_groups_minus1 = h->pps.slice_group_count - 1;
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
166 pp->slice_group_map_type = h->pps.mb_slice_group_map_type;
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
167 pp->deblocking_filter_control_present_flag = h->pps.deblocking_filter_parameters_present;
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
168 pp->redundant_pic_cnt_present_flag= h->pps.redundant_pic_cnt_present;
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
169 pp->Reserved8BitsB = 0;
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
170 pp->slice_group_change_rate_minus1= 0; /* XXX not implemented by FFmpeg */
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
171 //pp->SliceGroupMap[810]; /* XXX not implemented by FFmpeg */
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
172 }
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
173
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
174 static void fill_scaling_lists(const H264Context *h, DXVA_Qmatrix_H264 *qm)
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
175 {
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
176 unsigned i, j;
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
177 memset(qm, 0, sizeof(*qm));
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
178 for (i = 0; i < 6; i++)
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
179 for (j = 0; j < 16; j++)
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
180 qm->bScalingLists4x4[i][j] = h->pps.scaling_matrix4[i][zigzag_scan[j]];
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
181
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
182 for (i = 0; i < 2; i++)
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
183 for (j = 0; j < 64; j++)
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
184 qm->bScalingLists8x8[i][j] = h->pps.scaling_matrix8[i][ff_zigzag_direct[j]];
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
185 }
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
186
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
187 static int is_slice_short(struct dxva_context *ctx)
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
188 {
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
189 assert(ctx->cfg->ConfigBitstreamRaw == 1 ||
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
190 ctx->cfg->ConfigBitstreamRaw == 2);
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
191 return ctx->cfg->ConfigBitstreamRaw == 2;
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
192 }
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
193
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
194 static void fill_slice_short(DXVA_Slice_H264_Short *slice,
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
195 unsigned position, unsigned size)
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
196 {
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
197 memset(slice, 0, sizeof(*slice));
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
198 slice->BSNALunitDataLocation = position;
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
199 slice->SliceBytesInBuffer = size;
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
200 slice->wBadSliceChopping = 0;
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
201 }
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
202
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
203 static void fill_slice_long(AVCodecContext *avctx, DXVA_Slice_H264_Long *slice,
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
204 unsigned position, unsigned size)
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
205 {
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
206 H264Context *h = avctx->priv_data; /* FIXME Can't use const because of get_bits_count */
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
207 struct dxva_context *ctx = avctx->hwaccel_context;
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
208 MpegEncContext *s = &h->s;
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
209 unsigned list;
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
210
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
211 memset(slice, 0, sizeof(*slice));
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
212 slice->BSNALunitDataLocation = position;
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
213 slice->SliceBytesInBuffer = size;
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
214 slice->wBadSliceChopping = 0;
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
215
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
216 slice->first_mb_in_slice = (s->mb_y >> FIELD_OR_MBAFF_PICTURE) * s->mb_width + s->mb_x;
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
217 slice->NumMbsForSlice = 0; /* XXX it is set once we have all slices */
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
218 slice->BitOffsetToSliceData = get_bits_count(&s->gb) + 8;
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
219 slice->slice_type = ff_h264_get_slice_type(h);
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
220 if (h->slice_type_fixed)
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
221 slice->slice_type += 5;
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
222 slice->luma_log2_weight_denom = h->luma_log2_weight_denom;
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
223 slice->chroma_log2_weight_denom = h->chroma_log2_weight_denom;
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
224 if (h->list_count > 0)
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
225 slice->num_ref_idx_l0_active_minus1 = h->ref_count[0] - 1;
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
226 if (h->list_count > 1)
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
227 slice->num_ref_idx_l1_active_minus1 = h->ref_count[1] - 1;
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
228 slice->slice_alpha_c0_offset_div2 = h->slice_alpha_c0_offset / 2;
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
229 slice->slice_beta_offset_div2 = h->slice_beta_offset / 2;
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
230 slice->Reserved8Bits = 0;
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
231
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
232 for (list = 0; list < 2; list++) {
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
233 unsigned i;
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
234 for (i = 0; i < FF_ARRAY_ELEMS(slice->RefPicList[list]); i++) {
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
235 if (list < h->list_count && i < h->ref_count[list]) {
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
236 const Picture *r = &h->ref_list[list][i];
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
237 unsigned plane;
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
238 fill_picture_entry(&slice->RefPicList[list][i],
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
239 get_surface_index(ctx, r),
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
240 r->reference == PICT_BOTTOM_FIELD);
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
241 for (plane = 0; plane < 3; plane++) {
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
242 int w, o;
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
243 if (plane == 0 && h->luma_weight_flag[list]) {
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
244 w = h->luma_weight[list][i];
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
245 o = h->luma_offset[list][i];
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
246 } else if (plane >= 1 && h->chroma_weight_flag[list]) {
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
247 w = h->chroma_weight[list][i][plane-1];
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
248 o = h->chroma_offset[list][i][plane-1];
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
249 } else {
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
250 w = 1 << (plane == 0 ? h->luma_log2_weight_denom :
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
251 h->chroma_log2_weight_denom);
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
252 o = 0;
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
253 }
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
254 slice->Weights[list][i][plane][0] = w;
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
255 slice->Weights[list][i][plane][1] = o;
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
256 }
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
257 } else {
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
258 unsigned plane;
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
259 slice->RefPicList[list][i].bPicEntry = 0xff;
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
260 for (plane = 0; plane < 3; plane++) {
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
261 slice->Weights[list][i][plane][0] = 0;
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
262 slice->Weights[list][i][plane][1] = 0;
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
263 }
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
264 }
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
265 }
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
266 }
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
267 slice->slice_qs_delta = 0; /* XXX not implemented by FFmpeg */
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
268 slice->slice_qp_delta = s->qscale - h->pps.init_qp;
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
269 slice->redundant_pic_cnt = h->redundant_pic_count;
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
270 if (h->slice_type == FF_B_TYPE)
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
271 slice->direct_spatial_mv_pred_flag = h->direct_spatial_mv_pred;
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
272 slice->cabac_init_idc = h->pps.cabac ? h->cabac_init_idc : 0;
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
273 if (h->deblocking_filter < 2)
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
274 slice->disable_deblocking_filter_idc = 1 - h->deblocking_filter;
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
275 else
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
276 slice->disable_deblocking_filter_idc = h->deblocking_filter;
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
277 slice->slice_id = h->current_slice - 1;
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
278 }
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
279
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
280 static int commit_buffer(AVCodecContext *avctx,
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
281 struct dxva_context *ctx,
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
282 DXVA2_DecodeBufferDesc *dsc,
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
283 unsigned type, const void *data, unsigned size,
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
284 unsigned mb_count)
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
285 {
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
286 void *dxva_data;
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
287 unsigned dxva_size;
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
288 int result;
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
289
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
290 if (FAILED(IDirectXVideoDecoder_GetBuffer(ctx->decoder, type,
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
291 &dxva_data, &dxva_size))) {
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
292 av_log(avctx, AV_LOG_ERROR, "Failed to get a buffer for %d\n", type);
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
293 return -1;
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
294 }
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
295 if (size <= dxva_size) {
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
296 memcpy(dxva_data, data, size);
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
297
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
298 memset(dsc, 0, sizeof(*dsc));
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
299 dsc->CompressedBufferType = type;
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
300 dsc->DataSize = size;
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
301 dsc->NumMBsInBuffer = mb_count;
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
302
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
303 result = 0;
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
304 } else {
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
305 av_log(avctx, AV_LOG_ERROR, "Buffer for type %d was too small\n", type);
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
306 result = -1;
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
307 }
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
308 if (FAILED(IDirectXVideoDecoder_ReleaseBuffer(ctx->decoder, type))) {
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
309 av_log(avctx, AV_LOG_ERROR, "Failed to release buffer type %d\n", type);
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
310 result = -1;
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
311 }
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
312 return result;
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
313 }
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
314
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
315 static int commit_bitstream_and_slice_buffer(AVCodecContext *avctx,
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
316 struct dxva_context *ctx,
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
317 struct dxva2_picture_context *ctx_pic,
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
318 DXVA2_DecodeBufferDesc *bs,
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
319 DXVA2_DecodeBufferDesc *sc,
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
320 unsigned mb_count)
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
321 {
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
322 DXVA_Slice_H264_Short *slice = NULL;
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
323 uint8_t *dxva_data, *current, *end;
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
324 unsigned dxva_size;
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
325 void *slice_data;
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
326 unsigned slice_size;
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
327 unsigned padding;
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
328 unsigned i;
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
329
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
330 /* Create an annex B bitstream buffer with only slice NAL and finalize slice */
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
331 if (FAILED(IDirectXVideoDecoder_GetBuffer(ctx->decoder,
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
332 DXVA2_BitStreamDateBufferType,
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
333 &dxva_data, &dxva_size)))
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
334 return -1;
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
335 current = dxva_data;
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
336 end = dxva_data + dxva_size;
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
337
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
338 for (i = 0; i < ctx_pic->slice_count; i++) {
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
339 static const uint8_t start_code[] = { 0, 0, 1 };
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
340 static const unsigned start_code_size = sizeof(start_code);
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
341 unsigned position, size;
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
342
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
343 assert(offsetof(DXVA_Slice_H264_Short, BSNALunitDataLocation) ==
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
344 offsetof(DXVA_Slice_H264_Long, BSNALunitDataLocation));
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
345 assert(offsetof(DXVA_Slice_H264_Short, SliceBytesInBuffer) ==
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
346 offsetof(DXVA_Slice_H264_Long, SliceBytesInBuffer));
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
347
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
348 if (is_slice_short(ctx))
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
349 slice = &ctx_pic->slice_short[i];
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
350 else
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
351 slice = (DXVA_Slice_H264_Short*)&ctx_pic->slice_long[i];
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
352
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
353 position = slice->BSNALunitDataLocation;
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
354 size = slice->SliceBytesInBuffer;
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
355 if (start_code_size + size > end - current) {
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
356 av_log(avctx, AV_LOG_ERROR, "Failed to build bitstream");
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
357 break;
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
358 }
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
359
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
360 slice->BSNALunitDataLocation = current - dxva_data;
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
361 slice->SliceBytesInBuffer = start_code_size + size;
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
362
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
363 if (!is_slice_short(ctx)) {
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
364 DXVA_Slice_H264_Long *slice_long = (DXVA_Slice_H264_Long*)slice;
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
365 if (i < ctx_pic->slice_count - 1)
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
366 slice_long->NumMbsForSlice =
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
367 slice_long[1].first_mb_in_slice - slice_long[0].first_mb_in_slice;
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
368 else
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
369 slice_long->NumMbsForSlice = mb_count - slice_long->first_mb_in_slice;
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
370 }
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
371
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
372 memcpy(current, start_code, start_code_size);
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
373 current += start_code_size;
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
374
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
375 memcpy(current, &ctx_pic->bitstream[position], size);
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
376 current += size;
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
377 }
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
378 padding = FFMIN(128 - ((current - dxva_data) & 127), end - current);
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
379 if (slice && padding > 0) {
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
380 memset(current, 0, padding);
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
381 current += padding;
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
382
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
383 slice->SliceBytesInBuffer += padding;
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
384 }
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
385 if (FAILED(IDirectXVideoDecoder_ReleaseBuffer(ctx->decoder,
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
386 DXVA2_BitStreamDateBufferType)))
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
387 return -1;
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
388 if (i < ctx_pic->slice_count)
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
389 return -1;
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
390
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
391 memset(bs, 0, sizeof(*bs));
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
392 bs->CompressedBufferType = DXVA2_BitStreamDateBufferType;
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
393 bs->DataSize = current - dxva_data;
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
394 bs->NumMBsInBuffer = mb_count;
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
395
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
396 if (is_slice_short(ctx)) {
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
397 slice_data = ctx_pic->slice_short;
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
398 slice_size = ctx_pic->slice_count * sizeof(*ctx_pic->slice_short);
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
399 } else {
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
400 slice_data = ctx_pic->slice_long;
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
401 slice_size = ctx_pic->slice_count * sizeof(*ctx_pic->slice_long);
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
402 }
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
403 assert((bs->DataSize & 127) == 0);
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
404 return commit_buffer(avctx, ctx, sc,
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
405 DXVA2_SliceControlBufferType,
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
406 slice_data, slice_size, mb_count);
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
407 }
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
408
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
409
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
410 static int start_frame(AVCodecContext *avctx,
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
411 av_unused const uint8_t *buffer,
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
412 av_unused uint32_t size)
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
413 {
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
414 const H264Context *h = avctx->priv_data;
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
415 struct dxva_context *ctx = avctx->hwaccel_context;
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
416 struct dxva2_picture_context *ctx_pic = h->s.current_picture_ptr->hwaccel_picture_private;
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
417
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
418 if (!ctx->decoder || !ctx->cfg || ctx->surface_count <= 0)
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
419 return -1;
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
420 assert(ctx_pic);
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
421
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
422 /* Fill up DXVA_PicParams_H264 */
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
423 fill_picture_parameters(ctx, h, &ctx_pic->pp);
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
424
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
425 /* Fill up DXVA_Qmatrix_H264 */
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
426 fill_scaling_lists(h, &ctx_pic->qm);
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
427
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
428 ctx_pic->slice_count = 0;
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
429 ctx_pic->bitstream_size = 0;
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
430 ctx_pic->bitstream = NULL;
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
431 return 0;
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
432 }
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
433
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
434 static int decode_slice(AVCodecContext *avctx,
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
435 const uint8_t *buffer, uint32_t size)
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
436 {
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
437 H264Context *h = avctx->priv_data; /* FIXME Can't use const because of get_bits_count */
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
438 struct dxva_context *ctx = avctx->hwaccel_context;
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
439 const Picture *current_picture = h->s.current_picture_ptr;
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
440 struct dxva2_picture_context *ctx_pic = current_picture->hwaccel_picture_private;
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
441 unsigned position;
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
442
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
443 if (ctx_pic->slice_count >= MAX_SLICES)
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
444 return -1;
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
445
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
446 if (!ctx_pic->bitstream)
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
447 ctx_pic->bitstream = buffer;
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
448 ctx_pic->bitstream_size += size;
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
449
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
450 position = buffer - ctx_pic->bitstream;
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
451 if (is_slice_short(ctx))
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
452 fill_slice_short(&ctx_pic->slice_short[ctx_pic->slice_count],
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
453 position, size);
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
454 else
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
455 fill_slice_long(avctx, &ctx_pic->slice_long[ctx_pic->slice_count],
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
456 position, size);
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
457 ctx_pic->slice_count++;
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
458
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
459 if (h->slice_type != FF_I_TYPE && h->slice_type != FF_SI_TYPE)
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
460 ctx_pic->pp.wBitFields &= ~(1 << 15); /* Set IntraPicFlag to 0 */
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
461 return 0;
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
462 }
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
463
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
464 static int end_frame(AVCodecContext *avctx)
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
465 {
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
466 H264Context *h = avctx->priv_data;
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
467 MpegEncContext *s = &h->s;
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
468 const unsigned mb_count = s->mb_width * s->mb_height;
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
469 struct dxva_context *ctx = avctx->hwaccel_context;
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
470 const Picture *current_picture = h->s.current_picture_ptr;
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
471 struct dxva2_picture_context *ctx_pic = current_picture->hwaccel_picture_private;
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
472 unsigned buffer_count = 0;
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
473 DXVA2_DecodeBufferDesc buffer[4];
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
474 DXVA2_DecodeExecuteParams exec;
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
475 int result;
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
476
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
477 if (ctx_pic->slice_count <= 0 || ctx_pic->bitstream_size <= 0)
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
478 return -1;
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
479
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
480 if (FAILED(IDirectXVideoDecoder_BeginFrame(ctx->decoder,
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
481 get_surface(current_picture),
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
482 NULL))) {
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
483 av_log(avctx, AV_LOG_ERROR, "Failed to begin frame\n");
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
484 return -1;
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
485 }
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
486
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
487 result = commit_buffer(avctx, ctx, &buffer[buffer_count],
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
488 DXVA2_PictureParametersBufferType,
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
489 &ctx_pic->pp, sizeof(ctx_pic->pp), 0);
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
490 if (result) {
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
491 av_log(avctx, AV_LOG_ERROR,
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
492 "Failed to add picture parameter buffer\n");
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
493 goto end;
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
494 }
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
495 buffer_count++;
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
496
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
497 result = commit_buffer(avctx, ctx, &buffer[buffer_count],
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
498 DXVA2_InverseQuantizationMatrixBufferType,
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
499 &ctx_pic->qm, sizeof(ctx_pic->qm), 0);
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
500 if (result) {
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
501 av_log(avctx, AV_LOG_ERROR,
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
502 "Failed to add inverse quantization matrix buffer\n");
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
503 goto end;
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
504 }
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
505 buffer_count++;
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
506
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
507 result = commit_bitstream_and_slice_buffer(avctx, ctx, ctx_pic,
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
508 &buffer[buffer_count + 0],
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
509 &buffer[buffer_count + 1],
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
510 mb_count);
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
511 if (result) {
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
512 av_log(avctx, AV_LOG_ERROR,
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
513 "Failed to add bitstream or slice control buffer\n");
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
514 goto end;
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
515 }
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
516 buffer_count += 2;
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
517
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
518 /* TODO Film Grain when possible */
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
519
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
520 assert(buffer_count == 4);
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
521
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
522 memset(&exec, 0, sizeof(exec));
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
523 exec.NumCompBuffers = buffer_count;
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
524 exec.pCompressedBuffers = buffer;
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
525 exec.pExtensionData = NULL;
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
526 if (FAILED(IDirectXVideoDecoder_Execute(ctx->decoder, &exec))) {
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
527 av_log(avctx, AV_LOG_ERROR, "Failed to execute\n");
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
528 result = -1;
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
529 }
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
530
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
531 end:
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
532 if (FAILED(IDirectXVideoDecoder_EndFrame(ctx->decoder, NULL))) {
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
533 av_log(avctx, AV_LOG_ERROR, "Failed to end frame\n");
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
534 result = -1;
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
535 }
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
536
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
537 if (!result)
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
538 ff_draw_horiz_band(s, 0, s->avctx->height);
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
539 return result;
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
540 }
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
541
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
542 AVHWAccel h264_dxva2_hwaccel = {
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
543 .name = "h264_dxva2",
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
544 .type = CODEC_TYPE_VIDEO,
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
545 .id = CODEC_ID_H264,
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
546 .pix_fmt = PIX_FMT_DXVA2_VLD,
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
547 .capabilities = 0,
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
548 .start_frame = start_frame,
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
549 .decode_slice = decode_slice,
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
550 .end_frame = end_frame,
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
551 .priv_data_size = sizeof(struct dxva2_picture_context),
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
552 };
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
553