annotate dxva2_vc1.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
10990
a6908ae0e0b5 VC-1/WMV3 DXVA2 implementation
fenrir
parents:
diff changeset
1 /*
a6908ae0e0b5 VC-1/WMV3 DXVA2 implementation
fenrir
parents:
diff changeset
2 * DXVA2 WMV3/VC-1 HW acceleration.
a6908ae0e0b5 VC-1/WMV3 DXVA2 implementation
fenrir
parents:
diff changeset
3 *
a6908ae0e0b5 VC-1/WMV3 DXVA2 implementation
fenrir
parents:
diff changeset
4 * copyright (c) 2010 Laurent Aimar
a6908ae0e0b5 VC-1/WMV3 DXVA2 implementation
fenrir
parents:
diff changeset
5 *
a6908ae0e0b5 VC-1/WMV3 DXVA2 implementation
fenrir
parents:
diff changeset
6 * This file is part of FFmpeg.
a6908ae0e0b5 VC-1/WMV3 DXVA2 implementation
fenrir
parents:
diff changeset
7 *
a6908ae0e0b5 VC-1/WMV3 DXVA2 implementation
fenrir
parents:
diff changeset
8 * FFmpeg is free software; you can redistribute it and/or
a6908ae0e0b5 VC-1/WMV3 DXVA2 implementation
fenrir
parents:
diff changeset
9 * modify it under the terms of the GNU Lesser General Public
a6908ae0e0b5 VC-1/WMV3 DXVA2 implementation
fenrir
parents:
diff changeset
10 * License as published by the Free Software Foundation; either
a6908ae0e0b5 VC-1/WMV3 DXVA2 implementation
fenrir
parents:
diff changeset
11 * version 2.1 of the License, or (at your option) any later version.
a6908ae0e0b5 VC-1/WMV3 DXVA2 implementation
fenrir
parents:
diff changeset
12 *
a6908ae0e0b5 VC-1/WMV3 DXVA2 implementation
fenrir
parents:
diff changeset
13 * FFmpeg is distributed in the hope that it will be useful,
a6908ae0e0b5 VC-1/WMV3 DXVA2 implementation
fenrir
parents:
diff changeset
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
a6908ae0e0b5 VC-1/WMV3 DXVA2 implementation
fenrir
parents:
diff changeset
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
a6908ae0e0b5 VC-1/WMV3 DXVA2 implementation
fenrir
parents:
diff changeset
16 * Lesser General Public License for more details.
a6908ae0e0b5 VC-1/WMV3 DXVA2 implementation
fenrir
parents:
diff changeset
17 *
a6908ae0e0b5 VC-1/WMV3 DXVA2 implementation
fenrir
parents:
diff changeset
18 * You should have received a copy of the GNU Lesser General Public
a6908ae0e0b5 VC-1/WMV3 DXVA2 implementation
fenrir
parents:
diff changeset
19 * License along with FFmpeg; if not, write to the Free Software
a6908ae0e0b5 VC-1/WMV3 DXVA2 implementation
fenrir
parents:
diff changeset
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
a6908ae0e0b5 VC-1/WMV3 DXVA2 implementation
fenrir
parents:
diff changeset
21 */
a6908ae0e0b5 VC-1/WMV3 DXVA2 implementation
fenrir
parents:
diff changeset
22
a6908ae0e0b5 VC-1/WMV3 DXVA2 implementation
fenrir
parents:
diff changeset
23 #include "dxva2_internal.h"
a6908ae0e0b5 VC-1/WMV3 DXVA2 implementation
fenrir
parents:
diff changeset
24 #include "vc1.h"
a6908ae0e0b5 VC-1/WMV3 DXVA2 implementation
fenrir
parents:
diff changeset
25 #include "vc1data.h"
a6908ae0e0b5 VC-1/WMV3 DXVA2 implementation
fenrir
parents:
diff changeset
26
a6908ae0e0b5 VC-1/WMV3 DXVA2 implementation
fenrir
parents:
diff changeset
27 struct dxva2_picture_context {
a6908ae0e0b5 VC-1/WMV3 DXVA2 implementation
fenrir
parents:
diff changeset
28 DXVA_PictureParameters pp;
a6908ae0e0b5 VC-1/WMV3 DXVA2 implementation
fenrir
parents:
diff changeset
29 DXVA_SliceInfo si;
a6908ae0e0b5 VC-1/WMV3 DXVA2 implementation
fenrir
parents:
diff changeset
30
a6908ae0e0b5 VC-1/WMV3 DXVA2 implementation
fenrir
parents:
diff changeset
31 const uint8_t *bitstream;
a6908ae0e0b5 VC-1/WMV3 DXVA2 implementation
fenrir
parents:
diff changeset
32 unsigned bitstream_size;
a6908ae0e0b5 VC-1/WMV3 DXVA2 implementation
fenrir
parents:
diff changeset
33 };
a6908ae0e0b5 VC-1/WMV3 DXVA2 implementation
fenrir
parents:
diff changeset
34
a6908ae0e0b5 VC-1/WMV3 DXVA2 implementation
fenrir
parents:
diff changeset
35 static void fill_picture_parameters(AVCodecContext *avctx,
a6908ae0e0b5 VC-1/WMV3 DXVA2 implementation
fenrir
parents:
diff changeset
36 struct dxva_context *ctx, const VC1Context *v,
a6908ae0e0b5 VC-1/WMV3 DXVA2 implementation
fenrir
parents:
diff changeset
37 DXVA_PictureParameters *pp)
a6908ae0e0b5 VC-1/WMV3 DXVA2 implementation
fenrir
parents:
diff changeset
38 {
a6908ae0e0b5 VC-1/WMV3 DXVA2 implementation
fenrir
parents:
diff changeset
39 const MpegEncContext *s = &v->s;
a6908ae0e0b5 VC-1/WMV3 DXVA2 implementation
fenrir
parents:
diff changeset
40 const Picture *current_picture = s->current_picture_ptr;
a6908ae0e0b5 VC-1/WMV3 DXVA2 implementation
fenrir
parents:
diff changeset
41
a6908ae0e0b5 VC-1/WMV3 DXVA2 implementation
fenrir
parents:
diff changeset
42 memset(pp, 0, sizeof(*pp));
a6908ae0e0b5 VC-1/WMV3 DXVA2 implementation
fenrir
parents:
diff changeset
43 pp->wDecodedPictureIndex =
a6908ae0e0b5 VC-1/WMV3 DXVA2 implementation
fenrir
parents:
diff changeset
44 pp->wDeblockedPictureIndex = ff_dxva2_get_surface_index(ctx, current_picture);
a6908ae0e0b5 VC-1/WMV3 DXVA2 implementation
fenrir
parents:
diff changeset
45 if (s->pict_type != FF_I_TYPE)
a6908ae0e0b5 VC-1/WMV3 DXVA2 implementation
fenrir
parents:
diff changeset
46 pp->wForwardRefPictureIndex = ff_dxva2_get_surface_index(ctx, &s->last_picture);
a6908ae0e0b5 VC-1/WMV3 DXVA2 implementation
fenrir
parents:
diff changeset
47 else
a6908ae0e0b5 VC-1/WMV3 DXVA2 implementation
fenrir
parents:
diff changeset
48 pp->wForwardRefPictureIndex = 0xffff;
a6908ae0e0b5 VC-1/WMV3 DXVA2 implementation
fenrir
parents:
diff changeset
49 if (s->pict_type == FF_B_TYPE)
a6908ae0e0b5 VC-1/WMV3 DXVA2 implementation
fenrir
parents:
diff changeset
50 pp->wBackwardRefPictureIndex = ff_dxva2_get_surface_index(ctx, &s->next_picture);
a6908ae0e0b5 VC-1/WMV3 DXVA2 implementation
fenrir
parents:
diff changeset
51 else
a6908ae0e0b5 VC-1/WMV3 DXVA2 implementation
fenrir
parents:
diff changeset
52 pp->wBackwardRefPictureIndex = 0xffff;
a6908ae0e0b5 VC-1/WMV3 DXVA2 implementation
fenrir
parents:
diff changeset
53 if (v->profile == PROFILE_ADVANCED) {
a6908ae0e0b5 VC-1/WMV3 DXVA2 implementation
fenrir
parents:
diff changeset
54 /* It is the cropped width/height -1 of the frame */
a6908ae0e0b5 VC-1/WMV3 DXVA2 implementation
fenrir
parents:
diff changeset
55 pp->wPicWidthInMBminus1 = avctx->width - 1;
a6908ae0e0b5 VC-1/WMV3 DXVA2 implementation
fenrir
parents:
diff changeset
56 pp->wPicHeightInMBminus1= avctx->height - 1;
a6908ae0e0b5 VC-1/WMV3 DXVA2 implementation
fenrir
parents:
diff changeset
57 } else {
a6908ae0e0b5 VC-1/WMV3 DXVA2 implementation
fenrir
parents:
diff changeset
58 /* It is the coded width/height in macroblock -1 of the frame */
a6908ae0e0b5 VC-1/WMV3 DXVA2 implementation
fenrir
parents:
diff changeset
59 pp->wPicWidthInMBminus1 = s->mb_width - 1;
a6908ae0e0b5 VC-1/WMV3 DXVA2 implementation
fenrir
parents:
diff changeset
60 pp->wPicHeightInMBminus1= s->mb_height - 1;
a6908ae0e0b5 VC-1/WMV3 DXVA2 implementation
fenrir
parents:
diff changeset
61 }
a6908ae0e0b5 VC-1/WMV3 DXVA2 implementation
fenrir
parents:
diff changeset
62 pp->bMacroblockWidthMinus1 = 15;
a6908ae0e0b5 VC-1/WMV3 DXVA2 implementation
fenrir
parents:
diff changeset
63 pp->bMacroblockHeightMinus1 = 15;
a6908ae0e0b5 VC-1/WMV3 DXVA2 implementation
fenrir
parents:
diff changeset
64 pp->bBlockWidthMinus1 = 7;
a6908ae0e0b5 VC-1/WMV3 DXVA2 implementation
fenrir
parents:
diff changeset
65 pp->bBlockHeightMinus1 = 7;
a6908ae0e0b5 VC-1/WMV3 DXVA2 implementation
fenrir
parents:
diff changeset
66 pp->bBPPminus1 = 7;
a6908ae0e0b5 VC-1/WMV3 DXVA2 implementation
fenrir
parents:
diff changeset
67 if (s->picture_structure & PICT_TOP_FIELD)
a6908ae0e0b5 VC-1/WMV3 DXVA2 implementation
fenrir
parents:
diff changeset
68 pp->bPicStructure |= 0x01;
a6908ae0e0b5 VC-1/WMV3 DXVA2 implementation
fenrir
parents:
diff changeset
69 if (s->picture_structure & PICT_BOTTOM_FIELD)
a6908ae0e0b5 VC-1/WMV3 DXVA2 implementation
fenrir
parents:
diff changeset
70 pp->bPicStructure |= 0x02;
a6908ae0e0b5 VC-1/WMV3 DXVA2 implementation
fenrir
parents:
diff changeset
71 pp->bSecondField = v->interlace && v->fcm != 0x03 && !s->first_field;
a6908ae0e0b5 VC-1/WMV3 DXVA2 implementation
fenrir
parents:
diff changeset
72 pp->bPicIntra = s->pict_type == FF_I_TYPE;
a6908ae0e0b5 VC-1/WMV3 DXVA2 implementation
fenrir
parents:
diff changeset
73 pp->bPicBackwardPrediction = s->pict_type == FF_B_TYPE;
a6908ae0e0b5 VC-1/WMV3 DXVA2 implementation
fenrir
parents:
diff changeset
74 pp->bBidirectionalAveragingMode = (1 << 7) |
a6908ae0e0b5 VC-1/WMV3 DXVA2 implementation
fenrir
parents:
diff changeset
75 ((ctx->cfg->ConfigIntraResidUnsigned != 0) << 6) |
a6908ae0e0b5 VC-1/WMV3 DXVA2 implementation
fenrir
parents:
diff changeset
76 ((ctx->cfg->ConfigResidDiffAccelerator != 0) << 5) |
a6908ae0e0b5 VC-1/WMV3 DXVA2 implementation
fenrir
parents:
diff changeset
77 ((v->lumscale != 32 || v->lumshift != 0) << 4) |
a6908ae0e0b5 VC-1/WMV3 DXVA2 implementation
fenrir
parents:
diff changeset
78 ((v->profile == PROFILE_ADVANCED) << 3);
a6908ae0e0b5 VC-1/WMV3 DXVA2 implementation
fenrir
parents:
diff changeset
79 pp->bMVprecisionAndChromaRelation = ((v->mv_mode == MV_PMODE_1MV_HPEL_BILIN) << 3) |
a6908ae0e0b5 VC-1/WMV3 DXVA2 implementation
fenrir
parents:
diff changeset
80 (1 << 2) |
a6908ae0e0b5 VC-1/WMV3 DXVA2 implementation
fenrir
parents:
diff changeset
81 (0 << 1) |
a6908ae0e0b5 VC-1/WMV3 DXVA2 implementation
fenrir
parents:
diff changeset
82 (!s->quarter_sample );
a6908ae0e0b5 VC-1/WMV3 DXVA2 implementation
fenrir
parents:
diff changeset
83 pp->bChromaFormat = v->chromaformat;
a6908ae0e0b5 VC-1/WMV3 DXVA2 implementation
fenrir
parents:
diff changeset
84 ctx->report_id++;
a6908ae0e0b5 VC-1/WMV3 DXVA2 implementation
fenrir
parents:
diff changeset
85 if (ctx->report_id >= (1 << 16))
a6908ae0e0b5 VC-1/WMV3 DXVA2 implementation
fenrir
parents:
diff changeset
86 ctx->report_id = 1;
a6908ae0e0b5 VC-1/WMV3 DXVA2 implementation
fenrir
parents:
diff changeset
87 pp->bPicScanFixed = ctx->report_id >> 8;
a6908ae0e0b5 VC-1/WMV3 DXVA2 implementation
fenrir
parents:
diff changeset
88 pp->bPicScanMethod = ctx->report_id & 0xff;
a6908ae0e0b5 VC-1/WMV3 DXVA2 implementation
fenrir
parents:
diff changeset
89 pp->bPicReadbackRequests = 0;
a6908ae0e0b5 VC-1/WMV3 DXVA2 implementation
fenrir
parents:
diff changeset
90 pp->bRcontrol = v->rnd;
a6908ae0e0b5 VC-1/WMV3 DXVA2 implementation
fenrir
parents:
diff changeset
91 pp->bPicSpatialResid8 = (v->panscanflag << 7) |
a6908ae0e0b5 VC-1/WMV3 DXVA2 implementation
fenrir
parents:
diff changeset
92 (v->refdist_flag << 6) |
a6908ae0e0b5 VC-1/WMV3 DXVA2 implementation
fenrir
parents:
diff changeset
93 (s->loop_filter << 5) |
a6908ae0e0b5 VC-1/WMV3 DXVA2 implementation
fenrir
parents:
diff changeset
94 (v->fastuvmc << 4) |
a6908ae0e0b5 VC-1/WMV3 DXVA2 implementation
fenrir
parents:
diff changeset
95 (v->extended_mv << 3) |
a6908ae0e0b5 VC-1/WMV3 DXVA2 implementation
fenrir
parents:
diff changeset
96 (v->dquant << 1) |
a6908ae0e0b5 VC-1/WMV3 DXVA2 implementation
fenrir
parents:
diff changeset
97 (v->vstransform );
a6908ae0e0b5 VC-1/WMV3 DXVA2 implementation
fenrir
parents:
diff changeset
98 pp->bPicOverflowBlocks = (v->quantizer_mode << 6) |
a6908ae0e0b5 VC-1/WMV3 DXVA2 implementation
fenrir
parents:
diff changeset
99 (v->multires << 5) |
a6908ae0e0b5 VC-1/WMV3 DXVA2 implementation
fenrir
parents:
diff changeset
100 (s->resync_marker << 4) |
a6908ae0e0b5 VC-1/WMV3 DXVA2 implementation
fenrir
parents:
diff changeset
101 (v->rangered << 3) |
a6908ae0e0b5 VC-1/WMV3 DXVA2 implementation
fenrir
parents:
diff changeset
102 (s->max_b_frames );
a6908ae0e0b5 VC-1/WMV3 DXVA2 implementation
fenrir
parents:
diff changeset
103 pp->bPicExtrapolation = (!v->interlace || v->fcm == 0x00) ? 1 : 2;
a6908ae0e0b5 VC-1/WMV3 DXVA2 implementation
fenrir
parents:
diff changeset
104 pp->bPicDeblocked = ((v->profile != PROFILE_ADVANCED && v->rangeredfrm) << 5) |
a6908ae0e0b5 VC-1/WMV3 DXVA2 implementation
fenrir
parents:
diff changeset
105 (s->loop_filter << 1);
a6908ae0e0b5 VC-1/WMV3 DXVA2 implementation
fenrir
parents:
diff changeset
106 pp->bPicDeblockConfined = (v->postprocflag << 7) |
a6908ae0e0b5 VC-1/WMV3 DXVA2 implementation
fenrir
parents:
diff changeset
107 (v->broadcast << 6) |
a6908ae0e0b5 VC-1/WMV3 DXVA2 implementation
fenrir
parents:
diff changeset
108 (v->interlace << 5) |
a6908ae0e0b5 VC-1/WMV3 DXVA2 implementation
fenrir
parents:
diff changeset
109 (v->tfcntrflag << 4) |
a6908ae0e0b5 VC-1/WMV3 DXVA2 implementation
fenrir
parents:
diff changeset
110 (v->finterpflag << 3) |
a6908ae0e0b5 VC-1/WMV3 DXVA2 implementation
fenrir
parents:
diff changeset
111 ((s->pict_type != FF_B_TYPE) << 2) |
a6908ae0e0b5 VC-1/WMV3 DXVA2 implementation
fenrir
parents:
diff changeset
112 (v->psf << 1) |
a6908ae0e0b5 VC-1/WMV3 DXVA2 implementation
fenrir
parents:
diff changeset
113 (v->extended_dmv );
a6908ae0e0b5 VC-1/WMV3 DXVA2 implementation
fenrir
parents:
diff changeset
114 if (s->pict_type != FF_I_TYPE)
a6908ae0e0b5 VC-1/WMV3 DXVA2 implementation
fenrir
parents:
diff changeset
115 pp->bPic4MVallowed = v->mv_mode == MV_PMODE_MIXED_MV ||
a6908ae0e0b5 VC-1/WMV3 DXVA2 implementation
fenrir
parents:
diff changeset
116 (v->mv_mode == MV_PMODE_INTENSITY_COMP &&
a6908ae0e0b5 VC-1/WMV3 DXVA2 implementation
fenrir
parents:
diff changeset
117 v->mv_mode2 == MV_PMODE_MIXED_MV);
a6908ae0e0b5 VC-1/WMV3 DXVA2 implementation
fenrir
parents:
diff changeset
118 if (v->profile == PROFILE_ADVANCED)
a6908ae0e0b5 VC-1/WMV3 DXVA2 implementation
fenrir
parents:
diff changeset
119 pp->bPicOBMC = (v->range_mapy_flag << 7) |
a6908ae0e0b5 VC-1/WMV3 DXVA2 implementation
fenrir
parents:
diff changeset
120 (v->range_mapy << 4) |
a6908ae0e0b5 VC-1/WMV3 DXVA2 implementation
fenrir
parents:
diff changeset
121 (v->range_mapuv_flag << 3) |
a6908ae0e0b5 VC-1/WMV3 DXVA2 implementation
fenrir
parents:
diff changeset
122 (v->range_mapuv );
a6908ae0e0b5 VC-1/WMV3 DXVA2 implementation
fenrir
parents:
diff changeset
123 pp->bPicBinPB = 0;
a6908ae0e0b5 VC-1/WMV3 DXVA2 implementation
fenrir
parents:
diff changeset
124 pp->bMV_RPS = 0;
a6908ae0e0b5 VC-1/WMV3 DXVA2 implementation
fenrir
parents:
diff changeset
125 pp->bReservedBits = 0;
a6908ae0e0b5 VC-1/WMV3 DXVA2 implementation
fenrir
parents:
diff changeset
126 if (s->picture_structure == PICT_FRAME) {
a6908ae0e0b5 VC-1/WMV3 DXVA2 implementation
fenrir
parents:
diff changeset
127 pp->wBitstreamFcodes = v->lumscale;
a6908ae0e0b5 VC-1/WMV3 DXVA2 implementation
fenrir
parents:
diff changeset
128 pp->wBitstreamPCEelements = v->lumshift;
a6908ae0e0b5 VC-1/WMV3 DXVA2 implementation
fenrir
parents:
diff changeset
129 } else {
a6908ae0e0b5 VC-1/WMV3 DXVA2 implementation
fenrir
parents:
diff changeset
130 /* Syntax: (top_field_param << 8) | bottom_field_param */
a6908ae0e0b5 VC-1/WMV3 DXVA2 implementation
fenrir
parents:
diff changeset
131 pp->wBitstreamFcodes = (v->lumscale << 8) | v->lumscale;
a6908ae0e0b5 VC-1/WMV3 DXVA2 implementation
fenrir
parents:
diff changeset
132 pp->wBitstreamPCEelements = (v->lumshift << 8) | v->lumshift;
a6908ae0e0b5 VC-1/WMV3 DXVA2 implementation
fenrir
parents:
diff changeset
133 }
a6908ae0e0b5 VC-1/WMV3 DXVA2 implementation
fenrir
parents:
diff changeset
134 pp->bBitstreamConcealmentNeed = 0;
a6908ae0e0b5 VC-1/WMV3 DXVA2 implementation
fenrir
parents:
diff changeset
135 pp->bBitstreamConcealmentMethod = 0;
a6908ae0e0b5 VC-1/WMV3 DXVA2 implementation
fenrir
parents:
diff changeset
136 }
a6908ae0e0b5 VC-1/WMV3 DXVA2 implementation
fenrir
parents:
diff changeset
137
a6908ae0e0b5 VC-1/WMV3 DXVA2 implementation
fenrir
parents:
diff changeset
138 static void fill_slice(AVCodecContext *avctx, DXVA_SliceInfo *slice,
a6908ae0e0b5 VC-1/WMV3 DXVA2 implementation
fenrir
parents:
diff changeset
139 unsigned position, unsigned size)
a6908ae0e0b5 VC-1/WMV3 DXVA2 implementation
fenrir
parents:
diff changeset
140 {
a6908ae0e0b5 VC-1/WMV3 DXVA2 implementation
fenrir
parents:
diff changeset
141 const VC1Context *v = avctx->priv_data;
a6908ae0e0b5 VC-1/WMV3 DXVA2 implementation
fenrir
parents:
diff changeset
142 const MpegEncContext *s = &v->s;
a6908ae0e0b5 VC-1/WMV3 DXVA2 implementation
fenrir
parents:
diff changeset
143
a6908ae0e0b5 VC-1/WMV3 DXVA2 implementation
fenrir
parents:
diff changeset
144 memset(slice, 0, sizeof(*slice));
a6908ae0e0b5 VC-1/WMV3 DXVA2 implementation
fenrir
parents:
diff changeset
145 slice->wHorizontalPosition = 0;
a6908ae0e0b5 VC-1/WMV3 DXVA2 implementation
fenrir
parents:
diff changeset
146 slice->wVerticalPosition = s->mb_y;
a6908ae0e0b5 VC-1/WMV3 DXVA2 implementation
fenrir
parents:
diff changeset
147 slice->dwSliceBitsInBuffer = 8 * size;
a6908ae0e0b5 VC-1/WMV3 DXVA2 implementation
fenrir
parents:
diff changeset
148 slice->dwSliceDataLocation = position;
a6908ae0e0b5 VC-1/WMV3 DXVA2 implementation
fenrir
parents:
diff changeset
149 slice->bStartCodeBitOffset = 0;
a6908ae0e0b5 VC-1/WMV3 DXVA2 implementation
fenrir
parents:
diff changeset
150 slice->bReservedBits = 0;
a6908ae0e0b5 VC-1/WMV3 DXVA2 implementation
fenrir
parents:
diff changeset
151 slice->wMBbitOffset = get_bits_count(&s->gb);
a6908ae0e0b5 VC-1/WMV3 DXVA2 implementation
fenrir
parents:
diff changeset
152 slice->wNumberMBsInSlice = s->mb_width * s->mb_height; /* XXX We assume 1 slice */
a6908ae0e0b5 VC-1/WMV3 DXVA2 implementation
fenrir
parents:
diff changeset
153 slice->wQuantizerScaleCode = v->pq;
a6908ae0e0b5 VC-1/WMV3 DXVA2 implementation
fenrir
parents:
diff changeset
154 slice->wBadSliceChopping = 0;
a6908ae0e0b5 VC-1/WMV3 DXVA2 implementation
fenrir
parents:
diff changeset
155 }
a6908ae0e0b5 VC-1/WMV3 DXVA2 implementation
fenrir
parents:
diff changeset
156
a6908ae0e0b5 VC-1/WMV3 DXVA2 implementation
fenrir
parents:
diff changeset
157 static int commit_bitstream_and_slice_buffer(AVCodecContext *avctx,
a6908ae0e0b5 VC-1/WMV3 DXVA2 implementation
fenrir
parents:
diff changeset
158 DXVA2_DecodeBufferDesc *bs,
a6908ae0e0b5 VC-1/WMV3 DXVA2 implementation
fenrir
parents:
diff changeset
159 DXVA2_DecodeBufferDesc *sc)
a6908ae0e0b5 VC-1/WMV3 DXVA2 implementation
fenrir
parents:
diff changeset
160 {
a6908ae0e0b5 VC-1/WMV3 DXVA2 implementation
fenrir
parents:
diff changeset
161 const VC1Context *v = avctx->priv_data;
a6908ae0e0b5 VC-1/WMV3 DXVA2 implementation
fenrir
parents:
diff changeset
162 struct dxva_context *ctx = avctx->hwaccel_context;
a6908ae0e0b5 VC-1/WMV3 DXVA2 implementation
fenrir
parents:
diff changeset
163 const MpegEncContext *s = &v->s;
a6908ae0e0b5 VC-1/WMV3 DXVA2 implementation
fenrir
parents:
diff changeset
164 struct dxva2_picture_context *ctx_pic = s->current_picture_ptr->hwaccel_picture_private;
a6908ae0e0b5 VC-1/WMV3 DXVA2 implementation
fenrir
parents:
diff changeset
165
a6908ae0e0b5 VC-1/WMV3 DXVA2 implementation
fenrir
parents:
diff changeset
166 DXVA_SliceInfo *slice = &ctx_pic->si;
a6908ae0e0b5 VC-1/WMV3 DXVA2 implementation
fenrir
parents:
diff changeset
167
a6908ae0e0b5 VC-1/WMV3 DXVA2 implementation
fenrir
parents:
diff changeset
168 static const uint8_t start_code[] = { 0, 0, 1, 0x0d };
a6908ae0e0b5 VC-1/WMV3 DXVA2 implementation
fenrir
parents:
diff changeset
169 const unsigned start_code_size = avctx->codec_id == CODEC_ID_VC1 ? sizeof(start_code) : 0;
a6908ae0e0b5 VC-1/WMV3 DXVA2 implementation
fenrir
parents:
diff changeset
170 const unsigned slice_size = slice->dwSliceBitsInBuffer / 8;
a6908ae0e0b5 VC-1/WMV3 DXVA2 implementation
fenrir
parents:
diff changeset
171 const unsigned padding = 128 - ((start_code_size + slice_size) & 127);
a6908ae0e0b5 VC-1/WMV3 DXVA2 implementation
fenrir
parents:
diff changeset
172 const unsigned data_size = start_code_size + slice_size + padding;
a6908ae0e0b5 VC-1/WMV3 DXVA2 implementation
fenrir
parents:
diff changeset
173
a6908ae0e0b5 VC-1/WMV3 DXVA2 implementation
fenrir
parents:
diff changeset
174 uint8_t *dxva_data;
a6908ae0e0b5 VC-1/WMV3 DXVA2 implementation
fenrir
parents:
diff changeset
175 unsigned dxva_size;
a6908ae0e0b5 VC-1/WMV3 DXVA2 implementation
fenrir
parents:
diff changeset
176 int result;
a6908ae0e0b5 VC-1/WMV3 DXVA2 implementation
fenrir
parents:
diff changeset
177
a6908ae0e0b5 VC-1/WMV3 DXVA2 implementation
fenrir
parents:
diff changeset
178 if (FAILED(IDirectXVideoDecoder_GetBuffer(ctx->decoder,
a6908ae0e0b5 VC-1/WMV3 DXVA2 implementation
fenrir
parents:
diff changeset
179 DXVA2_BitStreamDateBufferType,
a6908ae0e0b5 VC-1/WMV3 DXVA2 implementation
fenrir
parents:
diff changeset
180 &dxva_data, &dxva_size)))
a6908ae0e0b5 VC-1/WMV3 DXVA2 implementation
fenrir
parents:
diff changeset
181 return -1;
a6908ae0e0b5 VC-1/WMV3 DXVA2 implementation
fenrir
parents:
diff changeset
182
a6908ae0e0b5 VC-1/WMV3 DXVA2 implementation
fenrir
parents:
diff changeset
183 result = data_size <= dxva_size ? 0 : -1;
a6908ae0e0b5 VC-1/WMV3 DXVA2 implementation
fenrir
parents:
diff changeset
184 if (!result) {
a6908ae0e0b5 VC-1/WMV3 DXVA2 implementation
fenrir
parents:
diff changeset
185 if (start_code_size > 0)
a6908ae0e0b5 VC-1/WMV3 DXVA2 implementation
fenrir
parents:
diff changeset
186 memcpy(dxva_data, start_code, start_code_size);
a6908ae0e0b5 VC-1/WMV3 DXVA2 implementation
fenrir
parents:
diff changeset
187 memcpy(dxva_data + start_code_size,
a6908ae0e0b5 VC-1/WMV3 DXVA2 implementation
fenrir
parents:
diff changeset
188 ctx_pic->bitstream + slice->dwSliceDataLocation, slice_size);
a6908ae0e0b5 VC-1/WMV3 DXVA2 implementation
fenrir
parents:
diff changeset
189 if (padding > 0)
a6908ae0e0b5 VC-1/WMV3 DXVA2 implementation
fenrir
parents:
diff changeset
190 memset(dxva_data + start_code_size + slice_size, 0, padding);
a6908ae0e0b5 VC-1/WMV3 DXVA2 implementation
fenrir
parents:
diff changeset
191 slice->dwSliceBitsInBuffer = 8 * data_size;
a6908ae0e0b5 VC-1/WMV3 DXVA2 implementation
fenrir
parents:
diff changeset
192 }
a6908ae0e0b5 VC-1/WMV3 DXVA2 implementation
fenrir
parents:
diff changeset
193 if (FAILED(IDirectXVideoDecoder_ReleaseBuffer(ctx->decoder,
a6908ae0e0b5 VC-1/WMV3 DXVA2 implementation
fenrir
parents:
diff changeset
194 DXVA2_BitStreamDateBufferType)))
a6908ae0e0b5 VC-1/WMV3 DXVA2 implementation
fenrir
parents:
diff changeset
195 return -1;
a6908ae0e0b5 VC-1/WMV3 DXVA2 implementation
fenrir
parents:
diff changeset
196 if (result)
a6908ae0e0b5 VC-1/WMV3 DXVA2 implementation
fenrir
parents:
diff changeset
197 return result;
a6908ae0e0b5 VC-1/WMV3 DXVA2 implementation
fenrir
parents:
diff changeset
198
a6908ae0e0b5 VC-1/WMV3 DXVA2 implementation
fenrir
parents:
diff changeset
199 memset(bs, 0, sizeof(*bs));
a6908ae0e0b5 VC-1/WMV3 DXVA2 implementation
fenrir
parents:
diff changeset
200 bs->CompressedBufferType = DXVA2_BitStreamDateBufferType;
a6908ae0e0b5 VC-1/WMV3 DXVA2 implementation
fenrir
parents:
diff changeset
201 bs->DataSize = data_size;
a6908ae0e0b5 VC-1/WMV3 DXVA2 implementation
fenrir
parents:
diff changeset
202 bs->NumMBsInBuffer = s->mb_width * s->mb_height;
a6908ae0e0b5 VC-1/WMV3 DXVA2 implementation
fenrir
parents:
diff changeset
203 assert((bs->DataSize & 127) == 0);
a6908ae0e0b5 VC-1/WMV3 DXVA2 implementation
fenrir
parents:
diff changeset
204
a6908ae0e0b5 VC-1/WMV3 DXVA2 implementation
fenrir
parents:
diff changeset
205 return ff_dxva2_commit_buffer(avctx, ctx, sc,
a6908ae0e0b5 VC-1/WMV3 DXVA2 implementation
fenrir
parents:
diff changeset
206 DXVA2_SliceControlBufferType,
a6908ae0e0b5 VC-1/WMV3 DXVA2 implementation
fenrir
parents:
diff changeset
207 slice, sizeof(*slice), bs->NumMBsInBuffer);
a6908ae0e0b5 VC-1/WMV3 DXVA2 implementation
fenrir
parents:
diff changeset
208 }
a6908ae0e0b5 VC-1/WMV3 DXVA2 implementation
fenrir
parents:
diff changeset
209
a6908ae0e0b5 VC-1/WMV3 DXVA2 implementation
fenrir
parents:
diff changeset
210 static int start_frame(AVCodecContext *avctx,
a6908ae0e0b5 VC-1/WMV3 DXVA2 implementation
fenrir
parents:
diff changeset
211 av_unused const uint8_t *buffer,
a6908ae0e0b5 VC-1/WMV3 DXVA2 implementation
fenrir
parents:
diff changeset
212 av_unused uint32_t size)
a6908ae0e0b5 VC-1/WMV3 DXVA2 implementation
fenrir
parents:
diff changeset
213 {
a6908ae0e0b5 VC-1/WMV3 DXVA2 implementation
fenrir
parents:
diff changeset
214 const VC1Context *v = avctx->priv_data;
a6908ae0e0b5 VC-1/WMV3 DXVA2 implementation
fenrir
parents:
diff changeset
215 struct dxva_context *ctx = avctx->hwaccel_context;
a6908ae0e0b5 VC-1/WMV3 DXVA2 implementation
fenrir
parents:
diff changeset
216 struct dxva2_picture_context *ctx_pic = v->s.current_picture_ptr->hwaccel_picture_private;
a6908ae0e0b5 VC-1/WMV3 DXVA2 implementation
fenrir
parents:
diff changeset
217
a6908ae0e0b5 VC-1/WMV3 DXVA2 implementation
fenrir
parents:
diff changeset
218 if (!ctx->decoder || !ctx->cfg || ctx->surface_count <= 0)
a6908ae0e0b5 VC-1/WMV3 DXVA2 implementation
fenrir
parents:
diff changeset
219 return -1;
a6908ae0e0b5 VC-1/WMV3 DXVA2 implementation
fenrir
parents:
diff changeset
220 assert(ctx_pic);
a6908ae0e0b5 VC-1/WMV3 DXVA2 implementation
fenrir
parents:
diff changeset
221
a6908ae0e0b5 VC-1/WMV3 DXVA2 implementation
fenrir
parents:
diff changeset
222 fill_picture_parameters(avctx, ctx, v, &ctx_pic->pp);
a6908ae0e0b5 VC-1/WMV3 DXVA2 implementation
fenrir
parents:
diff changeset
223
a6908ae0e0b5 VC-1/WMV3 DXVA2 implementation
fenrir
parents:
diff changeset
224 ctx_pic->bitstream_size = 0;
a6908ae0e0b5 VC-1/WMV3 DXVA2 implementation
fenrir
parents:
diff changeset
225 ctx_pic->bitstream = NULL;
a6908ae0e0b5 VC-1/WMV3 DXVA2 implementation
fenrir
parents:
diff changeset
226 return 0;
a6908ae0e0b5 VC-1/WMV3 DXVA2 implementation
fenrir
parents:
diff changeset
227 }
a6908ae0e0b5 VC-1/WMV3 DXVA2 implementation
fenrir
parents:
diff changeset
228
a6908ae0e0b5 VC-1/WMV3 DXVA2 implementation
fenrir
parents:
diff changeset
229 static int decode_slice(AVCodecContext *avctx,
a6908ae0e0b5 VC-1/WMV3 DXVA2 implementation
fenrir
parents:
diff changeset
230 const uint8_t *buffer, uint32_t size)
a6908ae0e0b5 VC-1/WMV3 DXVA2 implementation
fenrir
parents:
diff changeset
231 {
a6908ae0e0b5 VC-1/WMV3 DXVA2 implementation
fenrir
parents:
diff changeset
232 const VC1Context *v = avctx->priv_data;
a6908ae0e0b5 VC-1/WMV3 DXVA2 implementation
fenrir
parents:
diff changeset
233 const Picture *current_picture = v->s.current_picture_ptr;
a6908ae0e0b5 VC-1/WMV3 DXVA2 implementation
fenrir
parents:
diff changeset
234 struct dxva2_picture_context *ctx_pic = current_picture->hwaccel_picture_private;
a6908ae0e0b5 VC-1/WMV3 DXVA2 implementation
fenrir
parents:
diff changeset
235
a6908ae0e0b5 VC-1/WMV3 DXVA2 implementation
fenrir
parents:
diff changeset
236 if (ctx_pic->bitstream_size > 0)
a6908ae0e0b5 VC-1/WMV3 DXVA2 implementation
fenrir
parents:
diff changeset
237 return -1;
a6908ae0e0b5 VC-1/WMV3 DXVA2 implementation
fenrir
parents:
diff changeset
238
a6908ae0e0b5 VC-1/WMV3 DXVA2 implementation
fenrir
parents:
diff changeset
239 if (avctx->codec_id == CODEC_ID_VC1 &&
a6908ae0e0b5 VC-1/WMV3 DXVA2 implementation
fenrir
parents:
diff changeset
240 size >= 4 && IS_MARKER(AV_RB32(buffer))) {
a6908ae0e0b5 VC-1/WMV3 DXVA2 implementation
fenrir
parents:
diff changeset
241 buffer += 4;
a6908ae0e0b5 VC-1/WMV3 DXVA2 implementation
fenrir
parents:
diff changeset
242 size -= 4;
a6908ae0e0b5 VC-1/WMV3 DXVA2 implementation
fenrir
parents:
diff changeset
243 }
a6908ae0e0b5 VC-1/WMV3 DXVA2 implementation
fenrir
parents:
diff changeset
244
a6908ae0e0b5 VC-1/WMV3 DXVA2 implementation
fenrir
parents:
diff changeset
245 ctx_pic->bitstream_size = size;
a6908ae0e0b5 VC-1/WMV3 DXVA2 implementation
fenrir
parents:
diff changeset
246 ctx_pic->bitstream = buffer;
a6908ae0e0b5 VC-1/WMV3 DXVA2 implementation
fenrir
parents:
diff changeset
247
a6908ae0e0b5 VC-1/WMV3 DXVA2 implementation
fenrir
parents:
diff changeset
248 fill_slice(avctx, &ctx_pic->si, 0, size);
a6908ae0e0b5 VC-1/WMV3 DXVA2 implementation
fenrir
parents:
diff changeset
249 return 0;
a6908ae0e0b5 VC-1/WMV3 DXVA2 implementation
fenrir
parents:
diff changeset
250 }
a6908ae0e0b5 VC-1/WMV3 DXVA2 implementation
fenrir
parents:
diff changeset
251
a6908ae0e0b5 VC-1/WMV3 DXVA2 implementation
fenrir
parents:
diff changeset
252 static int end_frame(AVCodecContext *avctx)
a6908ae0e0b5 VC-1/WMV3 DXVA2 implementation
fenrir
parents:
diff changeset
253 {
a6908ae0e0b5 VC-1/WMV3 DXVA2 implementation
fenrir
parents:
diff changeset
254 VC1Context *v = avctx->priv_data;
a6908ae0e0b5 VC-1/WMV3 DXVA2 implementation
fenrir
parents:
diff changeset
255 struct dxva2_picture_context *ctx_pic = v->s.current_picture_ptr->hwaccel_picture_private;
a6908ae0e0b5 VC-1/WMV3 DXVA2 implementation
fenrir
parents:
diff changeset
256
a6908ae0e0b5 VC-1/WMV3 DXVA2 implementation
fenrir
parents:
diff changeset
257 if (ctx_pic->bitstream_size <= 0)
a6908ae0e0b5 VC-1/WMV3 DXVA2 implementation
fenrir
parents:
diff changeset
258 return -1;
a6908ae0e0b5 VC-1/WMV3 DXVA2 implementation
fenrir
parents:
diff changeset
259
a6908ae0e0b5 VC-1/WMV3 DXVA2 implementation
fenrir
parents:
diff changeset
260 return ff_dxva2_common_end_frame(avctx, &v->s,
a6908ae0e0b5 VC-1/WMV3 DXVA2 implementation
fenrir
parents:
diff changeset
261 &ctx_pic->pp, sizeof(ctx_pic->pp),
a6908ae0e0b5 VC-1/WMV3 DXVA2 implementation
fenrir
parents:
diff changeset
262 NULL, 0,
a6908ae0e0b5 VC-1/WMV3 DXVA2 implementation
fenrir
parents:
diff changeset
263 commit_bitstream_and_slice_buffer);
a6908ae0e0b5 VC-1/WMV3 DXVA2 implementation
fenrir
parents:
diff changeset
264 }
a6908ae0e0b5 VC-1/WMV3 DXVA2 implementation
fenrir
parents:
diff changeset
265
a6908ae0e0b5 VC-1/WMV3 DXVA2 implementation
fenrir
parents:
diff changeset
266 #if CONFIG_WMV3_DXVA2_HWACCEL
a6908ae0e0b5 VC-1/WMV3 DXVA2 implementation
fenrir
parents:
diff changeset
267 AVHWAccel wmv3_dxva2_hwaccel = {
a6908ae0e0b5 VC-1/WMV3 DXVA2 implementation
fenrir
parents:
diff changeset
268 .name = "wmv3_dxva2",
11560
8a4984c5cacc Define AVMediaType enum, and use it instead of enum CodecType, which
stefano
parents: 10990
diff changeset
269 .type = AVMEDIA_TYPE_VIDEO,
10990
a6908ae0e0b5 VC-1/WMV3 DXVA2 implementation
fenrir
parents:
diff changeset
270 .id = CODEC_ID_WMV3,
a6908ae0e0b5 VC-1/WMV3 DXVA2 implementation
fenrir
parents:
diff changeset
271 .pix_fmt = PIX_FMT_DXVA2_VLD,
a6908ae0e0b5 VC-1/WMV3 DXVA2 implementation
fenrir
parents:
diff changeset
272 .capabilities = 0,
a6908ae0e0b5 VC-1/WMV3 DXVA2 implementation
fenrir
parents:
diff changeset
273 .start_frame = start_frame,
a6908ae0e0b5 VC-1/WMV3 DXVA2 implementation
fenrir
parents:
diff changeset
274 .decode_slice = decode_slice,
a6908ae0e0b5 VC-1/WMV3 DXVA2 implementation
fenrir
parents:
diff changeset
275 .end_frame = end_frame,
a6908ae0e0b5 VC-1/WMV3 DXVA2 implementation
fenrir
parents:
diff changeset
276 .priv_data_size = sizeof(struct dxva2_picture_context),
a6908ae0e0b5 VC-1/WMV3 DXVA2 implementation
fenrir
parents:
diff changeset
277 };
a6908ae0e0b5 VC-1/WMV3 DXVA2 implementation
fenrir
parents:
diff changeset
278 #endif
a6908ae0e0b5 VC-1/WMV3 DXVA2 implementation
fenrir
parents:
diff changeset
279
a6908ae0e0b5 VC-1/WMV3 DXVA2 implementation
fenrir
parents:
diff changeset
280 AVHWAccel vc1_dxva2_hwaccel = {
a6908ae0e0b5 VC-1/WMV3 DXVA2 implementation
fenrir
parents:
diff changeset
281 .name = "vc1_dxva2",
11560
8a4984c5cacc Define AVMediaType enum, and use it instead of enum CodecType, which
stefano
parents: 10990
diff changeset
282 .type = AVMEDIA_TYPE_VIDEO,
10990
a6908ae0e0b5 VC-1/WMV3 DXVA2 implementation
fenrir
parents:
diff changeset
283 .id = CODEC_ID_VC1,
a6908ae0e0b5 VC-1/WMV3 DXVA2 implementation
fenrir
parents:
diff changeset
284 .pix_fmt = PIX_FMT_DXVA2_VLD,
a6908ae0e0b5 VC-1/WMV3 DXVA2 implementation
fenrir
parents:
diff changeset
285 .capabilities = 0,
a6908ae0e0b5 VC-1/WMV3 DXVA2 implementation
fenrir
parents:
diff changeset
286 .start_frame = start_frame,
a6908ae0e0b5 VC-1/WMV3 DXVA2 implementation
fenrir
parents:
diff changeset
287 .decode_slice = decode_slice,
a6908ae0e0b5 VC-1/WMV3 DXVA2 implementation
fenrir
parents:
diff changeset
288 .end_frame = end_frame,
a6908ae0e0b5 VC-1/WMV3 DXVA2 implementation
fenrir
parents:
diff changeset
289 .priv_data_size = sizeof(struct dxva2_picture_context),
a6908ae0e0b5 VC-1/WMV3 DXVA2 implementation
fenrir
parents:
diff changeset
290 };
a6908ae0e0b5 VC-1/WMV3 DXVA2 implementation
fenrir
parents:
diff changeset
291