Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | RSS feed

  1. /*
  2.  * MPEG-2 HW acceleration.
  3.  *
  4.  * copyright (c) 2010 Laurent Aimar
  5.  *
  6.  * This file is part of FFmpeg.
  7.  *
  8.  * FFmpeg is free software; you can redistribute it and/or
  9.  * modify it under the terms of the GNU Lesser General Public
  10.  * License as published by the Free Software Foundation; either
  11.  * version 2.1 of the License, or (at your option) any later version.
  12.  *
  13.  * FFmpeg is distributed in the hope that it will be useful,
  14.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  16.  * Lesser General Public License for more details.
  17.  *
  18.  * You should have received a copy of the GNU Lesser General Public
  19.  * License along with FFmpeg; if not, write to the Free Software
  20.  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  21.  */
  22.  
  23. #include "libavutil/log.h"
  24. #include "dxva2_internal.h"
  25. #include "mpegutils.h"
  26.  
  27. #define MAX_SLICES 1024
  28. struct dxva2_picture_context {
  29.     DXVA_PictureParameters pp;
  30.     DXVA_QmatrixData       qm;
  31.     unsigned               slice_count;
  32.     DXVA_SliceInfo         slice[MAX_SLICES];
  33.  
  34.     const uint8_t          *bitstream;
  35.     unsigned               bitstream_size;
  36. };
  37.  
  38. static void fill_picture_parameters(AVCodecContext *avctx,
  39.                                     AVDXVAContext *ctx,
  40.                                     const struct MpegEncContext *s,
  41.                                     DXVA_PictureParameters *pp)
  42. {
  43.     const Picture *current_picture = s->current_picture_ptr;
  44.     int is_field = s->picture_structure != PICT_FRAME;
  45.  
  46.     memset(pp, 0, sizeof(*pp));
  47.     pp->wDecodedPictureIndex         = ff_dxva2_get_surface_index(avctx, ctx, current_picture->f);
  48.     pp->wDeblockedPictureIndex       = 0;
  49.     if (s->pict_type != AV_PICTURE_TYPE_I)
  50.         pp->wForwardRefPictureIndex  = ff_dxva2_get_surface_index(avctx, ctx, s->last_picture.f);
  51.     else
  52.         pp->wForwardRefPictureIndex  = 0xffff;
  53.     if (s->pict_type == AV_PICTURE_TYPE_B)
  54.         pp->wBackwardRefPictureIndex = ff_dxva2_get_surface_index(avctx, ctx, s->next_picture.f);
  55.     else
  56.         pp->wBackwardRefPictureIndex = 0xffff;
  57.     pp->wPicWidthInMBminus1          = s->mb_width  - 1;
  58.     pp->wPicHeightInMBminus1         = (s->mb_height >> is_field) - 1;
  59.     pp->bMacroblockWidthMinus1       = 15;
  60.     pp->bMacroblockHeightMinus1      = 15;
  61.     pp->bBlockWidthMinus1            = 7;
  62.     pp->bBlockHeightMinus1           = 7;
  63.     pp->bBPPminus1                   = 7;
  64.     pp->bPicStructure                = s->picture_structure;
  65.     pp->bSecondField                 = is_field && !s->first_field;
  66.     pp->bPicIntra                    = s->pict_type == AV_PICTURE_TYPE_I;
  67.     pp->bPicBackwardPrediction       = s->pict_type == AV_PICTURE_TYPE_B;
  68.     pp->bBidirectionalAveragingMode  = 0;
  69.     pp->bMVprecisionAndChromaRelation= 0; /* FIXME */
  70.     pp->bChromaFormat                = s->chroma_format;
  71.     pp->bPicScanFixed                = 1;
  72.     pp->bPicScanMethod               = s->alternate_scan ? 1 : 0;
  73.     pp->bPicReadbackRequests         = 0;
  74.     pp->bRcontrol                    = 0;
  75.     pp->bPicSpatialResid8            = 0;
  76.     pp->bPicOverflowBlocks           = 0;
  77.     pp->bPicExtrapolation            = 0;
  78.     pp->bPicDeblocked                = 0;
  79.     pp->bPicDeblockConfined          = 0;
  80.     pp->bPic4MVallowed               = 0;
  81.     pp->bPicOBMC                     = 0;
  82.     pp->bPicBinPB                    = 0;
  83.     pp->bMV_RPS                      = 0;
  84.     pp->bReservedBits                = 0;
  85.     pp->wBitstreamFcodes             = (s->mpeg_f_code[0][0] << 12) |
  86.                                        (s->mpeg_f_code[0][1] <<  8) |
  87.                                        (s->mpeg_f_code[1][0] <<  4) |
  88.                                        (s->mpeg_f_code[1][1]      );
  89.     pp->wBitstreamPCEelements        = (s->intra_dc_precision         << 14) |
  90.                                        (s->picture_structure          << 12) |
  91.                                        (s->top_field_first            << 11) |
  92.                                        (s->frame_pred_frame_dct       << 10) |
  93.                                        (s->concealment_motion_vectors <<  9) |
  94.                                        (s->q_scale_type               <<  8) |
  95.                                        (s->intra_vlc_format           <<  7) |
  96.                                        (s->alternate_scan             <<  6) |
  97.                                        (s->repeat_first_field         <<  5) |
  98.                                        (s->chroma_420_type            <<  4) |
  99.                                        (s->progressive_frame          <<  3);
  100.     pp->bBitstreamConcealmentNeed    = 0;
  101.     pp->bBitstreamConcealmentMethod  = 0;
  102. }
  103.  
  104. static void fill_quantization_matrices(AVCodecContext *avctx,
  105.                                        AVDXVAContext *ctx,
  106.                                        const struct MpegEncContext *s,
  107.                                        DXVA_QmatrixData *qm)
  108. {
  109.     int i;
  110.     for (i = 0; i < 4; i++)
  111.         qm->bNewQmatrix[i] = 1;
  112.     for (i = 0; i < 64; i++) {
  113.         int n = s->idsp.idct_permutation[ff_zigzag_direct[i]];
  114.         qm->Qmatrix[0][i] = s->intra_matrix[n];
  115.         qm->Qmatrix[1][i] = s->inter_matrix[n];
  116.         qm->Qmatrix[2][i] = s->chroma_intra_matrix[n];
  117.         qm->Qmatrix[3][i] = s->chroma_inter_matrix[n];
  118.     }
  119. }
  120.  
  121. static void fill_slice(AVCodecContext *avctx,
  122.                        const struct MpegEncContext *s,
  123.                        DXVA_SliceInfo *slice,
  124.                        unsigned position,
  125.                        const uint8_t *buffer, unsigned size)
  126. {
  127.     int is_field = s->picture_structure != PICT_FRAME;
  128.     GetBitContext gb;
  129.  
  130.     memset(slice, 0, sizeof(*slice));
  131.     slice->wHorizontalPosition = s->mb_x;
  132.     slice->wVerticalPosition   = s->mb_y >> is_field;
  133.     slice->dwSliceBitsInBuffer = 8 * size;
  134.     slice->dwSliceDataLocation = position;
  135.     slice->bStartCodeBitOffset = 0;
  136.     slice->bReservedBits       = 0;
  137.     /* XXX We store the index of the first MB and it will be fixed later */
  138.     slice->wNumberMBsInSlice   = (s->mb_y >> is_field) * s->mb_width + s->mb_x;
  139.     slice->wBadSliceChopping   = 0;
  140.  
  141.     init_get_bits(&gb, &buffer[4], 8 * (size - 4));
  142.  
  143.     slice->wQuantizerScaleCode = get_bits(&gb, 5);
  144.     skip_1stop_8data_bits(&gb);
  145.  
  146.     slice->wMBbitOffset        = 4 * 8 + get_bits_count(&gb);
  147. }
  148. static int commit_bitstream_and_slice_buffer(AVCodecContext *avctx,
  149.                                              DECODER_BUFFER_DESC *bs,
  150.                                              DECODER_BUFFER_DESC *sc)
  151. {
  152.     const struct MpegEncContext *s = avctx->priv_data;
  153.     AVDXVAContext *ctx = avctx->hwaccel_context;
  154.     struct dxva2_picture_context *ctx_pic =
  155.         s->current_picture_ptr->hwaccel_picture_private;
  156.     const int is_field = s->picture_structure != PICT_FRAME;
  157.     const unsigned mb_count = s->mb_width * (s->mb_height >> is_field);
  158.     void     *dxva_data_ptr;
  159.     uint8_t  *dxva_data, *current, *end;
  160.     unsigned dxva_size;
  161.     unsigned i;
  162.     unsigned type;
  163.  
  164. #if CONFIG_D3D11VA
  165.     if (avctx->pix_fmt == AV_PIX_FMT_D3D11VA_VLD) {
  166.         type = D3D11_VIDEO_DECODER_BUFFER_BITSTREAM;
  167.         if (FAILED(ID3D11VideoContext_GetDecoderBuffer(D3D11VA_CONTEXT(ctx)->video_context,
  168.                                                        D3D11VA_CONTEXT(ctx)->decoder,
  169.                                                        type,
  170.                                                        &dxva_size, &dxva_data_ptr)))
  171.             return -1;
  172.     }
  173. #endif
  174. #if CONFIG_DXVA2
  175.     if (avctx->pix_fmt == AV_PIX_FMT_DXVA2_VLD) {
  176.         type = DXVA2_BitStreamDateBufferType;
  177.         if (FAILED(IDirectXVideoDecoder_GetBuffer(DXVA2_CONTEXT(ctx)->decoder,
  178.                                                   type,
  179.                                                   &dxva_data_ptr, &dxva_size)))
  180.             return -1;
  181.     }
  182. #endif
  183.  
  184.     dxva_data = dxva_data_ptr;
  185.     current = dxva_data;
  186.     end = dxva_data + dxva_size;
  187.  
  188.     for (i = 0; i < ctx_pic->slice_count; i++) {
  189.         DXVA_SliceInfo *slice = &ctx_pic->slice[i];
  190.         unsigned position = slice->dwSliceDataLocation;
  191.         unsigned size     = slice->dwSliceBitsInBuffer / 8;
  192.         if (size > end - current) {
  193.             av_log(avctx, AV_LOG_ERROR, "Failed to build bitstream");
  194.             break;
  195.         }
  196.         slice->dwSliceDataLocation = current - dxva_data;
  197.  
  198.         if (i < ctx_pic->slice_count - 1)
  199.             slice->wNumberMBsInSlice =
  200.                 slice[1].wNumberMBsInSlice - slice[0].wNumberMBsInSlice;
  201.         else
  202.             slice->wNumberMBsInSlice =
  203.                 mb_count - slice[0].wNumberMBsInSlice;
  204.  
  205.         memcpy(current, &ctx_pic->bitstream[position], size);
  206.         current += size;
  207.     }
  208. #if CONFIG_D3D11VA
  209.     if (avctx->pix_fmt == AV_PIX_FMT_D3D11VA_VLD)
  210.         if (FAILED(ID3D11VideoContext_ReleaseDecoderBuffer(D3D11VA_CONTEXT(ctx)->video_context, D3D11VA_CONTEXT(ctx)->decoder, type)))
  211.             return -1;
  212. #endif
  213. #if CONFIG_DXVA2
  214.     if (avctx->pix_fmt == AV_PIX_FMT_DXVA2_VLD)
  215.         if (FAILED(IDirectXVideoDecoder_ReleaseBuffer(DXVA2_CONTEXT(ctx)->decoder, type)))
  216.             return -1;
  217. #endif
  218.     if (i < ctx_pic->slice_count)
  219.         return -1;
  220.  
  221. #if CONFIG_D3D11VA
  222.     if (avctx->pix_fmt == AV_PIX_FMT_D3D11VA_VLD) {
  223.         D3D11_VIDEO_DECODER_BUFFER_DESC *dsc11 = bs;
  224.         memset(dsc11, 0, sizeof(*dsc11));
  225.         dsc11->BufferType           = type;
  226.         dsc11->DataSize             = current - dxva_data;
  227.         dsc11->NumMBsInBuffer       = mb_count;
  228.  
  229.         type = D3D11_VIDEO_DECODER_BUFFER_SLICE_CONTROL;
  230.     }
  231. #endif
  232. #if CONFIG_DXVA2
  233.     if (avctx->pix_fmt == AV_PIX_FMT_DXVA2_VLD) {
  234.         DXVA2_DecodeBufferDesc *dsc2 = bs;
  235.         memset(dsc2, 0, sizeof(*dsc2));
  236.         dsc2->CompressedBufferType = type;
  237.         dsc2->DataSize             = current - dxva_data;
  238.         dsc2->NumMBsInBuffer       = mb_count;
  239.  
  240.         type = DXVA2_SliceControlBufferType;
  241.     }
  242. #endif
  243.  
  244.     return ff_dxva2_commit_buffer(avctx, ctx, sc,
  245.                                   type,
  246.                                   ctx_pic->slice,
  247.                                   ctx_pic->slice_count * sizeof(*ctx_pic->slice),
  248.                                   mb_count);
  249. }
  250.  
  251. static int dxva2_mpeg2_start_frame(AVCodecContext *avctx,
  252.                                    av_unused const uint8_t *buffer,
  253.                                    av_unused uint32_t size)
  254. {
  255.     const struct MpegEncContext *s = avctx->priv_data;
  256.     AVDXVAContext *ctx = avctx->hwaccel_context;
  257.     struct dxva2_picture_context *ctx_pic =
  258.         s->current_picture_ptr->hwaccel_picture_private;
  259.  
  260.     if (DXVA_CONTEXT_DECODER(avctx, ctx) == NULL ||
  261.         DXVA_CONTEXT_CFG(avctx, ctx) == NULL ||
  262.         DXVA_CONTEXT_COUNT(avctx, ctx) <= 0)
  263.         return -1;
  264.     assert(ctx_pic);
  265.  
  266.     fill_picture_parameters(avctx, ctx, s, &ctx_pic->pp);
  267.     fill_quantization_matrices(avctx, ctx, s, &ctx_pic->qm);
  268.  
  269.     ctx_pic->slice_count    = 0;
  270.     ctx_pic->bitstream_size = 0;
  271.     ctx_pic->bitstream      = NULL;
  272.     return 0;
  273. }
  274.  
  275. static int dxva2_mpeg2_decode_slice(AVCodecContext *avctx,
  276.                                     const uint8_t *buffer, uint32_t size)
  277. {
  278.     const struct MpegEncContext *s = avctx->priv_data;
  279.     struct dxva2_picture_context *ctx_pic =
  280.         s->current_picture_ptr->hwaccel_picture_private;
  281.     unsigned position;
  282.  
  283.     if (ctx_pic->slice_count >= MAX_SLICES) {
  284.         avpriv_request_sample(avctx, "%d slices in dxva2",
  285.                               ctx_pic->slice_count);
  286.         return -1;
  287.     }
  288.     if (!ctx_pic->bitstream)
  289.         ctx_pic->bitstream = buffer;
  290.     ctx_pic->bitstream_size += size;
  291.  
  292.     position = buffer - ctx_pic->bitstream;
  293.     fill_slice(avctx, s, &ctx_pic->slice[ctx_pic->slice_count++], position,
  294.                buffer, size);
  295.     return 0;
  296. }
  297.  
  298. static int dxva2_mpeg2_end_frame(AVCodecContext *avctx)
  299. {
  300.     struct MpegEncContext *s = avctx->priv_data;
  301.     struct dxva2_picture_context *ctx_pic =
  302.         s->current_picture_ptr->hwaccel_picture_private;
  303.     int ret;
  304.  
  305.     if (ctx_pic->slice_count <= 0 || ctx_pic->bitstream_size <= 0)
  306.         return -1;
  307.     ret = ff_dxva2_common_end_frame(avctx, s->current_picture_ptr->f,
  308.                                     &ctx_pic->pp, sizeof(ctx_pic->pp),
  309.                                     &ctx_pic->qm, sizeof(ctx_pic->qm),
  310.                                     commit_bitstream_and_slice_buffer);
  311.     if (!ret)
  312.         ff_mpeg_draw_horiz_band(s, 0, avctx->height);
  313.     return ret;
  314. }
  315.  
  316. #if CONFIG_MPEG2_DXVA2_HWACCEL
  317. AVHWAccel ff_mpeg2_dxva2_hwaccel = {
  318.     .name           = "mpeg2_dxva2",
  319.     .type           = AVMEDIA_TYPE_VIDEO,
  320.     .id             = AV_CODEC_ID_MPEG2VIDEO,
  321.     .pix_fmt        = AV_PIX_FMT_DXVA2_VLD,
  322.     .start_frame    = dxva2_mpeg2_start_frame,
  323.     .decode_slice   = dxva2_mpeg2_decode_slice,
  324.     .end_frame      = dxva2_mpeg2_end_frame,
  325.     .frame_priv_data_size = sizeof(struct dxva2_picture_context),
  326. };
  327. #endif
  328.  
  329. #if CONFIG_MPEG2_D3D11VA_HWACCEL
  330. AVHWAccel ff_mpeg2_d3d11va_hwaccel = {
  331.     .name           = "mpeg2_d3d11va",
  332.     .type           = AVMEDIA_TYPE_VIDEO,
  333.     .id             = AV_CODEC_ID_MPEG2VIDEO,
  334.     .pix_fmt        = AV_PIX_FMT_D3D11VA_VLD,
  335.     .start_frame    = dxva2_mpeg2_start_frame,
  336.     .decode_slice   = dxva2_mpeg2_decode_slice,
  337.     .end_frame      = dxva2_mpeg2_end_frame,
  338.     .frame_priv_data_size = sizeof(struct dxva2_picture_context),
  339. };
  340. #endif
  341.