annotate dxva2.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 9f771d4312ed
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
10952
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
1 /*
10980
9f771d4312ed Moved reusable functions from dxva2_h264.c to dxva2.c
fenrir
parents: 10979
diff changeset
2 * DXVA2 HW acceleration.
10952
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
3 *
10980
9f771d4312ed Moved reusable functions from dxva2_h264.c to dxva2.c
fenrir
parents: 10979
diff changeset
4 * copyright (c) 2010 Laurent Aimar
10952
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
5 *
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
6 * This file is part of FFmpeg.
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
7 *
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
8 * FFmpeg is free software; you can redistribute it and/or
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
9 * modify it under the terms of the GNU Lesser General Public
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
10 * License as published by the Free Software Foundation; either
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
11 * version 2.1 of the License, or (at your option) any later version.
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
12 *
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
13 * FFmpeg is distributed in the hope that it will be useful,
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
16 * Lesser General Public License for more details.
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
17 *
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
18 * You should have received a copy of the GNU Lesser General Public
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
19 * License along with FFmpeg; if not, write to the Free Software
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
21 */
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
22
10980
9f771d4312ed Moved reusable functions from dxva2_h264.c to dxva2.c
fenrir
parents: 10979
diff changeset
23 #include "dxva2_internal.h"
10952
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
24
10980
9f771d4312ed Moved reusable functions from dxva2_h264.c to dxva2.c
fenrir
parents: 10979
diff changeset
25 void *ff_dxva2_get_surface(const Picture *picture)
10952
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
26 {
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
27 return picture->data[3];
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
28 }
10980
9f771d4312ed Moved reusable functions from dxva2_h264.c to dxva2.c
fenrir
parents: 10979
diff changeset
29
9f771d4312ed Moved reusable functions from dxva2_h264.c to dxva2.c
fenrir
parents: 10979
diff changeset
30 unsigned ff_dxva2_get_surface_index(const struct dxva_context *ctx,
9f771d4312ed Moved reusable functions from dxva2_h264.c to dxva2.c
fenrir
parents: 10979
diff changeset
31 const Picture *picture)
10952
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
32 {
10976
b3e3f5cb4b46 Added ff_dxva2_ prefix to get_surface(_index) and commit_buffer functions.
fenrir
parents: 10975
diff changeset
33 void *surface = ff_dxva2_get_surface(picture);
10952
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
34 unsigned i;
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
35
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
36 for (i = 0; i < ctx->surface_count; i++)
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
37 if (ctx->surface[i] == surface)
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
38 return i;
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
39
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
40 assert(0);
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
41 return 0;
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
42 }
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
43
10980
9f771d4312ed Moved reusable functions from dxva2_h264.c to dxva2.c
fenrir
parents: 10979
diff changeset
44 int ff_dxva2_commit_buffer(AVCodecContext *avctx,
9f771d4312ed Moved reusable functions from dxva2_h264.c to dxva2.c
fenrir
parents: 10979
diff changeset
45 struct dxva_context *ctx,
9f771d4312ed Moved reusable functions from dxva2_h264.c to dxva2.c
fenrir
parents: 10979
diff changeset
46 DXVA2_DecodeBufferDesc *dsc,
9f771d4312ed Moved reusable functions from dxva2_h264.c to dxva2.c
fenrir
parents: 10979
diff changeset
47 unsigned type, const void *data, unsigned size,
9f771d4312ed Moved reusable functions from dxva2_h264.c to dxva2.c
fenrir
parents: 10979
diff changeset
48 unsigned mb_count)
10952
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
49 {
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
50 void *dxva_data;
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
51 unsigned dxva_size;
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
52 int result;
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
53
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
54 if (FAILED(IDirectXVideoDecoder_GetBuffer(ctx->decoder, type,
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
55 &dxva_data, &dxva_size))) {
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
56 av_log(avctx, AV_LOG_ERROR, "Failed to get a buffer for %d\n", type);
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
57 return -1;
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
58 }
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
59 if (size <= dxva_size) {
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
60 memcpy(dxva_data, data, size);
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
61
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
62 memset(dsc, 0, sizeof(*dsc));
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
63 dsc->CompressedBufferType = type;
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
64 dsc->DataSize = size;
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
65 dsc->NumMBsInBuffer = mb_count;
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
66
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
67 result = 0;
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
68 } else {
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
69 av_log(avctx, AV_LOG_ERROR, "Buffer for type %d was too small\n", type);
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
70 result = -1;
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
71 }
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
72 if (FAILED(IDirectXVideoDecoder_ReleaseBuffer(ctx->decoder, type))) {
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
73 av_log(avctx, AV_LOG_ERROR, "Failed to release buffer type %d\n", type);
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
74 result = -1;
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
75 }
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
76 return result;
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
77 }
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
78
10980
9f771d4312ed Moved reusable functions from dxva2_h264.c to dxva2.c
fenrir
parents: 10979
diff changeset
79 int ff_dxva2_common_end_frame(AVCodecContext *avctx, MpegEncContext *s,
9f771d4312ed Moved reusable functions from dxva2_h264.c to dxva2.c
fenrir
parents: 10979
diff changeset
80 const void *pp, unsigned pp_size,
9f771d4312ed Moved reusable functions from dxva2_h264.c to dxva2.c
fenrir
parents: 10979
diff changeset
81 const void *qm, unsigned qm_size,
9f771d4312ed Moved reusable functions from dxva2_h264.c to dxva2.c
fenrir
parents: 10979
diff changeset
82 int (*commit_bs_si)(AVCodecContext *,
9f771d4312ed Moved reusable functions from dxva2_h264.c to dxva2.c
fenrir
parents: 10979
diff changeset
83 DXVA2_DecodeBufferDesc *bs,
9f771d4312ed Moved reusable functions from dxva2_h264.c to dxva2.c
fenrir
parents: 10979
diff changeset
84 DXVA2_DecodeBufferDesc *slice))
10952
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
85 {
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
86 struct dxva_context *ctx = avctx->hwaccel_context;
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
87 unsigned buffer_count = 0;
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
88 DXVA2_DecodeBufferDesc buffer[4];
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
89 DXVA2_DecodeExecuteParams exec;
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
90 int result;
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
91
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
92 if (FAILED(IDirectXVideoDecoder_BeginFrame(ctx->decoder,
10976
b3e3f5cb4b46 Added ff_dxva2_ prefix to get_surface(_index) and commit_buffer functions.
fenrir
parents: 10975
diff changeset
93 ff_dxva2_get_surface(s->current_picture_ptr),
10952
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
94 NULL))) {
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
95 av_log(avctx, AV_LOG_ERROR, "Failed to begin frame\n");
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
96 return -1;
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
97 }
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
98
10976
b3e3f5cb4b46 Added ff_dxva2_ prefix to get_surface(_index) and commit_buffer functions.
fenrir
parents: 10975
diff changeset
99 result = ff_dxva2_commit_buffer(avctx, ctx, &buffer[buffer_count],
b3e3f5cb4b46 Added ff_dxva2_ prefix to get_surface(_index) and commit_buffer functions.
fenrir
parents: 10975
diff changeset
100 DXVA2_PictureParametersBufferType,
b3e3f5cb4b46 Added ff_dxva2_ prefix to get_surface(_index) and commit_buffer functions.
fenrir
parents: 10975
diff changeset
101 pp, pp_size, 0);
10952
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
102 if (result) {
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
103 av_log(avctx, AV_LOG_ERROR,
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
104 "Failed to add picture parameter buffer\n");
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
105 goto end;
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
106 }
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
107 buffer_count++;
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
108
10974
b1ccfdc1b409 Moved reusable code from dxva2_h264.c:end_frame to ff_dxva2_common_end_frame.
fenrir
parents: 10952
diff changeset
109 if (qm_size > 0) {
10976
b3e3f5cb4b46 Added ff_dxva2_ prefix to get_surface(_index) and commit_buffer functions.
fenrir
parents: 10975
diff changeset
110 result = ff_dxva2_commit_buffer(avctx, ctx, &buffer[buffer_count],
b3e3f5cb4b46 Added ff_dxva2_ prefix to get_surface(_index) and commit_buffer functions.
fenrir
parents: 10975
diff changeset
111 DXVA2_InverseQuantizationMatrixBufferType,
b3e3f5cb4b46 Added ff_dxva2_ prefix to get_surface(_index) and commit_buffer functions.
fenrir
parents: 10975
diff changeset
112 qm, qm_size, 0);
10975
cec4a174365c Reindent the content of one if(){} in ff_dxva2_common_end_frame.
fenrir
parents: 10974
diff changeset
113 if (result) {
cec4a174365c Reindent the content of one if(){} in ff_dxva2_common_end_frame.
fenrir
parents: 10974
diff changeset
114 av_log(avctx, AV_LOG_ERROR,
cec4a174365c Reindent the content of one if(){} in ff_dxva2_common_end_frame.
fenrir
parents: 10974
diff changeset
115 "Failed to add inverse quantization matrix buffer\n");
cec4a174365c Reindent the content of one if(){} in ff_dxva2_common_end_frame.
fenrir
parents: 10974
diff changeset
116 goto end;
cec4a174365c Reindent the content of one if(){} in ff_dxva2_common_end_frame.
fenrir
parents: 10974
diff changeset
117 }
cec4a174365c Reindent the content of one if(){} in ff_dxva2_common_end_frame.
fenrir
parents: 10974
diff changeset
118 buffer_count++;
10974
b1ccfdc1b409 Moved reusable code from dxva2_h264.c:end_frame to ff_dxva2_common_end_frame.
fenrir
parents: 10952
diff changeset
119 }
10952
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
120
10974
b1ccfdc1b409 Moved reusable code from dxva2_h264.c:end_frame to ff_dxva2_common_end_frame.
fenrir
parents: 10952
diff changeset
121 result = commit_bs_si(avctx,
b1ccfdc1b409 Moved reusable code from dxva2_h264.c:end_frame to ff_dxva2_common_end_frame.
fenrir
parents: 10952
diff changeset
122 &buffer[buffer_count + 0],
b1ccfdc1b409 Moved reusable code from dxva2_h264.c:end_frame to ff_dxva2_common_end_frame.
fenrir
parents: 10952
diff changeset
123 &buffer[buffer_count + 1]);
10952
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
124 if (result) {
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
125 av_log(avctx, AV_LOG_ERROR,
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
126 "Failed to add bitstream or slice control buffer\n");
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
127 goto end;
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
128 }
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
129 buffer_count += 2;
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
130
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
131 /* TODO Film Grain when possible */
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
132
10974
b1ccfdc1b409 Moved reusable code from dxva2_h264.c:end_frame to ff_dxva2_common_end_frame.
fenrir
parents: 10952
diff changeset
133 assert(buffer_count == 1 + (qm_size > 0) + 2);
10952
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
134
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
135 memset(&exec, 0, sizeof(exec));
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
136 exec.NumCompBuffers = buffer_count;
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
137 exec.pCompressedBuffers = buffer;
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
138 exec.pExtensionData = NULL;
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
139 if (FAILED(IDirectXVideoDecoder_Execute(ctx->decoder, &exec))) {
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
140 av_log(avctx, AV_LOG_ERROR, "Failed to execute\n");
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
141 result = -1;
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
142 }
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
143
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
144 end:
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
145 if (FAILED(IDirectXVideoDecoder_EndFrame(ctx->decoder, NULL))) {
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
146 av_log(avctx, AV_LOG_ERROR, "Failed to end frame\n");
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
147 result = -1;
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
148 }
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
149
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
150 if (!result)
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
151 ff_draw_horiz_band(s, 0, s->avctx->height);
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
152 return result;
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
153 }
ea8f891d997d H264 DXVA2 implementation
fenrir
parents:
diff changeset
154