Revision 85167c46 libavcodec/dxva2_h264.c

View differences:

libavcodec/dxva2_h264.c
20 20
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21 21
 */
22 22

  
23
#include "dxva2.h"
24
#include "avcodec.h"
25

  
26
#include "mpegvideo.h"
23
#include "dxva2_internal.h"
27 24
#include "h264.h"
28 25
#include "h264data.h"
29 26

  
......
37 34
    unsigned              bitstream_size;
38 35
};
39 36

  
40
static void *ff_dxva2_get_surface(const Picture *picture)
41
{
42
    return picture->data[3];
43
}
44
static unsigned ff_dxva2_get_surface_index(const struct dxva_context *ctx,
45
                                           const Picture *picture)
46
{
47
    void *surface = ff_dxva2_get_surface(picture);
48
    unsigned i;
49

  
50
    for (i = 0; i < ctx->surface_count; i++)
51
        if (ctx->surface[i] == surface)
52
            return i;
53

  
54
    assert(0);
55
    return 0;
56
}
57

  
58 37
static void fill_picture_entry(DXVA_PicEntry_H264 *pic,
59 38
                               unsigned index, unsigned flag)
60 39
{
......
277 256
    slice->slice_id = h->current_slice - 1;
278 257
}
279 258

  
280
static int ff_dxva2_commit_buffer(AVCodecContext *avctx,
281
                                  struct dxva_context *ctx,
282
                                  DXVA2_DecodeBufferDesc *dsc,
283
                                  unsigned type, const void *data, unsigned size,
284
                                  unsigned mb_count)
285
{
286
    void     *dxva_data;
287
    unsigned dxva_size;
288
    int      result;
289

  
290
    if (FAILED(IDirectXVideoDecoder_GetBuffer(ctx->decoder, type,
291
                                              &dxva_data, &dxva_size))) {
292
        av_log(avctx, AV_LOG_ERROR, "Failed to get a buffer for %d\n", type);
293
        return -1;
294
    }
295
    if (size <= dxva_size) {
296
        memcpy(dxva_data, data, size);
297

  
298
        memset(dsc, 0, sizeof(*dsc));
299
        dsc->CompressedBufferType = type;
300
        dsc->DataSize             = size;
301
        dsc->NumMBsInBuffer       = mb_count;
302

  
303
        result = 0;
304
    } else {
305
        av_log(avctx, AV_LOG_ERROR, "Buffer for type %d was too small\n", type);
306
        result = -1;
307
    }
308
    if (FAILED(IDirectXVideoDecoder_ReleaseBuffer(ctx->decoder, type))) {
309
        av_log(avctx, AV_LOG_ERROR, "Failed to release buffer type %d\n", type);
310
        result = -1;
311
    }
312
    return result;
313
}
314

  
315 259
static int commit_bitstream_and_slice_buffer(AVCodecContext *avctx,
316 260
                                             DXVA2_DecodeBufferDesc *bs,
317 261
                                             DXVA2_DecodeBufferDesc *sc)
......
464 408
    return 0;
465 409
}
466 410

  
467
static int ff_dxva2_common_end_frame(AVCodecContext *avctx, MpegEncContext *s,
468
                                     const void *pp, unsigned pp_size,
469
                                     const void *qm, unsigned qm_size,
470
                                     int (*commit_bs_si)(AVCodecContext *,
471
                                                         DXVA2_DecodeBufferDesc *bs,
472
                                                         DXVA2_DecodeBufferDesc *slice))
473
{
474
    struct dxva_context *ctx = avctx->hwaccel_context;
475
    unsigned               buffer_count = 0;
476
    DXVA2_DecodeBufferDesc buffer[4];
477
    DXVA2_DecodeExecuteParams exec;
478
    int      result;
479

  
480
    if (FAILED(IDirectXVideoDecoder_BeginFrame(ctx->decoder,
481
                                               ff_dxva2_get_surface(s->current_picture_ptr),
482
                                               NULL))) {
483
        av_log(avctx, AV_LOG_ERROR, "Failed to begin frame\n");
484
        return -1;
485
    }
486

  
487
    result = ff_dxva2_commit_buffer(avctx, ctx, &buffer[buffer_count],
488
                                    DXVA2_PictureParametersBufferType,
489
                                    pp, pp_size, 0);
490
    if (result) {
491
        av_log(avctx, AV_LOG_ERROR,
492
               "Failed to add picture parameter buffer\n");
493
        goto end;
494
    }
495
    buffer_count++;
496

  
497
    if (qm_size > 0) {
498
        result = ff_dxva2_commit_buffer(avctx, ctx, &buffer[buffer_count],
499
                                        DXVA2_InverseQuantizationMatrixBufferType,
500
                                        qm, qm_size, 0);
501
        if (result) {
502
            av_log(avctx, AV_LOG_ERROR,
503
                   "Failed to add inverse quantization matrix buffer\n");
504
            goto end;
505
        }
506
        buffer_count++;
507
    }
508

  
509
    result = commit_bs_si(avctx,
510
                          &buffer[buffer_count + 0],
511
                          &buffer[buffer_count + 1]);
512
    if (result) {
513
        av_log(avctx, AV_LOG_ERROR,
514
               "Failed to add bitstream or slice control buffer\n");
515
        goto end;
516
    }
517
    buffer_count += 2;
518

  
519
    /* TODO Film Grain when possible */
520

  
521
    assert(buffer_count == 1 + (qm_size > 0) + 2);
522

  
523
    memset(&exec, 0, sizeof(exec));
524
    exec.NumCompBuffers      = buffer_count;
525
    exec.pCompressedBuffers  = buffer;
526
    exec.pExtensionData      = NULL;
527
    if (FAILED(IDirectXVideoDecoder_Execute(ctx->decoder, &exec))) {
528
        av_log(avctx, AV_LOG_ERROR, "Failed to execute\n");
529
        result = -1;
530
    }
531

  
532
end:
533
    if (FAILED(IDirectXVideoDecoder_EndFrame(ctx->decoder, NULL))) {
534
        av_log(avctx, AV_LOG_ERROR, "Failed to end frame\n");
535
        result = -1;
536
    }
537

  
538
    if (!result)
539
        ff_draw_horiz_band(s, 0, s->avctx->height);
540
    return result;
541
}
542

  
543 411
static int end_frame(AVCodecContext *avctx)
544 412
{
545 413
    H264Context *h = avctx->priv_data;

Also available in: Unified diff