1 /*
2 * Intel MediaSDK QSV codec-independent code
3 *
4 * copyright (c) 2013 Luca Barbato
5 * copyright (c) 2015 Anton Khirnov <anton@khirnov.net>
6 *
7 * This file is part of FFmpeg.
8 *
9 * FFmpeg is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Lesser General Public
11 * License as published by the Free Software Foundation; either
12 * version 2.1 of the License, or (at your option) any later version.
13 *
14 * FFmpeg is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * Lesser General Public License for more details.
18 *
19 * You should have received a copy of the GNU Lesser General Public
20 * License along with FFmpeg; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
22 */
23
24 #include <string.h>
25 #include <sys/types.h>
26
27 #include <mfx/mfxvideo.h>
28
34
38
40 {
41 switch (mfx_err) {
42 case MFX_ERR_NONE:
43 return 0;
44 case MFX_ERR_MEMORY_ALLOC:
45 case MFX_ERR_NOT_ENOUGH_BUFFER:
47 case MFX_ERR_INVALID_HANDLE:
49 case MFX_ERR_DEVICE_FAILED:
50 case MFX_ERR_DEVICE_LOST:
51 case MFX_ERR_LOCK_MEMORY:
53 case MFX_ERR_NULL_PTR:
54 case MFX_ERR_UNDEFINED_BEHAVIOR:
55 case MFX_ERR_NOT_INITIALIZED:
57 case MFX_ERR_UNSUPPORTED:
58 case MFX_ERR_NOT_FOUND:
60 case MFX_ERR_MORE_DATA:
61 case MFX_ERR_MORE_SURFACE:
62 case MFX_ERR_MORE_BITSTREAM:
64 case MFX_ERR_INCOMPATIBLE_VIDEO_PARAM:
65 case MFX_ERR_INVALID_VIDEO_PARAM:
67 case MFX_ERR_ABORTED:
68 case MFX_ERR_UNKNOWN:
69 default:
71 }
72 }
73
75 {
76 switch (format) {
80 default:
82 }
83 }
84
86 {
87 switch (codec_id) {
89 return MFX_CODEC_AVC;
92 return MFX_CODEC_MPEG2;
94 return MFX_CODEC_VC1;
95 default:
96 break;
97 }
98
100 }
101
103 {
104 if (!session) {
106 mfxIMPL impl = MFX_IMPL_AUTO_ANY;
108
109 const char *desc;
111
113 if (ret < 0) {
116 }
117
119
120 if (impl & MFX_IMPL_SOFTWARE)
121 desc = "software";
122 else if (impl & MFX_IMPL_HARDWARE)
123 desc = "hardware accelerated";
124 else
125 desc = "unknown";
126
128 "Initialized an internal MFX session using %s implementation\n",
129 desc);
130 }
131
133 } else {
135 }
136
137 /* make sure the decoder is uninitialized */
138 MFXVideoDECODE_Close(q->
session);
139
140 return 0;
141 }
142
144 {
145 mfxVideoParam param = { { 0 } };
147
149 if (ret < 0) {
152 }
153
154
156 if (ret < 0)
158
159 param.mfx.CodecId =
ret;
160 param.mfx.CodecProfile = avctx->
profile;
161 param.mfx.CodecLevel = avctx->
level;
162
163 param.mfx.FrameInfo.BitDepthLuma = 8;
164 param.mfx.FrameInfo.BitDepthChroma = 8;
165 param.mfx.FrameInfo.Shift = 0;
166 param.mfx.FrameInfo.FourCC = MFX_FOURCC_NV12;
169 param.mfx.FrameInfo.ChromaFormat = MFX_CHROMAFORMAT_YUV420;
170
175
176 ret = MFXVideoDECODE_Init(q->
session, ¶m);
177 if (ret < 0) {
180 }
181
182 return 0;
183 }
184
186 {
188
190 if (ret < 0)
192
195 } else {
202
206
208 }
209
210 return 0;
211 }
212
214 {
216 while (cur) {
220 }
222 }
223 }
224
226 {
229
231
234 while (frame) {
237 if (ret < 0)
240 return 0;
241 }
242
245 }
246
248 if (!frame)
254 }
256
258 if (ret < 0)
260
262
263 return 0;
264 }
265
267 {
269 while (cur) {
273 }
275 }
276
280 {
281 mfxFrameSurface1 *insurf;
282 mfxFrameSurface1 *outsurf;
283 mfxSyncPoint sync;
284 mfxBitstream bs = { { { 0 } } };
286
288 bs.Data = avpkt->
data;
289 bs.DataLength = avpkt->
size;
290 bs.MaxLength = bs.DataLength;
291 bs.TimeStamp = avpkt->
pts;
292 }
293
294 do {
296 if (ret < 0)
298
299 ret = MFXVideoDECODE_DecodeFrameAsync(q->
session, avpkt->
size ? &bs :
NULL,
300 insurf, &outsurf, &sync);
301 if (ret == MFX_WRN_DEVICE_BUSY)
303
304 } while (ret == MFX_WRN_DEVICE_BUSY || ret == MFX_ERR_MORE_SURFACE);
305
306 if (ret != MFX_ERR_NONE &&
307 ret != MFX_ERR_MORE_DATA &&
308 ret != MFX_WRN_VIDEO_PARAM_CHANGED &&
309 ret != MFX_ERR_MORE_SURFACE) {
312 }
313
314 if (sync) {
316
317 MFXVideoCORE_SyncOperation(q->
session, sync, 60000);
318
320 if (!src_frame) {
322 "The returned surface does not correspond to any frame\n");
324 }
325
327 if (ret < 0)
329
330 frame->
pkt_pts = frame->
pts = outsurf->Data.TimeStamp;
331
333 outsurf->Info.PicStruct & MFX_PICSTRUCT_FRAME_TRIPLING ? 4 :
334 outsurf->Info.PicStruct & MFX_PICSTRUCT_FRAME_DOUBLING ? 2 :
335 outsurf->Info.PicStruct & MFX_PICSTRUCT_FIELD_REPEATED ? 1 : 0;
337 outsurf->Info.PicStruct & MFX_PICSTRUCT_FIELD_TFF;
339 !(outsurf->Info.PicStruct & MFX_PICSTRUCT_PROGRESSIVE);
340
341 *got_frame = 1;
342 }
343
344 return bs.DataOffset;
345 }
346
348 {
350
351 while (cur) {
356 }
357
360
361 return 0;
362 }