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
00025 #define MAX_SLICES (SLICE_MAX_START_CODE - SLICE_MIN_START_CODE + 1)
00026 struct dxva2_picture_context {
00027 DXVA_PictureParameters pp;
00028 DXVA_QmatrixData qm;
00029 unsigned slice_count;
00030 DXVA_SliceInfo slice[MAX_SLICES];
00031
00032 const uint8_t *bitstream;
00033 unsigned bitstream_size;
00034 };
00035
00036 static void fill_picture_parameters(AVCodecContext *avctx,
00037 struct dxva_context *ctx,
00038 const struct MpegEncContext *s,
00039 DXVA_PictureParameters *pp)
00040 {
00041 const Picture *current_picture = s->current_picture_ptr;
00042 int is_field = s->picture_structure != PICT_FRAME;
00043
00044 memset(pp, 0, sizeof(*pp));
00045 pp->wDecodedPictureIndex = ff_dxva2_get_surface_index(ctx, current_picture);
00046 pp->wDeblockedPictureIndex = 0;
00047 if (s->pict_type != AV_PICTURE_TYPE_I)
00048 pp->wForwardRefPictureIndex = ff_dxva2_get_surface_index(ctx, &s->last_picture);
00049 else
00050 pp->wForwardRefPictureIndex = 0xffff;
00051 if (s->pict_type == AV_PICTURE_TYPE_B)
00052 pp->wBackwardRefPictureIndex = ff_dxva2_get_surface_index(ctx, &s->next_picture);
00053 else
00054 pp->wBackwardRefPictureIndex = 0xffff;
00055 pp->wPicWidthInMBminus1 = s->mb_width - 1;
00056 pp->wPicHeightInMBminus1 = (s->mb_height >> is_field) - 1;
00057 pp->bMacroblockWidthMinus1 = 15;
00058 pp->bMacroblockHeightMinus1 = 15;
00059 pp->bBlockWidthMinus1 = 7;
00060 pp->bBlockHeightMinus1 = 7;
00061 pp->bBPPminus1 = 7;
00062 pp->bPicStructure = s->picture_structure;
00063 pp->bSecondField = is_field && !s->first_field;
00064 pp->bPicIntra = s->pict_type == AV_PICTURE_TYPE_I;
00065 pp->bPicBackwardPrediction = s->pict_type == AV_PICTURE_TYPE_B;
00066 pp->bBidirectionalAveragingMode = 0;
00067 pp->bMVprecisionAndChromaRelation= 0;
00068 pp->bChromaFormat = s->chroma_format;
00069 pp->bPicScanFixed = 1;
00070 pp->bPicScanMethod = s->alternate_scan ? 1 : 0;
00071 pp->bPicReadbackRequests = 0;
00072 pp->bRcontrol = 0;
00073 pp->bPicSpatialResid8 = 0;
00074 pp->bPicOverflowBlocks = 0;
00075 pp->bPicExtrapolation = 0;
00076 pp->bPicDeblocked = 0;
00077 pp->bPicDeblockConfined = 0;
00078 pp->bPic4MVallowed = 0;
00079 pp->bPicOBMC = 0;
00080 pp->bPicBinPB = 0;
00081 pp->bMV_RPS = 0;
00082 pp->bReservedBits = 0;
00083 pp->wBitstreamFcodes = (s->mpeg_f_code[0][0] << 12) |
00084 (s->mpeg_f_code[0][1] << 8) |
00085 (s->mpeg_f_code[1][0] << 4) |
00086 (s->mpeg_f_code[1][1] );
00087 pp->wBitstreamPCEelements = (s->intra_dc_precision << 14) |
00088 (s->picture_structure << 12) |
00089 (s->top_field_first << 11) |
00090 (s->frame_pred_frame_dct << 10) |
00091 (s->concealment_motion_vectors << 9) |
00092 (s->q_scale_type << 8) |
00093 (s->intra_vlc_format << 7) |
00094 (s->alternate_scan << 6) |
00095 (s->repeat_first_field << 5) |
00096 (s->chroma_420_type << 4) |
00097 (s->progressive_frame << 3);
00098 pp->bBitstreamConcealmentNeed = 0;
00099 pp->bBitstreamConcealmentMethod = 0;
00100 }
00101
00102 static void fill_quantization_matrices(AVCodecContext *avctx,
00103 struct dxva_context *ctx,
00104 const struct MpegEncContext *s,
00105 DXVA_QmatrixData *qm)
00106 {
00107 int i;
00108 for (i = 0; i < 4; i++)
00109 qm->bNewQmatrix[i] = 1;
00110 for (i = 0; i < 64; i++) {
00111 int n = s->dsp.idct_permutation[ff_zigzag_direct[i]];
00112 qm->Qmatrix[0][i] = s->intra_matrix[n];
00113 qm->Qmatrix[1][i] = s->inter_matrix[n];
00114 qm->Qmatrix[2][i] = s->chroma_intra_matrix[n];
00115 qm->Qmatrix[3][i] = s->chroma_inter_matrix[n];
00116 }
00117 }
00118
00119 static void fill_slice(AVCodecContext *avctx,
00120 const struct MpegEncContext *s,
00121 DXVA_SliceInfo *slice,
00122 unsigned position,
00123 const uint8_t *buffer, unsigned size)
00124 {
00125 int is_field = s->picture_structure != PICT_FRAME;
00126 GetBitContext gb;
00127
00128 memset(slice, 0, sizeof(*slice));
00129 slice->wHorizontalPosition = s->mb_x;
00130 slice->wVerticalPosition = s->mb_y >> is_field;
00131 slice->dwSliceBitsInBuffer = 8 * size;
00132 slice->dwSliceDataLocation = position;
00133 slice->bStartCodeBitOffset = 0;
00134 slice->bReservedBits = 0;
00135
00136 slice->wNumberMBsInSlice = (s->mb_y >> is_field) * s->mb_width + s->mb_x;
00137 slice->wBadSliceChopping = 0;
00138
00139 init_get_bits(&gb, &buffer[4], 8 * (size - 4));
00140
00141 slice->wQuantizerScaleCode = get_bits(&gb, 5);
00142 while (get_bits1(&gb))
00143 skip_bits(&gb, 8);
00144
00145 slice->wMBbitOffset = 4 * 8 + get_bits_count(&gb);
00146 }
00147 static int commit_bitstream_and_slice_buffer(AVCodecContext *avctx,
00148 DXVA2_DecodeBufferDesc *bs,
00149 DXVA2_DecodeBufferDesc *sc)
00150 {
00151 const struct MpegEncContext *s = avctx->priv_data;
00152 struct dxva_context *ctx = avctx->hwaccel_context;
00153 struct dxva2_picture_context *ctx_pic =
00154 s->current_picture_ptr->f.hwaccel_picture_private;
00155 const int is_field = s->picture_structure != PICT_FRAME;
00156 const unsigned mb_count = s->mb_width * (s->mb_height >> is_field);
00157 uint8_t *dxva_data, *current, *end;
00158 unsigned dxva_size;
00159 unsigned i;
00160
00161 if (FAILED(IDirectXVideoDecoder_GetBuffer(ctx->decoder,
00162 DXVA2_BitStreamDateBufferType,
00163 (void **)&dxva_data, &dxva_size)))
00164 return -1;
00165 current = dxva_data;
00166 end = dxva_data + dxva_size;
00167
00168 for (i = 0; i < ctx_pic->slice_count; i++) {
00169 DXVA_SliceInfo *slice = &ctx_pic->slice[i];
00170 unsigned position = slice->dwSliceDataLocation;
00171 unsigned size = slice->dwSliceBitsInBuffer / 8;
00172 if (size > end - current) {
00173 av_log(avctx, AV_LOG_ERROR, "Failed to build bitstream");
00174 break;
00175 }
00176 slice->dwSliceDataLocation = current - dxva_data;
00177
00178 if (i < ctx_pic->slice_count - 1)
00179 slice->wNumberMBsInSlice =
00180 slice[1].wNumberMBsInSlice - slice[0].wNumberMBsInSlice;
00181 else
00182 slice->wNumberMBsInSlice =
00183 mb_count - slice[0].wNumberMBsInSlice;
00184
00185 memcpy(current, &ctx_pic->bitstream[position], size);
00186 current += size;
00187 }
00188 if (FAILED(IDirectXVideoDecoder_ReleaseBuffer(ctx->decoder,
00189 DXVA2_BitStreamDateBufferType)))
00190 return -1;
00191 if (i < ctx_pic->slice_count)
00192 return -1;
00193
00194 memset(bs, 0, sizeof(*bs));
00195 bs->CompressedBufferType = DXVA2_BitStreamDateBufferType;
00196 bs->DataSize = current - dxva_data;
00197 bs->NumMBsInBuffer = mb_count;
00198
00199 return ff_dxva2_commit_buffer(avctx, ctx, sc,
00200 DXVA2_SliceControlBufferType,
00201 ctx_pic->slice,
00202 ctx_pic->slice_count * sizeof(*ctx_pic->slice),
00203 mb_count);
00204 }
00205
00206 static int start_frame(AVCodecContext *avctx,
00207 av_unused const uint8_t *buffer,
00208 av_unused uint32_t size)
00209 {
00210 const struct MpegEncContext *s = avctx->priv_data;
00211 struct dxva_context *ctx = avctx->hwaccel_context;
00212 struct dxva2_picture_context *ctx_pic =
00213 s->current_picture_ptr->f.hwaccel_picture_private;
00214
00215 if (!ctx->decoder || !ctx->cfg || ctx->surface_count <= 0)
00216 return -1;
00217 assert(ctx_pic);
00218
00219 fill_picture_parameters(avctx, ctx, s, &ctx_pic->pp);
00220 fill_quantization_matrices(avctx, ctx, s, &ctx_pic->qm);
00221
00222 ctx_pic->slice_count = 0;
00223 ctx_pic->bitstream_size = 0;
00224 ctx_pic->bitstream = NULL;
00225 return 0;
00226 }
00227
00228 static int decode_slice(AVCodecContext *avctx,
00229 const uint8_t *buffer, uint32_t size)
00230 {
00231 const struct MpegEncContext *s = avctx->priv_data;
00232 struct dxva2_picture_context *ctx_pic =
00233 s->current_picture_ptr->f.hwaccel_picture_private;
00234 unsigned position;
00235
00236 if (ctx_pic->slice_count >= MAX_SLICES)
00237 return -1;
00238
00239 if (!ctx_pic->bitstream)
00240 ctx_pic->bitstream = buffer;
00241 ctx_pic->bitstream_size += size;
00242
00243 position = buffer - ctx_pic->bitstream;
00244 fill_slice(avctx, s, &ctx_pic->slice[ctx_pic->slice_count++], position,
00245 buffer, size);
00246 return 0;
00247 }
00248
00249 static int end_frame(AVCodecContext *avctx)
00250 {
00251 struct MpegEncContext *s = avctx->priv_data;
00252 struct dxva2_picture_context *ctx_pic =
00253 s->current_picture_ptr->f.hwaccel_picture_private;
00254
00255 if (ctx_pic->slice_count <= 0 || ctx_pic->bitstream_size <= 0)
00256 return -1;
00257 return ff_dxva2_common_end_frame(avctx, s,
00258 &ctx_pic->pp, sizeof(ctx_pic->pp),
00259 &ctx_pic->qm, sizeof(ctx_pic->qm),
00260 commit_bitstream_and_slice_buffer);
00261 }
00262
00263 AVHWAccel ff_mpeg2_dxva2_hwaccel = {
00264 .name = "mpeg2_dxva2",
00265 .type = AVMEDIA_TYPE_VIDEO,
00266 .id = AV_CODEC_ID_MPEG2VIDEO,
00267 .pix_fmt = PIX_FMT_DXVA2_VLD,
00268 .start_frame = start_frame,
00269 .decode_slice = decode_slice,
00270 .end_frame = end_frame,
00271 .priv_data_size = sizeof(struct dxva2_picture_context),
00272 };