00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #include "dxva2_internal.h"
00024 #include "vc1.h"
00025 #include "vc1data.h"
00026
00027 struct dxva2_picture_context {
00028 DXVA_PictureParameters pp;
00029 DXVA_SliceInfo si;
00030
00031 const uint8_t *bitstream;
00032 unsigned bitstream_size;
00033 };
00034
00035 static void fill_picture_parameters(AVCodecContext *avctx,
00036 struct dxva_context *ctx, const VC1Context *v,
00037 DXVA_PictureParameters *pp)
00038 {
00039 const MpegEncContext *s = &v->s;
00040 const Picture *current_picture = s->current_picture_ptr;
00041
00042 memset(pp, 0, sizeof(*pp));
00043 pp->wDecodedPictureIndex =
00044 pp->wDeblockedPictureIndex = ff_dxva2_get_surface_index(ctx, current_picture);
00045 if (s->pict_type != AV_PICTURE_TYPE_I && !v->bi_type)
00046 pp->wForwardRefPictureIndex = ff_dxva2_get_surface_index(ctx, &s->last_picture);
00047 else
00048 pp->wForwardRefPictureIndex = 0xffff;
00049 if (s->pict_type == AV_PICTURE_TYPE_B && !v->bi_type)
00050 pp->wBackwardRefPictureIndex = ff_dxva2_get_surface_index(ctx, &s->next_picture);
00051 else
00052 pp->wBackwardRefPictureIndex = 0xffff;
00053 if (v->profile == PROFILE_ADVANCED) {
00054
00055 pp->wPicWidthInMBminus1 = avctx->width - 1;
00056 pp->wPicHeightInMBminus1= avctx->height - 1;
00057 } else {
00058
00059 pp->wPicWidthInMBminus1 = s->mb_width - 1;
00060 pp->wPicHeightInMBminus1= s->mb_height - 1;
00061 }
00062 pp->bMacroblockWidthMinus1 = 15;
00063 pp->bMacroblockHeightMinus1 = 15;
00064 pp->bBlockWidthMinus1 = 7;
00065 pp->bBlockHeightMinus1 = 7;
00066 pp->bBPPminus1 = 7;
00067 if (s->picture_structure & PICT_TOP_FIELD)
00068 pp->bPicStructure |= 0x01;
00069 if (s->picture_structure & PICT_BOTTOM_FIELD)
00070 pp->bPicStructure |= 0x02;
00071 pp->bSecondField = v->interlace && v->fcm != ILACE_FIELD && !s->first_field;
00072 pp->bPicIntra = s->pict_type == AV_PICTURE_TYPE_I || v->bi_type;
00073 pp->bPicBackwardPrediction = s->pict_type == AV_PICTURE_TYPE_B && !v->bi_type;
00074 pp->bBidirectionalAveragingMode = (1 << 7) |
00075 ((ctx->cfg->ConfigIntraResidUnsigned != 0) << 6) |
00076 ((ctx->cfg->ConfigResidDiffAccelerator != 0) << 5) |
00077 ((v->lumscale != 32 || v->lumshift != 0) << 4) |
00078 ((v->profile == PROFILE_ADVANCED) << 3);
00079 pp->bMVprecisionAndChromaRelation = ((v->mv_mode == MV_PMODE_1MV_HPEL_BILIN) << 3) |
00080 (1 << 2) |
00081 (0 << 1) |
00082 (!s->quarter_sample );
00083 pp->bChromaFormat = v->chromaformat;
00084 ctx->report_id++;
00085 if (ctx->report_id >= (1 << 16))
00086 ctx->report_id = 1;
00087 pp->bPicScanFixed = ctx->report_id >> 8;
00088 pp->bPicScanMethod = ctx->report_id & 0xff;
00089 pp->bPicReadbackRequests = 0;
00090 pp->bRcontrol = v->rnd;
00091 pp->bPicSpatialResid8 = (v->panscanflag << 7) |
00092 (v->refdist_flag << 6) |
00093 (s->loop_filter << 5) |
00094 (v->fastuvmc << 4) |
00095 (v->extended_mv << 3) |
00096 (v->dquant << 1) |
00097 (v->vstransform );
00098 pp->bPicOverflowBlocks = (v->quantizer_mode << 6) |
00099 (v->multires << 5) |
00100 (s->resync_marker << 4) |
00101 (v->rangered << 3) |
00102 (s->max_b_frames );
00103 pp->bPicExtrapolation = (!v->interlace || v->fcm == PROGRESSIVE) ? 1 : 2;
00104 pp->bPicDeblocked = ((!pp->bPicBackwardPrediction && v->overlap) << 6) |
00105 ((v->profile != PROFILE_ADVANCED && v->rangeredfrm) << 5) |
00106 (s->loop_filter << 1);
00107 pp->bPicDeblockConfined = (v->postprocflag << 7) |
00108 (v->broadcast << 6) |
00109 (v->interlace << 5) |
00110 (v->tfcntrflag << 4) |
00111 (v->finterpflag << 3) |
00112 ((s->pict_type != AV_PICTURE_TYPE_B) << 2) |
00113 (v->psf << 1) |
00114 (v->extended_dmv );
00115 if (s->pict_type != AV_PICTURE_TYPE_I)
00116 pp->bPic4MVallowed = v->mv_mode == MV_PMODE_MIXED_MV ||
00117 (v->mv_mode == MV_PMODE_INTENSITY_COMP &&
00118 v->mv_mode2 == MV_PMODE_MIXED_MV);
00119 if (v->profile == PROFILE_ADVANCED)
00120 pp->bPicOBMC = (v->range_mapy_flag << 7) |
00121 (v->range_mapy << 4) |
00122 (v->range_mapuv_flag << 3) |
00123 (v->range_mapuv );
00124 pp->bPicBinPB = 0;
00125 pp->bMV_RPS = 0;
00126 pp->bReservedBits = 0;
00127 if (s->picture_structure == PICT_FRAME) {
00128 pp->wBitstreamFcodes = v->lumscale;
00129 pp->wBitstreamPCEelements = v->lumshift;
00130 } else {
00131
00132 pp->wBitstreamFcodes = (v->lumscale << 8) | v->lumscale;
00133 pp->wBitstreamPCEelements = (v->lumshift << 8) | v->lumshift;
00134 }
00135 pp->bBitstreamConcealmentNeed = 0;
00136 pp->bBitstreamConcealmentMethod = 0;
00137 }
00138
00139 static void fill_slice(AVCodecContext *avctx, DXVA_SliceInfo *slice,
00140 unsigned position, unsigned size)
00141 {
00142 const VC1Context *v = avctx->priv_data;
00143 const MpegEncContext *s = &v->s;
00144
00145 memset(slice, 0, sizeof(*slice));
00146 slice->wHorizontalPosition = 0;
00147 slice->wVerticalPosition = s->mb_y;
00148 slice->dwSliceBitsInBuffer = 8 * size;
00149 slice->dwSliceDataLocation = position;
00150 slice->bStartCodeBitOffset = 0;
00151 slice->bReservedBits = 0;
00152 slice->wMBbitOffset = get_bits_count(&s->gb);
00153 slice->wNumberMBsInSlice = s->mb_width * s->mb_height;
00154 slice->wQuantizerScaleCode = v->pq;
00155 slice->wBadSliceChopping = 0;
00156 }
00157
00158 static int commit_bitstream_and_slice_buffer(AVCodecContext *avctx,
00159 DXVA2_DecodeBufferDesc *bs,
00160 DXVA2_DecodeBufferDesc *sc)
00161 {
00162 const VC1Context *v = avctx->priv_data;
00163 struct dxva_context *ctx = avctx->hwaccel_context;
00164 const MpegEncContext *s = &v->s;
00165 struct dxva2_picture_context *ctx_pic = s->current_picture_ptr->f.hwaccel_picture_private;
00166
00167 DXVA_SliceInfo *slice = &ctx_pic->si;
00168
00169 static const uint8_t start_code[] = { 0, 0, 1, 0x0d };
00170 const unsigned start_code_size = avctx->codec_id == CODEC_ID_VC1 ? sizeof(start_code) : 0;
00171 const unsigned slice_size = slice->dwSliceBitsInBuffer / 8;
00172 const unsigned padding = 128 - ((start_code_size + slice_size) & 127);
00173 const unsigned data_size = start_code_size + slice_size + padding;
00174
00175 uint8_t *dxva_data;
00176 unsigned dxva_size;
00177 int result;
00178
00179 if (FAILED(IDirectXVideoDecoder_GetBuffer(ctx->decoder,
00180 DXVA2_BitStreamDateBufferType,
00181 &dxva_data, &dxva_size)))
00182 return -1;
00183
00184 result = data_size <= dxva_size ? 0 : -1;
00185 if (!result) {
00186 if (start_code_size > 0)
00187 memcpy(dxva_data, start_code, start_code_size);
00188 memcpy(dxva_data + start_code_size,
00189 ctx_pic->bitstream + slice->dwSliceDataLocation, slice_size);
00190 if (padding > 0)
00191 memset(dxva_data + start_code_size + slice_size, 0, padding);
00192 slice->dwSliceBitsInBuffer = 8 * data_size;
00193 }
00194 if (FAILED(IDirectXVideoDecoder_ReleaseBuffer(ctx->decoder,
00195 DXVA2_BitStreamDateBufferType)))
00196 return -1;
00197 if (result)
00198 return result;
00199
00200 memset(bs, 0, sizeof(*bs));
00201 bs->CompressedBufferType = DXVA2_BitStreamDateBufferType;
00202 bs->DataSize = data_size;
00203 bs->NumMBsInBuffer = s->mb_width * s->mb_height;
00204 assert((bs->DataSize & 127) == 0);
00205
00206 return ff_dxva2_commit_buffer(avctx, ctx, sc,
00207 DXVA2_SliceControlBufferType,
00208 slice, sizeof(*slice), bs->NumMBsInBuffer);
00209 }
00210
00211 static int start_frame(AVCodecContext *avctx,
00212 av_unused const uint8_t *buffer,
00213 av_unused uint32_t size)
00214 {
00215 const VC1Context *v = avctx->priv_data;
00216 struct dxva_context *ctx = avctx->hwaccel_context;
00217 struct dxva2_picture_context *ctx_pic = v->s.current_picture_ptr->f.hwaccel_picture_private;
00218
00219 if (!ctx->decoder || !ctx->cfg || ctx->surface_count <= 0)
00220 return -1;
00221 assert(ctx_pic);
00222
00223 fill_picture_parameters(avctx, ctx, v, &ctx_pic->pp);
00224
00225 ctx_pic->bitstream_size = 0;
00226 ctx_pic->bitstream = NULL;
00227 return 0;
00228 }
00229
00230 static int decode_slice(AVCodecContext *avctx,
00231 const uint8_t *buffer, uint32_t size)
00232 {
00233 const VC1Context *v = avctx->priv_data;
00234 const Picture *current_picture = v->s.current_picture_ptr;
00235 struct dxva2_picture_context *ctx_pic = current_picture->f.hwaccel_picture_private;
00236
00237 if (ctx_pic->bitstream_size > 0)
00238 return -1;
00239
00240 if (avctx->codec_id == CODEC_ID_VC1 &&
00241 size >= 4 && IS_MARKER(AV_RB32(buffer))) {
00242 buffer += 4;
00243 size -= 4;
00244 }
00245
00246 ctx_pic->bitstream_size = size;
00247 ctx_pic->bitstream = buffer;
00248
00249 fill_slice(avctx, &ctx_pic->si, 0, size);
00250 return 0;
00251 }
00252
00253 static int end_frame(AVCodecContext *avctx)
00254 {
00255 VC1Context *v = avctx->priv_data;
00256 struct dxva2_picture_context *ctx_pic = v->s.current_picture_ptr->f.hwaccel_picture_private;
00257
00258 if (ctx_pic->bitstream_size <= 0)
00259 return -1;
00260
00261 return ff_dxva2_common_end_frame(avctx, &v->s,
00262 &ctx_pic->pp, sizeof(ctx_pic->pp),
00263 NULL, 0,
00264 commit_bitstream_and_slice_buffer);
00265 }
00266
00267 #if CONFIG_WMV3_DXVA2_HWACCEL
00268 AVHWAccel ff_wmv3_dxva2_hwaccel = {
00269 .name = "wmv3_dxva2",
00270 .type = AVMEDIA_TYPE_VIDEO,
00271 .id = CODEC_ID_WMV3,
00272 .pix_fmt = PIX_FMT_DXVA2_VLD,
00273 .start_frame = start_frame,
00274 .decode_slice = decode_slice,
00275 .end_frame = end_frame,
00276 .priv_data_size = sizeof(struct dxva2_picture_context),
00277 };
00278 #endif
00279
00280 AVHWAccel ff_vc1_dxva2_hwaccel = {
00281 .name = "vc1_dxva2",
00282 .type = AVMEDIA_TYPE_VIDEO,
00283 .id = CODEC_ID_VC1,
00284 .pix_fmt = PIX_FMT_DXVA2_VLD,
00285 .start_frame = start_frame,
00286 .decode_slice = decode_slice,
00287 .end_frame = end_frame,
00288 .priv_data_size = sizeof(struct dxva2_picture_context),
00289 };