1 // Copyright (c) 2017-2020 Intel Corporation
2 //
3 // Permission is hereby granted, free of charge, to any person obtaining a copy
4 // of this software and associated documentation files (the "Software"), to deal
5 // in the Software without restriction, including without limitation the rights
6 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7 // copies of the Software, and to permit persons to whom the Software is
8 // furnished to do so, subject to the following conditions:
9 //
10 // The above copyright notice and this permission notice shall be included in all
11 // copies or substantial portions of the Software.
12 //
13 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
19 // SOFTWARE.
20
21 #include "mfx_common.h"
22 #if defined (MFX_ENABLE_MJPEG_VIDEO_ENCODE)
23
24 #include "mfx_mjpeg_encode_hw_utils.h"
25 #include "libmfx_core_factory.h"
26 #include "libmfx_core_interface.h"
27 #include "jpegbase.h"
28 #include "mfx_enc_common.h"
29 #include "mfx_mjpeg_encode_interface.h"
30
31 using namespace MfxHwMJpegEncode;
32
33
QueryHwCaps(VideoCORE * core,JpegEncCaps & hwCaps)34 mfxStatus MfxHwMJpegEncode::QueryHwCaps(VideoCORE * core, JpegEncCaps & hwCaps)
35 {
36 MFX_CHECK_NULL_PTR1(core);
37
38 if (core->GetVAType() == MFX_HW_VAAPI && core->GetHWType() < MFX_HW_CHT)
39 return MFX_ERR_UNSUPPORTED;
40
41 std::unique_ptr<DriverEncoder> ddi;
42 ddi.reset( CreatePlatformMJpegEncoder(core) );
43 if (ddi.get() == 0)
44 return MFX_ERR_NULL_PTR;
45
46 // the device is created just to query caps,
47 // so width/height are insignificant
48 mfxStatus sts = ddi->CreateAuxilliaryDevice(core, 640, 480, true);
49 MFX_CHECK_STS(sts);
50
51 sts = ddi->QueryEncodeCaps(hwCaps);
52 MFX_CHECK_STS(sts);
53
54 return MFX_ERR_NONE;
55 }
56
IsJpegParamExtBufferIdSupported(mfxU32 id)57 bool MfxHwMJpegEncode::IsJpegParamExtBufferIdSupported(mfxU32 id)
58 {
59 return
60 id == MFX_EXTBUFF_OPAQUE_SURFACE_ALLOCATION ||
61 id == MFX_EXTBUFF_JPEG_QT ||
62 id == MFX_EXTBUFF_JPEG_HUFFMAN;
63 }
64
CheckExtBufferId(mfxVideoParam const & par)65 mfxStatus MfxHwMJpegEncode::CheckExtBufferId(mfxVideoParam const & par)
66 {
67 for (mfxU32 i = 0; i < par.NumExtParam; i++)
68 {
69 if (par.ExtParam[i] == 0)
70 return MFX_ERR_INVALID_VIDEO_PARAM;
71
72 if (!IsJpegParamExtBufferIdSupported(par.ExtParam[i]->BufferId))
73 return MFX_ERR_INVALID_VIDEO_PARAM;
74
75 // check if buffer presents twice in video param
76 if (GetExtBuffer(
77 par.ExtParam + i + 1,
78 par.NumExtParam - i - 1,
79 par.ExtParam[i]->BufferId) != 0)
80 {
81 return MFX_ERR_INVALID_VIDEO_PARAM;
82 }
83 }
84
85 return MFX_ERR_NONE;
86 }
87
CheckJpegParam(VideoCORE * core,mfxVideoParam & par,JpegEncCaps const & hwCaps)88 mfxStatus MfxHwMJpegEncode::CheckJpegParam(VideoCORE *core, mfxVideoParam & par, JpegEncCaps const & hwCaps)
89 {
90 MFX_CHECK(core, MFX_ERR_UNDEFINED_BEHAVIOR);
91 MFX_CHECK(hwCaps.Baseline, MFX_ERR_INCOMPATIBLE_VIDEO_PARAM);
92 MFX_CHECK(hwCaps.Sequential, MFX_ERR_INCOMPATIBLE_VIDEO_PARAM);
93 MFX_CHECK(hwCaps.Huffman, MFX_ERR_INCOMPATIBLE_VIDEO_PARAM);
94
95 MFX_CHECK((par.mfx.Interleaved && hwCaps.Interleaved) || (!par.mfx.Interleaved && hwCaps.NonInterleaved),
96 MFX_WRN_PARTIAL_ACCELERATION);
97
98 MFX_CHECK(par.mfx.FrameInfo.Width > 0 && par.mfx.FrameInfo.Height > 0,
99 MFX_ERR_INCOMPATIBLE_VIDEO_PARAM);
100
101 mfxF64 BytesPerPx = 0;
102 switch (par.mfx.FrameInfo.FourCC)
103 {
104 case MFX_FOURCC_NV12:
105 case MFX_FOURCC_YV12:
106 BytesPerPx = 1.5;
107 break;
108 case MFX_FOURCC_YUY2:
109 BytesPerPx = 2;
110 break;
111 case MFX_FOURCC_RGB4:
112 default:
113 BytesPerPx = 4;
114 }
115 if (core->GetVAType() == MFX_HW_D3D9)
116 {
117 MFX_CHECK(par.mfx.FrameInfo.Height <= hwCaps.MaxPicWidth/BytesPerPx, MFX_WRN_PARTIAL_ACCELERATION );
118 }
119
120 MFX_CHECK(par.mfx.FrameInfo.Width <= (mfxU16)hwCaps.MaxPicWidth && par.mfx.FrameInfo.Height <= (mfxU16)hwCaps.MaxPicHeight,
121 MFX_WRN_PARTIAL_ACCELERATION);
122
123 MFX_CHECK(hwCaps.SampleBitDepth == 8, MFX_ERR_INCOMPATIBLE_VIDEO_PARAM);
124 MFX_CHECK(hwCaps.MaxNumComponent == 3, MFX_ERR_INCOMPATIBLE_VIDEO_PARAM);
125 MFX_CHECK(hwCaps.MaxNumScan >= 1, MFX_WRN_PARTIAL_ACCELERATION);
126
127 mfxStatus sts = CheckExtBufferId(par);
128 if (sts != MFX_ERR_NONE)
129 return MFX_WRN_PARTIAL_ACCELERATION;
130
131 mfxExtJPEGQuantTables* qt_in = (mfxExtJPEGQuantTables*)GetExtBuffer( par.ExtParam, par.NumExtParam, MFX_EXTBUFF_JPEG_QT );
132 mfxExtJPEGHuffmanTables* ht_in = (mfxExtJPEGHuffmanTables*)GetExtBuffer( par.ExtParam, par.NumExtParam, MFX_EXTBUFF_JPEG_HUFFMAN );
133
134 if (qt_in && qt_in->NumTable > hwCaps.MaxNumQuantTable)
135 return MFX_WRN_PARTIAL_ACCELERATION;
136 if (ht_in && (ht_in->NumDCTable > hwCaps.MaxNumHuffTable || ht_in->NumACTable > hwCaps.MaxNumHuffTable))
137 return MFX_WRN_PARTIAL_ACCELERATION;
138
139 return MFX_ERR_NONE;
140 }
141
FastCopyFrameBufferSys2Vid(VideoCORE * core,mfxMemId vidMemId,mfxFrameData & sysSurf,mfxFrameInfo & frmInfo)142 mfxStatus MfxHwMJpegEncode::FastCopyFrameBufferSys2Vid(
143 VideoCORE * core,
144 mfxMemId vidMemId,
145 mfxFrameData & sysSurf,
146 mfxFrameInfo & frmInfo
147 )
148 {
149 MFX_CHECK_NULL_PTR1(core);
150 mfxFrameData vidSurf = {};
151 mfxStatus sts = MFX_ERR_NONE;
152 vidSurf.MemId = vidMemId;
153
154 {
155 MFX_AUTO_LTRACE(MFX_TRACE_LEVEL_INTERNAL, "Copy input (sys->vid)");
156 mfxFrameSurface1 surfSrc = { {0,}, frmInfo, sysSurf };
157 mfxFrameSurface1 surfDst = { {0,}, frmInfo, vidSurf };
158 sts = core->DoFastCopyWrapper(&surfDst,MFX_MEMTYPE_INTERNAL_FRAME|MFX_MEMTYPE_VIDEO_MEMORY_DECODER_TARGET, &surfSrc,MFX_MEMTYPE_EXTERNAL_FRAME|MFX_MEMTYPE_SYSTEM_MEMORY);
159 MFX_CHECK_STS(sts);
160 }
161 MFX_CHECK_STS(sts);
162
163 return sts;
164 }
165
Init(mfxVideoParam const * par,mfxEncodeCtrl const * ctrl,JpegEncCaps const * hwCaps)166 mfxStatus ExecuteBuffers::Init(mfxVideoParam const *par, mfxEncodeCtrl const * ctrl, JpegEncCaps const * hwCaps)
167 {
168 mfxStatus sts = MFX_ERR_NONE;
169
170 mfxU32 fourCC = par->mfx.FrameInfo.FourCC;
171 mfxU16 chromaFormat = par->mfx.FrameInfo.ChromaFormat;
172
173 mfxExtJPEGQuantTables* jpegQT = NULL;
174 mfxExtJPEGHuffmanTables* jpegHT = NULL;
175 if (ctrl && ctrl->ExtParam && ctrl->NumExtParam > 0)
176 {
177 jpegQT = (mfxExtJPEGQuantTables*) GetExtBuffer( ctrl->ExtParam, ctrl->NumExtParam, MFX_EXTBUFF_JPEG_QT );
178 jpegHT = (mfxExtJPEGHuffmanTables*) GetExtBuffer( ctrl->ExtParam, ctrl->NumExtParam, MFX_EXTBUFF_JPEG_HUFFMAN );
179 }
180
181 mfxExtJPEGQuantTables* jpegQTInitial = (mfxExtJPEGQuantTables*) GetExtBuffer( par->ExtParam, par->NumExtParam, MFX_EXTBUFF_JPEG_QT );
182 mfxExtJPEGHuffmanTables* jpegHTInitial = (mfxExtJPEGHuffmanTables*) GetExtBuffer( par->ExtParam, par->NumExtParam, MFX_EXTBUFF_JPEG_HUFFMAN );
183
184 m_payload_base.length = 0;
185 m_payload_list.clear();
186 if (fourCC == MFX_FOURCC_RGB4 && chromaFormat == MFX_CHROMAFORMAT_YUV444)
187 {
188 m_app14_data.header = 0xEEFF;//APP14
189 m_app14_data.lenH = 0;
190 m_app14_data.lenL = 14;
191 m_app14_data.s[0] = 0x41;//"A"
192 m_app14_data.s[1] = 0x64;//"D"
193 m_app14_data.s[2] = 0x6F;//"O"
194 m_app14_data.s[3] = 0x62;//"B"
195 m_app14_data.s[4] = 0x65;//"E"
196 m_app14_data.versionH = 0;
197 m_app14_data.versionL = 0x64;
198 m_app14_data.flags0H = 0;
199 m_app14_data.flags0L = 0;
200 m_app14_data.flags1H = 0;
201 m_app14_data.flags1L = 0;
202 m_app14_data.transform = 0; //RGB
203
204 mfxU32 payloadSize = 16;
205 if (m_payload_base.length + payloadSize > m_payload_base.maxLength)
206 {
207 mfxU8* data = new mfxU8[m_payload_base.length + payloadSize];
208 std::copy(m_payload_base.data, m_payload_base.data + m_payload_base.length, data);
209 delete[] m_payload_base.data;
210 m_payload_base.data = data;
211 m_payload_base.maxLength = m_payload_base.length + payloadSize;
212 }
213 m_payload_list.resize(1);
214 m_payload_list.back().data = m_payload_base.data + m_payload_base.length;
215 std::copy(reinterpret_cast<mfxU8*>(&m_app14_data), reinterpret_cast<mfxU8*>(&m_app14_data) + payloadSize, m_payload_list.back().data);
216 m_payload_list.back().length = payloadSize;
217 m_payload_base.length += m_payload_list.back().length;
218 }
219 else
220 {
221 m_app0_data.header = 0xE0FF;//APP0
222 m_app0_data.lenH = 0;
223 m_app0_data.lenL = 16;
224 m_app0_data.s[0] = 0x4A;//"J"
225 m_app0_data.s[1] = 0x46;//"F"
226 m_app0_data.s[2] = 0x49;//"I"
227 m_app0_data.s[3] = 0x46;//"F"
228 m_app0_data.s[4] = 0; // 0
229 m_app0_data.versionH = 0x01;
230 m_app0_data.versionL = 0x02;
231 m_app0_data.units = JRU_NONE;
232 m_app0_data.xDensity = 0x0100;//1
233 m_app0_data.yDensity = 0x0100;//1
234 m_app0_data.xThumbnails = 0;
235 m_app0_data.yThumbnails = 0;
236
237 mfxU32 payloadSize = 18;
238 if (m_payload_base.length + payloadSize > m_payload_base.maxLength)
239 {
240 mfxU8* data = new mfxU8[m_payload_base.length + payloadSize];
241 std::copy(m_payload_base.data, m_payload_base.data + m_payload_base.length, data);
242 delete[] m_payload_base.data;
243 m_payload_base.data = data;
244 m_payload_base.maxLength = m_payload_base.length + payloadSize;
245 }
246 m_payload_list.resize(1);
247 m_payload_list.back().data = m_payload_base.data + m_payload_base.length;
248 std::copy(reinterpret_cast<mfxU8*>(&m_app0_data), reinterpret_cast<mfxU8*>(&m_app0_data) + payloadSize, m_payload_list.back().data);
249 m_payload_list.back().length = payloadSize;
250 m_payload_base.length += m_payload_list.back().length;
251 }
252
253 if (ctrl && ctrl->Payload && ctrl->NumPayload > 0)
254 {
255 for (mfxU16 i=0; i<ctrl->NumPayload; i++)
256 {
257 mfxPayload* pExtPayload = ctrl->Payload[i];
258 if (pExtPayload)
259 {
260 if (pExtPayload->Data && (pExtPayload->NumBit>>3) > 0)
261 {
262 mfxU32 payloadSize = pExtPayload->NumBit>>3;
263 if (m_payload_base.length + payloadSize > m_payload_base.maxLength)
264 {
265 mfxU8* data = new mfxU8[m_payload_base.length + payloadSize];
266 std::copy(m_payload_base.data, m_payload_base.data + m_payload_base.length, data);
267 delete[] m_payload_base.data;
268 m_payload_base.data = data;
269 m_payload_base.maxLength = m_payload_base.length + payloadSize;
270 }
271 m_payload_list.resize(m_payload_list.size()+1);
272 m_payload_list.back().data = m_payload_base.data + m_payload_base.length;
273 std::copy(pExtPayload->Data, pExtPayload->Data + payloadSize, m_payload_list.back().data);
274 m_payload_list.back().length = payloadSize;
275 m_payload_base.length += m_payload_list.back().length;
276 }
277 else
278 {
279 return MFX_ERR_INVALID_VIDEO_PARAM;
280 }
281 }
282 }
283 }
284
285 #if defined (MFX_VA_LINUX)
286 // Picture Header
287 memset(&m_pps, 0, sizeof(m_pps));
288 m_pps.reconstructed_picture = 0;
289 m_pps.pic_flags.bits.profile = 0;
290 m_pps.pic_flags.bits.progressive = 0;
291 m_pps.pic_flags.bits.huffman = 1;
292 m_pps.pic_flags.bits.interleaved = (par->mfx.Interleaved != 0);
293 m_pps.pic_flags.bits.differential = 0;
294 m_pps.picture_width = (mfxU32)par->mfx.FrameInfo.CropW;
295 m_pps.picture_height = (mfxU32)par->mfx.FrameInfo.CropH;
296 m_pps.sample_bit_depth = 8;
297 m_pps.component_id[0] = 1;
298 m_pps.component_id[1] = 2;
299 m_pps.component_id[2] = 3;
300
301 if (!jpegQT && !jpegQTInitial)
302 m_pps.quality = (par->mfx.Quality > 100) ? 100 : par->mfx.Quality;
303
304 if (fourCC == MFX_FOURCC_NV12 && chromaFormat == MFX_CHROMAFORMAT_YUV420)
305 m_pps.num_components = 3;
306 else if (fourCC == MFX_FOURCC_YUY2 && chromaFormat == MFX_CHROMAFORMAT_YUV422H)
307 m_pps.num_components = 3;
308 else if (fourCC == MFX_FOURCC_NV12 && chromaFormat == MFX_CHROMAFORMAT_YUV400)
309 m_pps.num_components = 1;
310 else if (fourCC == MFX_FOURCC_RGB4 && chromaFormat == MFX_CHROMAFORMAT_YUV444)
311 m_pps.num_components = 3;
312 else
313 return MFX_ERR_UNDEFINED_BEHAVIOR;
314
315 // Scan Header
316 m_pps.num_scan = 1;
317 m_scan_list.resize(1);
318 memset(&m_scan_list[0], 0, sizeof(m_scan_list[0]));
319 m_scan_list[0].restart_interval = par->mfx.RestartInterval;
320 m_scan_list[0].num_components = m_pps.num_components;
321 m_scan_list[0].components[0].component_selector = 1;
322 m_scan_list[0].components[1].component_selector = 2;
323 m_scan_list[0].components[2].component_selector = 3;
324
325 // Quanlization tables
326 if (jpegQT || jpegQTInitial)
327 {
328 // External tables
329 mfxExtJPEGQuantTables *pExtQuant = jpegQT ? jpegQT : jpegQTInitial;
330 MFX_CHECK(pExtQuant->NumTable && (pExtQuant->NumTable <= hwCaps->MaxNumQuantTable), MFX_ERR_UNDEFINED_BEHAVIOR);
331 m_dqt_list.resize(1);
332 if(pExtQuant->NumTable == 1)
333 {
334 m_dqt_list[0].load_lum_quantiser_matrix = true;
335 m_dqt_list[0].load_chroma_quantiser_matrix = false;
336 for(mfxU16 i = 0; i< 64; i++)
337 {
338 m_dqt_list[0].lum_quantiser_matrix[i]=(unsigned char) pExtQuant->Qm[0][i];
339 }
340 m_pps.quantiser_table_selector[0] = 0;
341 m_pps.quantiser_table_selector[1] = 0;
342 m_pps.quantiser_table_selector[2] = 0;
343 }
344 else if(pExtQuant->NumTable == 2)
345 {
346 m_dqt_list[0].load_chroma_quantiser_matrix = true;
347 m_dqt_list[0].load_lum_quantiser_matrix = true;
348 for(mfxU16 i = 0; i< 64; i++)
349 {
350 m_dqt_list[0].lum_quantiser_matrix[i]=(unsigned char) pExtQuant->Qm[0][i];
351 m_dqt_list[0].chroma_quantiser_matrix[i]=(unsigned char) pExtQuant->Qm[1][i];
352 }
353 m_pps.quantiser_table_selector[0] = 0;
354 m_pps.quantiser_table_selector[1] = 1;
355 m_pps.quantiser_table_selector[2] = 1;
356 }
357 else
358 return MFX_ERR_INVALID_VIDEO_PARAM;
359 }
360 else
361 {
362 // No external tables - use Quality parameter
363 m_dqt_list.resize(0);
364 if (fourCC == MFX_FOURCC_RGB4)
365 {
366 m_pps.quantiser_table_selector[0] = 0;
367 m_pps.quantiser_table_selector[1] = 0;
368 m_pps.quantiser_table_selector[2] = 0;
369 }
370 else
371 {
372 m_pps.quantiser_table_selector[0] = 0;
373 m_pps.quantiser_table_selector[1] = 1;
374 m_pps.quantiser_table_selector[2] = 1;
375 }
376 }
377
378 // Huffman tables
379 if (jpegHT || jpegHTInitial)
380 {
381 // External tables
382 mfxExtJPEGHuffmanTables *pExtHuffman = jpegHT ? jpegHT : jpegHTInitial;
383 MFX_CHECK(pExtHuffman->NumDCTable &&
384 pExtHuffman->NumACTable &&
385 (pExtHuffman->NumDCTable < hwCaps->MaxNumHuffTable) &&
386 (pExtHuffman->NumACTable < hwCaps->MaxNumHuffTable), MFX_ERR_UNDEFINED_BEHAVIOR);
387 m_dht_list.resize(1);
388 for (mfxU16 j = 0; j < pExtHuffman->NumDCTable; j++)
389 {
390 if(j < 2)
391 {
392 MFX_INTERNAL_CPY(m_dht_list[0].huffman_table[j].num_dc_codes, pExtHuffman->DCTables[j].Bits, 16 * sizeof(mfxU8));
393 MFX_INTERNAL_CPY(m_dht_list[0].huffman_table[j].dc_values, pExtHuffman->DCTables[j].Values, 12 * sizeof(mfxU8));
394 }
395 else
396 return MFX_ERR_INVALID_VIDEO_PARAM;
397 }
398 for (mfxU16 j = 0; j < pExtHuffman->NumACTable; j++)
399 {
400 if(j < 2)
401 {
402 MFX_INTERNAL_CPY(m_dht_list[0].huffman_table[j].num_ac_codes, pExtHuffman->ACTables[j].Bits, 16 * sizeof(mfxU8));
403 MFX_INTERNAL_CPY(m_dht_list[0].huffman_table[j].ac_values, pExtHuffman->ACTables[j].Values, 162 * sizeof(mfxU8));
404 }
405 else
406 return MFX_ERR_INVALID_VIDEO_PARAM;
407 }
408 }
409 else
410 {
411 // Internal tables
412 if (hwCaps->MaxNumHuffTable == 0)
413 {
414 m_dht_list.resize(0);
415 }
416 else if (hwCaps->MaxNumHuffTable == 1 || fourCC == MFX_FOURCC_RGB4)
417 {
418 m_dht_list.resize(1);
419
420 m_dht_list[0].load_huffman_table[0] = 1; //0 for luma
421
422 for(mfxU16 i = 0; i < 16; i++)
423 m_dht_list[0].huffman_table[0].num_dc_codes[i] = DefaultLuminanceDCBits[i];
424 for(mfxU16 i = 0; i < 12; i++)
425 m_dht_list[0].huffman_table[0].dc_values[i] = DefaultLuminanceDCValues[i];
426 for(mfxU16 i = 0; i < 16; i++)
427 m_dht_list[0].huffman_table[0].num_ac_codes[i] = DefaultLuminanceACBits[i];
428 for(mfxU16 i = 0; i < 162; i++)
429 m_dht_list[0].huffman_table[0].ac_values[i] = DefaultLuminanceACValues[i];
430
431 m_scan_list[0].components[0].dc_table_selector = 0;
432 m_scan_list[0].components[1].dc_table_selector = 0;
433 m_scan_list[0].components[2].dc_table_selector = 0;
434 m_scan_list[0].components[0].ac_table_selector = 0;
435 m_scan_list[0].components[1].ac_table_selector = 0;
436 m_scan_list[0].components[2].ac_table_selector = 0;
437 }
438 else
439 {
440 m_dht_list.resize(1);
441
442 m_dht_list[0].load_huffman_table[0] = 1; //0 for luma
443 m_dht_list[0].load_huffman_table[1] = 1; // 1 for chroma
444
445 for(mfxU16 i = 0; i < 16; i++)
446 m_dht_list[0].huffman_table[0].num_dc_codes[i] = DefaultLuminanceDCBits[i];
447 for(mfxU16 i = 0; i < 12; i++)
448 m_dht_list[0].huffman_table[0].dc_values[i] = DefaultLuminanceDCValues[i];
449 for(mfxU16 i = 0; i < 16; i++)
450 m_dht_list[0].huffman_table[0].num_ac_codes[i] = DefaultLuminanceACBits[i];
451 for(mfxU16 i = 0; i < 162; i++)
452 m_dht_list[0].huffman_table[0].ac_values[i] = DefaultLuminanceACValues[i];
453 for(mfxU16 i = 0; i < 16; i++)
454 m_dht_list[0].huffman_table[1].num_dc_codes[i] = DefaultChrominanceDCBits[i];
455 for(mfxU16 i = 0; i < 12; i++)
456 m_dht_list[0].huffman_table[1].dc_values[i] = DefaultChrominanceDCValues[i];
457 for(mfxU16 i = 0; i < 16; i++)
458 m_dht_list[0].huffman_table[1].num_ac_codes[i] = DefaultChrominanceACBits[i];
459 for(mfxU16 i = 0; i < 162; i++)
460 m_dht_list[0].huffman_table[1].ac_values[i] = DefaultChrominanceACValues[i];
461
462 m_scan_list[0].components[0].dc_table_selector = 0;
463 m_scan_list[0].components[1].dc_table_selector = 1;
464 m_scan_list[0].components[2].dc_table_selector = 1;
465 m_scan_list[0].components[0].ac_table_selector = 0;
466 m_scan_list[0].components[1].ac_table_selector = 1;
467 m_scan_list[0].components[2].ac_table_selector = 1;
468 }
469 }
470 #endif
471
472 return sts;
473 }
474
Close()475 void ExecuteBuffers::Close()
476 {
477 if (m_payload_base.data)
478 {
479 delete [] m_payload_base.data;
480 m_payload_base.data = 0;
481 m_payload_base.length = 0;
482 m_payload_base.maxLength = 0;
483 }
484 m_dht_list.clear();
485 m_dqt_list.clear();
486 m_scan_list.clear();
487 m_payload_list.clear();
488 }
489
TaskManager()490 TaskManager::TaskManager()
491 {
492 m_pTaskList = 0;
493 m_TaskNum = 0;
494 }
495
~TaskManager()496 TaskManager::~TaskManager()
497 {
498 UMC::AutomaticUMCMutex guard(m_mutex);
499
500 Close();
501 }
502
Init(mfxU32 maxTaskNum)503 mfxStatus TaskManager::Init(mfxU32 maxTaskNum)
504 {
505 UMC::AutomaticUMCMutex guard(m_mutex);
506
507 if (maxTaskNum > 0 &&
508 maxTaskNum < JPEG_DDITASK_MAX_NUM)
509 {
510 m_TaskNum = maxTaskNum;
511 m_pTaskList = new DdiTask[m_TaskNum];
512 memset(m_pTaskList, 0, m_TaskNum * sizeof(DdiTask));
513 for (mfxU32 i = 0; i < m_TaskNum; i++)
514 {
515 m_pTaskList[i].m_idx = i;
516 m_pTaskList[i].m_idxBS = i;
517 }
518 return MFX_ERR_NONE;
519 }
520 else
521 {
522 m_pTaskList = 0;
523 m_TaskNum = 0;
524 return MFX_ERR_INVALID_VIDEO_PARAM;
525 }
526 }
527
Reset()528 mfxStatus TaskManager::Reset()
529 {
530 UMC::AutomaticUMCMutex guard(m_mutex);
531
532 if (m_pTaskList)
533 {
534 for (mfxU32 i = 0; i < m_TaskNum; i++)
535 {
536 if(m_pTaskList[i].m_pDdiData)
537 {
538 m_pTaskList[i].m_pDdiData->Close();
539 delete m_pTaskList[i].m_pDdiData;
540 m_pTaskList[i].m_pDdiData = NULL;
541 }
542 vm_interlocked_xchg32(&m_pTaskList[i].lInUse, 0);
543 m_pTaskList[i].surface = 0;
544 m_pTaskList[i].bs = 0;
545 }
546 }
547
548 return MFX_ERR_NONE;
549 }
550
Close()551 mfxStatus TaskManager::Close()
552 {
553 if (m_pTaskList)
554 {
555 for (mfxU32 i = 0; i < m_TaskNum; i++)
556 {
557 if(m_pTaskList[i].m_pDdiData)
558 {
559 m_pTaskList[i].m_pDdiData->Close();
560 delete m_pTaskList[i].m_pDdiData;
561 m_pTaskList[i].m_pDdiData = NULL;
562 }
563 }
564 delete [] m_pTaskList;
565 m_pTaskList = 0;
566 }
567
568 return MFX_ERR_NONE;
569 }
570
AssignTask(DdiTask * & newTask)571 mfxStatus TaskManager::AssignTask(DdiTask *& newTask)
572 {
573 UMC::AutomaticUMCMutex guard(m_mutex);
574
575 if (m_pTaskList)
576 {
577 mfxU32 i;
578 for (i = 0; i < m_TaskNum; i++)
579 {
580 if (m_pTaskList[i].lInUse == 0)
581 break;
582 }
583 if (i < m_TaskNum)
584 {
585 newTask = &m_pTaskList[i];
586 vm_interlocked_xchg32(&newTask->lInUse, 1);
587 return MFX_ERR_NONE;
588 }
589 else
590 {
591 return MFX_WRN_DEVICE_BUSY;
592 }
593 }
594 else
595 {
596 return MFX_ERR_NULL_PTR;
597 }
598 }
599
RemoveTask(DdiTask & task)600 mfxStatus TaskManager::RemoveTask(DdiTask & task)
601 {
602 UMC::AutomaticUMCMutex guard(m_mutex);
603
604 if (m_pTaskList)
605 {
606 vm_interlocked_xchg32(&task.lInUse, 0);
607 task.surface = 0;
608 task.bs = 0;
609 return MFX_ERR_NONE;
610 }
611 else
612 {
613 return MFX_ERR_NULL_PTR;
614 }
615 }
616
617 #endif // #if defined (MFX_ENABLE_MJPEG_VIDEO_ENCODE) && defined (MFX_VA)
618