1 // Copyright (c) 2018-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 #include "mfx_common.h"
21 #ifdef MFX_ENABLE_H264_VIDEO_ENCODE_HW
22
23 #include <vector>
24 #include <list>
25 #include <memory>
26 #include <algorithm> /* for std::find_if on Linux/Android */
27 #include <mfx_brc_common.h>
28
29 #include "mfx_h264_encode_struct_vaapi.h"
30 #include "umc_mutex.h"
31 #include "umc_event.h"
32 #include "umc_h264_brc.h"
33 #include "mfx_h264_enc_common_hw.h"
34 #include "mfx_ext_buffers.h"
35 #include "mfx_h264_encode_interface.h"
36 #include "mfx_h264_encode_cm.h"
37 #include "vm_time.h"
38 #include "asc.h"
39
40 #ifdef MFX_ENABLE_MCTF_IN_AVC
41 #include "cmvm.h"
42 #include "mctf_common.h"
43 #endif
44
45 #ifndef _MFX_H264_ENCODE_HW_UTILS_H_
46 #define _MFX_H264_ENCODE_HW_UTILS_H_
47
48 #if defined(AS_H264LA_PLUGIN) && defined(MFX_ENABLE_ENCTOOLS)
49 #undef MFX_ENABLE_ENCTOOLS
50 #endif
51
52 #define bRateControlLA(RCMethod) ((RCMethod == MFX_RATECONTROL_LA)||(RCMethod == MFX_RATECONTROL_LA_ICQ)||(RCMethod == MFX_RATECONTROL_LA_EXT)||(RCMethod == MFX_RATECONTROL_LA_HRD))
53 #define bIntRateControlLA(RCMethod) ((RCMethod == MFX_RATECONTROL_LA)||(RCMethod == MFX_RATECONTROL_LA_ICQ)||(RCMethod == MFX_RATECONTROL_LA_HRD))
54
55 inline constexpr
hasSupportVME(eMFXHWType platform)56 bool hasSupportVME(eMFXHWType platform)
57 {
58 return
59 (platform <= MFX_HW_ADL_S
60 && platform != MFX_HW_JSL
61 && platform != MFX_HW_EHL
62 );
63 }
64
65 #define MFX_H264ENC_HW_TASK_TIMEOUT 2000
66
67 #define MFX_ARRAY_SIZE(ARR) (sizeof(ARR)/sizeof(ARR[0]))
68 const int MFX_MAX_DIRTY_RECT_COUNT = MFX_ARRAY_SIZE(mfxExtDirtyRect::Rect);
69 const int MFX_MAX_MOVE_RECT_COUNT = MFX_ARRAY_SIZE(mfxExtMoveRect::Rect);
70 const int DEFAULT_PPYR_INTERVAL = 3;
71
72
73 namespace MfxHwH264Encode
74 {
75 struct VmeData;
76
77 enum {
78 STAGE_QP = 0xf00000,
79 STAGE_ENC1 = 0x0f0000,
80 STAGE_PAK1 = 0x00f000,
81 STAGE_ENC2 = 0x000f00,
82 STAGE_PAK2 = 0x0000f0,
83 STAGE_ENC = STAGE_ENC1 | STAGE_ENC2,
84 STAGE_PAK = STAGE_PAK1 | STAGE_PAK2,
85 STAGE_ALL = 0xffffff
86 };
87
88 static const mfxU16 MFX_MEMTYPE_SYS_INT =
89 MFX_MEMTYPE_FROM_ENCODE | MFX_MEMTYPE_SYSTEM_MEMORY | MFX_MEMTYPE_INTERNAL_FRAME;
90
91 static const mfxU16 MFX_MEMTYPE_SYS_EXT =
92 MFX_MEMTYPE_FROM_ENCODE | MFX_MEMTYPE_SYSTEM_MEMORY | MFX_MEMTYPE_EXTERNAL_FRAME;
93
94 static const mfxU16 MFX_MEMTYPE_D3D_INT =
95 MFX_MEMTYPE_FROM_ENCODE | MFX_MEMTYPE_DXVA2_DECODER_TARGET | MFX_MEMTYPE_INTERNAL_FRAME;
96
97 static const mfxU16 MFX_MEMTYPE_D3D_EXT =
98 MFX_MEMTYPE_FROM_ENCODE | MFX_MEMTYPE_DXVA2_DECODER_TARGET | MFX_MEMTYPE_EXTERNAL_FRAME;
99
100
101 mfxU16 CalcNumFrameMin(const MfxHwH264Encode::MfxVideoParam &par, MFX_ENCODE_CAPS const & hwCaps);
102
103 enum
104 {
105 TFIELD = 0,
106 BFIELD = 1
107 };
108
109 enum
110 {
111 ENC = 0,
112 DISP = 1
113 };
114
115 /*
116 NAL unit types for internal usage
117 */
118 enum {
119 NALU_NON_IDR = 1,
120 NALU_IDR = 5,
121 NALU_SEI = 6,
122 NALU_SPS = 7,
123 NALU_PPS = 8,
124 NALU_AUD = 9,
125 NALU_PREFIX = 14,
126 NALU_CODED_SLICE_EXT = 20,
127 };
128
129
130 class DdiTask;
131
132 struct mfxExtAvcSeiBufferingPeriod
133 {
134 mfxU8 seq_parameter_set_id;
135 mfxU8 nal_cpb_cnt;
136 mfxU8 vcl_cpb_cnt;
137 mfxU8 initial_cpb_removal_delay_length;
138 mfxU32 nal_initial_cpb_removal_delay[32];
139 mfxU32 nal_initial_cpb_removal_delay_offset[32];
140 mfxU32 vcl_initial_cpb_removal_delay[32];
141 mfxU32 vcl_initial_cpb_removal_delay_offset[32];
142 };
143
144 struct mfxExtAvcSeiPicTiming
145 {
146 mfxU8 cpb_dpb_delays_present_flag;
147 mfxU8 cpb_removal_delay_length;
148 mfxU8 dpb_output_delay_length;
149 mfxU8 pic_struct_present_flag;
150 mfxU8 time_offset_length;
151
152 mfxU32 cpb_removal_delay;
153 mfxU32 dpb_output_delay;
154 mfxU8 pic_struct;
155 mfxU8 ct_type;
156 };
157
158 struct mfxExtAvcSeiDecRefPicMrkRep
159 {
160 mfxU8 original_idr_flag;
161 mfxU16 original_frame_num;
162 mfxU8 original_field_info_present_flag;
163 mfxU8 original_field_pic_flag;
164 mfxU8 original_bottom_field_flag;
165 mfxU8 no_output_of_prior_pics_flag;
166 mfxU8 long_term_reference_flag;
167 mfxU8 adaptive_ref_pic_marking_mode_flag;
168 mfxU32 num_mmco_entries; // number of currently valid mmco, value pairs
169 mfxU8 mmco[32]; // memory management control operation id
170 mfxU32 value[64]; // operation-dependent data, max 2 per operation
171 };
172
173 struct mfxExtAvcSeiRecPoint
174 {
175 mfxU16 recovery_frame_cnt;
176 mfxU8 exact_match_flag;
177 mfxU8 broken_link_flag;
178 mfxU8 changing_slice_group_idc;
179 };
180
181
182 template <typename T> struct Pair
183 {
184 T top;
185 T bot;
186
PairPair187 Pair()
188 : top()
189 , bot()
190 {
191 }
192
PairPair193 template<typename U> Pair(Pair<U> const & pair)
194 : top(static_cast<T>(pair.top))
195 , bot(static_cast<T>(pair.bot))
196 {
197 }
198
PairPair199 template<typename U> explicit Pair(U const & value)
200 : top(static_cast<T>(value))
201 , bot(static_cast<T>(value))
202 {
203 }
204
PairPair205 template<typename U> Pair(U const & t, U const & b)
206 : top(static_cast<T>(t))
207 , bot(static_cast<T>(b))
208 {
209 }
210
211 template<typename U>
212 Pair<T> & operator =(Pair<U> const & pair)
213 {
214 Pair<T> tmp(pair);
215 std::swap(*this, tmp);
216 return *this;
217 }
218
219 T & operator[] (mfxU32 parity)
220 {
221 assert(parity < 2);
222 return (&top)[parity & 1];
223 }
224
225 T const & operator[] (mfxU32 parity) const
226 {
227 assert(parity < 2);
228 return (&top)[parity & 1];
229 }
230 };
231
MakePair(T const & top,T const & bot)232 template <class T> Pair<T> MakePair(T const & top, T const & bot)
233 {
234 return Pair<T>(top, bot);
235 }
236
237 template <class T> bool operator ==(Pair<T> const & l, Pair<T> const & r)
238 {
239 return l.top == r.top && l.bot == r.bot;
240 }
241
242 typedef Pair<mfxU8> PairU8;
243 typedef Pair<mfxU16> PairU16;
244 typedef Pair<mfxU32> PairU32;
245 typedef Pair<mfxI32> PairI32;
246
247 void PrepareSeiMessage(
248 DdiTask const & task,
249 mfxU32 nalHrdBpPresentFlag,
250 mfxU32 vclHrdBpPresentFlag,
251 mfxU32 seqParameterSetId,
252 mfxExtAvcSeiBufferingPeriod & msg);
253
254 void PrepareSeiMessage(
255 DdiTask const & task,
256 mfxU32 fieldId,
257 mfxU32 cpbDpbDelaysPresentFlag,
258 mfxExtAvcSeiPicTiming & msg);
259
260 void PrepareSeiMessage(
261 DdiTask const & task,
262 mfxU32 fieldId,
263 mfxU32 frame_mbs_only_flag,
264 mfxExtAvcSeiDecRefPicMrkRep & msg);
265
266 void PrepareSeiMessage(
267 MfxVideoParam const & par,
268 mfxExtAvcSeiRecPoint & msg);
269
270 mfxU32 CalculateSeiSize( mfxExtAvcSeiRecPoint const & msg);
271 mfxU32 CalculateSeiSize( mfxExtAvcSeiDecRefPicMrkRep const & msg);
272
273 // MVC BD {
274 mfxU32 CalculateSeiSize( mfxExtAvcSeiBufferingPeriod const & msg);
275 mfxU32 CalculateSeiSize(
276 mfxExtPictureTimingSEI const & extPt,
277 mfxExtAvcSeiPicTiming const & msg);
278 // MVC BD }
279
280 mfxStatus CheckBeforeCopy(
281 mfxExtMVCSeqDesc & dst,
282 mfxExtMVCSeqDesc const & src);
283
284 mfxStatus CheckBeforeCopyQueryLike(
285 mfxExtMVCSeqDesc & dst,
286 mfxExtMVCSeqDesc const & src);
287
288 void Copy(
289 mfxExtMVCSeqDesc & dst,
290 mfxExtMVCSeqDesc const & src);
291
292 void FastCopyBufferVid2Sys(
293 void * dstSys,
294 void const * srcVid,
295 mfxI32 bytes);
296
297 void FastCopyBufferSys2Vid(
298 void * dstSys,
299 void const * srcVid,
300 mfxI32 bytes);
301
302 PairU8 ExtendFrameType(
303 mfxU32 type);
304
305 mfxU8 CalcTemporalLayerIndex(
306 MfxVideoParam const & video,
307 mfxI32 frameOrder);
308
309 bool CheckSubMbPartition(
310 mfxExtCodingOptionDDI const * extDdi,
311 mfxU8 frameType);
312
313 mfxU8 GetPFrameLevel(
314 mfxU32 i,
315 mfxU32 num);
316
317 mfxU8 PLayer(
318 MfxVideoParam const & par,
319 mfxU32 order);
320
321 mfxU8 GetQpValue(
322 DdiTask const & task,
323 MfxVideoParam const & par,
324 mfxU32 frameType);
325
326 PairU16 GetPicStruct(
327 MfxVideoParam const & video,
328 mfxU16 runtPs);
329
330 PairU16 GetPicStruct(
331 MfxVideoParam const & video,
332 DdiTask const & task);
333
334 bool isBitstreamUpdateRequired(MfxVideoParam const & video,
335 MFX_ENCODE_CAPS caps,
336 eMFXHWType platform);
337 // Helper which checks number of allocated frames and auto-free.
338 enum
339 {
340 H264_FRAME_FLAG_SKIPPED = 1,
341 H264_FRAME_FLAG_READY = 2
342 };
343
344 class MfxFrameAllocResponse : public mfxFrameAllocResponse
345 {
346 public:
347 MfxFrameAllocResponse();
348
349 ~MfxFrameAllocResponse();
350
351 mfxStatus Alloc(
352 VideoCORE * core,
353 mfxFrameAllocRequest & req,
354 bool isCopyRequired = true,
355 bool isAllFramesRequired = false);
356
357 mfxStatus Alloc(
358 VideoCORE * core,
359 mfxFrameAllocRequest & req,
360 mfxFrameSurface1 ** opaqSurf,
361 mfxU32 numOpaqSurf);
362
363 mfxStatus AllocCmBuffers(
364 CmDevice * device,
365 mfxFrameAllocRequest & req);
366
367 mfxStatus AllocCmBuffersUp(
368 CmDevice * device,
369 mfxFrameAllocRequest & req);
370
371 mfxStatus AllocCmSurfaces(
372 CmDevice * device,
373 mfxFrameAllocRequest & req);
374
375 mfxStatus AllocCmSurfacesUP(
376 CmDevice * device,
377 mfxFrameAllocRequest & req);
378 mfxStatus AllocFrames(
379 VideoCORE * core,
380 mfxFrameAllocRequest & req);
381 mfxStatus UpdateResourcePointers(
382 mfxU32 idxScd,
383 void * memY,
384 void * gpuSurf);
385
386 void * GetSysmemBuffer(mfxU32 idx);
387
388 mfxU32 Lock(mfxU32 idx);
389
390 void Unlock();
391
392 mfxU32 Unlock(mfxU32 idx);
393
394 mfxU32 Locked(mfxU32 idx) const;
395
396 void ClearFlag(mfxU32 idx);
397 void SetFlag(mfxU32 idx, mfxU32 flag);
398 mfxU32 GetFlag(mfxU32 idx) const;
399 private:
400 MfxFrameAllocResponse(MfxFrameAllocResponse const &);
401 MfxFrameAllocResponse & operator =(MfxFrameAllocResponse const &);
402
403 static void DestroyBuffer (CmDevice * device, void * p);
404 static void DestroySurface (CmDevice * device, void * p);
405 static void DestroySurface2DUP(CmDevice * device, void * p);
406 static void DestroyBufferUp (CmDevice * device, void * p);
407
408 void (*m_cmDestroy)(CmDevice *, void *);
409
410 VideoCORE * m_core;
411 CmDevice * m_cmDevice;
412 mfxU16 m_numFrameActualReturnedByAllocFrames;
413
414 std::vector<mfxFrameAllocResponse> m_responseQueue;
415 std::vector<mfxMemId> m_mids;
416 std::vector<mfxU32> m_locked;
417 std::vector<mfxU32> m_flag;
418 std::vector<void *> m_sysmems;
419 };
420
421 mfxU32 FindFreeResourceIndex(
422 MfxFrameAllocResponse const & pool,
423 mfxU32 startingFrom = 0);
424
425 mfxMemId AcquireResource(
426 MfxFrameAllocResponse & pool,
427 mfxU32 index);
428
429 mfxMemId AcquireResource(
430 MfxFrameAllocResponse & pool);
431
432 mfxHDLPair AcquireResourceUp(
433 MfxFrameAllocResponse & pool,
434 mfxU32 index);
435
436 mfxHDLPair AcquireResourceUp(
437 MfxFrameAllocResponse & pool);
438
439 void ReleaseResource(
440 MfxFrameAllocResponse & pool,
441 mfxMemId mid);
442
443 // add hwType param
444 mfxStatus CheckEncodeFrameParam(
445 MfxVideoParam const & video,
446 mfxEncodeCtrl * ctrl,
447 mfxFrameSurface1 * surface,
448 mfxBitstream * bs,
449 bool isExternalFrameAllocator,
450 MFX_ENCODE_CAPS const & caps,
451 eMFXHWType hwType = MFX_HW_UNKNOWN);
452
Clear(std::vector<T> & v)453 template<typename T> void Clear(std::vector<T> & v)
454 {
455 std::vector<T>().swap(v);
456 }
457
458
459 template<class T, mfxU32 N>
460 struct FixedArray
461 {
FixedArrayFixedArray462 FixedArray()
463 : m_numElem(0)
464 {
465 }
466
FixedArrayFixedArray467 explicit FixedArray(T fillVal)
468 : m_numElem(0)
469 {
470 Fill(fillVal);
471 }
472
PushBackFixedArray473 void PushBack(T const & val)
474 {
475 assert(m_numElem < N);
476 m_arr[m_numElem] = val;
477 m_numElem++;
478 }
479
PushFrontFixedArray480 void PushFront(T const val)
481 {
482 assert(m_numElem < N);
483 std::copy(m_arr, m_arr + m_numElem, m_arr + 1);
484 m_arr[0] = val;
485 m_numElem++;
486 }
487
EraseFixedArray488 void Erase(T * p)
489 {
490 assert(p >= m_arr && p <= m_arr + m_numElem);
491
492 m_numElem = mfxU32(
493 std::copy(p + 1, m_arr + m_numElem, p) - m_arr);
494 }
495
EraseFixedArray496 void Erase(T * b, T * e)
497 {
498 assert(b <= e);
499 assert(b >= m_arr && b <= m_arr + m_numElem);
500 assert(e >= m_arr && e <= m_arr + m_numElem);
501
502 m_numElem = mfxU32(
503 std::copy(e, m_arr + m_numElem, b) - m_arr);
504 }
505
506 void Resize(mfxU32 size, T fillVal = T())
507 {
508 assert(size <= N);
509 for (mfxU32 i = m_numElem ; i < size; ++i)
510 m_arr[i] = fillVal;
511 m_numElem = size;
512 }
513
BeginFixedArray514 T * Begin()
515 {
516 return m_arr;
517 }
518
BeginFixedArray519 T const * Begin() const
520 {
521 return m_arr;
522 }
523
EndFixedArray524 T * End()
525 {
526 return m_arr + m_numElem;
527 }
528
EndFixedArray529 T const * End() const
530 {
531 return m_arr + m_numElem;
532 }
533
BackFixedArray534 T & Back()
535 {
536 assert(m_numElem > 0);
537 return m_arr[m_numElem - 1];
538 }
539
BackFixedArray540 T const & Back() const
541 {
542 assert(m_numElem > 0);
543 return m_arr[m_numElem - 1];
544 }
545
SizeFixedArray546 mfxU32 Size() const
547 {
548 return m_numElem;
549 }
550
CapacityFixedArray551 mfxU32 Capacity() const
552 {
553 return N;
554 }
555
556 T & operator[](mfxU32 idx)
557 {
558 assert(idx < N);
559 return m_arr[idx];
560 }
561
562 T const & operator[](mfxU32 idx) const
563 {
564 assert(idx < N);
565 return m_arr[idx];
566 }
567
FillFixedArray568 void Fill(T val)
569 {
570 for (mfxU32 i = 0; i < N; i++)
571 {
572 m_arr[i] = val;
573 }
574 }
575
576 template<mfxU32 M>
577 bool operator==(const FixedArray<T, M>& r) const
578 {
579 assert(Size() <= N);
580 assert(r.Size() <= M);
581
582 if (Size() != r.Size())
583 {
584 return false;
585 }
586
587 for (mfxU32 i = 0; i < Size(); i++)
588 {
589 if (m_arr[i] != r[i])
590 {
591 return false;
592 }
593 }
594
595 return true;
596 }
597
598 private:
599 T m_arr[N];
600 mfxU32 m_numElem;
601 };
602
603 struct BiFrameLocation
604 {
BiFrameLocationBiFrameLocation605 BiFrameLocation() { Zero(*this); }
606
607 mfxU32 miniGopCount; // sequence of B frames between I/P frames
608 mfxU32 encodingOrder; // number within mini-GOP (in encoding order)
609 mfxU16 refFrameFlag; // MFX_FRAMETYPE_REF if B frame is reference
610 mfxU32 level; // level of pyramid
611 };
612
613 class FrameTypeGenerator
614 {
615 public:
616 FrameTypeGenerator();
617
618 void Init(MfxVideoParam const & video);
619
620 PairU8 Get() const;
621
622 BiFrameLocation GetBiFrameLocation() const;
623
624 void Next();
625
626 private:
627 mfxU32 m_frameOrder; // in display order
628 mfxU16 m_gopOptFlag;
629 mfxU16 m_gopPicSize;
630 mfxU16 m_gopRefDist;
631 mfxU16 m_refBaseDist; // key picture distance
632 mfxU16 m_biPyramid;
633 mfxU32 m_idrDist;
634 };
635
636 /* Intra refresh types */
637 enum {
638 MFX_REFRESH_NO = 0,
639 MFX_REFRESH_VERTICAL = 1,
640 MFX_REFRESH_HORIZONTAL = 2,
641 MFX_REFRESH_SLICE = 3
642 };
643
644 struct IntraRefreshState
645 {
IntraRefreshStateIntraRefreshState646 IntraRefreshState() : refrType(0), IntraLocation(0), IntraSize(0), IntRefQPDelta(0), firstFrameInCycle(false) {}
647 bool operator==(const IntraRefreshState& rhs) const
648 {
649 return refrType == rhs.refrType &&
650 IntraLocation == rhs.IntraLocation &&
651 IntraSize == rhs.IntraSize &&
652 IntRefQPDelta == rhs.IntRefQPDelta &&
653 firstFrameInCycle == rhs.firstFrameInCycle;
654 }
655
656 mfxU16 refrType;
657 mfxU16 IntraLocation;
658 mfxU16 IntraSize;
659 mfxI16 IntRefQPDelta;
660 bool firstFrameInCycle;
661 };
662
663 class Surface
664 {
665 public:
Surface()666 Surface()
667 : m_free(true)
668 {
669 }
670
IsFree()671 bool IsFree() const
672 {
673 return m_free;
674 }
675
SetFree(bool free)676 void SetFree(bool free)
677 {
678 m_free = free;
679 }
680
681 private:
682 bool m_free;
683 };
684
685 class Reconstruct : public Surface
686 {
687 public:
Reconstruct()688 Reconstruct()
689 : Surface()
690 , m_yuv(0)
691 , m_frameOrderIdrInDisplayOrder(0)
692 , m_frameOrderIdr(0)
693 , m_frameOrderI(0)
694 , m_frameOrder(0)
695 , m_baseLayerOrder(0)
696 , m_frameOrderStartTScalStructure(0)
697 , m_frameNum(0)
698 , m_frameNumWrap(0)
699 , m_picNum(0, 0)
700 , m_longTermFrameIdx(NO_INDEX_U8)
701 , m_longTermPicNum(NO_INDEX_U8, NO_INDEX_U8)
702 , m_reference(false, false)
703 , m_picStruct((mfxU16)MFX_PICSTRUCT_PROGRESSIVE)
704 , m_extFrameTag(0)
705 , m_tid(0)
706 , m_tidx(0)
707 , m_panicMode(0)
708 {
709 }
710
GetPicStructForEncode()711 mfxU16 GetPicStructForEncode() const
712 {
713 return m_picStruct[ENC];
714 }
715
GetPicStructForDisplay()716 mfxU16 GetPicStructForDisplay() const
717 {
718 return m_picStruct[DISP];
719 }
720
GetFirstField()721 mfxU8 GetFirstField() const
722 {
723 return (GetPicStructForEncode() & MFX_PICSTRUCT_FIELD_BFF) ? 1 : 0;
724 }
725
GetPoc(mfxU32 parity)726 mfxI32 GetPoc(mfxU32 parity) const
727 {
728 return 2 * ((m_frameOrder - m_frameOrderIdr) & 0x7fffffff) + (parity != GetFirstField());
729 }
730
GetPoc()731 PairI32 GetPoc() const
732 {
733 return PairI32(GetPoc(TFIELD), GetPoc(BFIELD));
734 }
735
GetPictureCount()736 mfxU32 GetPictureCount() const
737 {
738 return (GetPicStructForEncode() & MFX_PICSTRUCT_PROGRESSIVE) ? 1 : 2;
739 }
740
741 mfxFrameSurface1* m_yuv;
742 mfxU32 m_frameOrderIdrInDisplayOrder; // most recent idr frame in display order
743 mfxU32 m_frameOrderIdr; // most recent idr frame in encoding order
744 mfxU32 m_frameOrderI; // most recent i frame in encoding order
745 mfxU32 m_frameOrder;
746 mfxU32 m_baseLayerOrder;
747 mfxU32 m_frameOrderStartTScalStructure; // starting point of temporal scalability structure
748 mfxU16 m_frameNum;
749 mfxI32 m_frameNumWrap;
750 PairI32 m_picNum;
751 mfxU8 m_longTermFrameIdx;
752 PairU8 m_longTermPicNum;
753 PairU8 m_reference; // is refrence (short or long term) or not
754 PairU16 m_picStruct;
755 mfxU32 m_extFrameTag;
756 mfxU32 m_tid; // temporal_id
757 mfxU8 m_tidx; // temporal layer index (in acsending order of temporal_id)
758 mfxU8 m_panicMode;
759 };
760
761 struct RefListMod
762 {
RefListModRefListMod763 RefListMod() : m_idc(3), m_diff(0) {}
RefListModRefListMod764 RefListMod(mfxU16 idc, mfxU16 diff) : m_idc(idc), m_diff(diff) { assert(idc < 6); }
765 mfxU16 m_idc;
766 mfxU16 m_diff;
767 };
768
769 struct WeightTab
770 {
771 mfxU8 m_lumaWeightL0Flag:1;
772 mfxU8 m_chromaWeightL0Flag:1;
773 mfxU8 m_lumaWeightL1Flag:1;
774 mfxU8 m_chromaWeightL1Flag:1;
775
776 mfxI8 m_lumaWeightL0;
777 mfxI8 m_lumaOffsetL0;
778 mfxI8 m_lumaWeightL1;
779 mfxI8 m_lumaOffsetL1;
780 mfxI8 m_chromaWeightL0[2];
781 mfxI8 m_chromaOffsetL0[2];
782 mfxI8 m_chromaWeightL1[2];
783 mfxI8 m_chromaOffsetL1[2];
784 };
785
786 struct DpbFrame
787 {
DpbFrameDpbFrame788 DpbFrame() { Zero(*this); }
789
790 PairI32 m_poc;
791 mfxU32 m_frameOrder;
792 mfxU32 m_extFrameTag; // frameOrder assigned by application
793 mfxU32 m_frameNum;
794 mfxI32 m_frameNumWrap;
795 mfxI32 m_picNum[2];
796 mfxU32 m_viewIdx;
797 mfxU32 m_frameIdx;
798 mfxU32 m_tid;
799 PairU8 m_longTermPicNum;
800 PairU8 m_refPicFlag;
801 mfxU8 m_longTermIdxPlus1;
802 mfxU8 m_longterm; // at least one field is a long term reference
803 mfxU8 m_refBase;
804 mfxU8 m_keyRef; //short term reference stored in DPB as long as possible
805
806 mfxU8 m_PIFieldFlag; // for P/I field pair
807
808 mfxMemId m_midRec;
809 CmSurface2D * m_cmRaw;
810 CmSurface2D * m_cmRawLa;
811 CmBufferUP * m_cmMb;
812
813 CmBufferUP * m_cmHist;
814 void * m_cmHistSys;
815
816 mfxMemId m_midRaw; // for RefRaw mode
817 mfxFrameSurface1* m_yuvRaw; // for RefRaw mode
818 };
819
820 inline bool operator ==(DpbFrame const & l, DpbFrame const & r)
821 {
822 return l.m_frameIdx == r.m_frameIdx && l.m_poc == r.m_poc && l.m_viewIdx == r.m_viewIdx;
823 }
824
825 typedef FixedArray<mfxU32, 16> ArrayU32x16;
826 typedef FixedArray<mfxU32, 64> ArrayU32x64;
827 typedef FixedArray<mfxU16, 16> ArrayU16x16;
828 typedef FixedArray<mfxU8, 8> ArrayU8x8;
829 typedef FixedArray<mfxU8, 16> ArrayU8x16;
830 typedef FixedArray<mfxU8, 32> ArrayU8x32;
831 typedef FixedArray<mfxU8, 33> ArrayU8x33;
832 typedef FixedArray<PairU32, 16> ArrayPairU32x16;
833 typedef FixedArray<RefListMod, 32> ArrayRefListMod;
834
835 typedef FixedArray<mfxRoiDesc, 256> ArrayRoi;
836 typedef FixedArray<mfxRectDesc, MFX_MAX_DIRTY_RECT_COUNT> ArrayRect;
837 typedef FixedArray<mfxMovingRectDesc, MFX_MAX_MOVE_RECT_COUNT> ArrayMovingRect;
838
839 struct ArrayDpbFrame : public FixedArray<DpbFrame, 16>
840 {
ArrayDpbFrameArrayDpbFrame841 ArrayDpbFrame()
842 : FixedArray<DpbFrame, 16>()
843 {
844 m_maxLongTermFrameIdxPlus1.Resize(8, 0);
845 }
846
847 ArrayU8x8 m_maxLongTermFrameIdxPlus1; // for each temporal layer
848 };
849
850 struct DecRefPicMarkingInfo
851 {
DecRefPicMarkingInfoDecRefPicMarkingInfo852 DecRefPicMarkingInfo() { Zero(*this); }
853
854 void PushBack(mfxU8 op, mfxU32 param0, mfxU32 param1 = 0)
855 {
856 mmco.PushBack(op);
857 value.PushBack(param0);
858 value.PushBack(param1);
859 }
860
ClearDecRefPicMarkingInfo861 void Clear()
862 {
863 mmco.Resize(0);
864 value.Resize(0);
865 value.Resize(0);
866 }
867
868 mfxU8 no_output_of_prior_pics_flag;
869 mfxU8 long_term_reference_flag;
870 ArrayU8x32 mmco; // memory management control operation id
871 ArrayU32x64 value; // operation-dependent data, max 2 per operation
872 };
873
874 struct DecRefPicMarkingRepeatInfo
875 {
DecRefPicMarkingRepeatInfoDecRefPicMarkingRepeatInfo876 DecRefPicMarkingRepeatInfo()
877 : presentFlag(false)
878 , original_idr_flag(0)
879 , original_frame_num(0)
880 , original_field_pic_flag(0)
881 , original_bottom_field_flag(0)
882 , dec_ref_pic_marking()
883 {
884 }
885
886 bool presentFlag;
887 mfxU8 original_idr_flag;
888 mfxU16 original_frame_num;
889 mfxU8 original_field_pic_flag;
890 mfxU8 original_bottom_field_flag;
891 DecRefPicMarkingInfo dec_ref_pic_marking;
892 };
893 struct SliceStructInfo
894 {
895 mfxU32 startMB;
896 mfxU32 numMB;
897 mfxF32 weight;
898 mfxU32 cost;
899 };
900
901 struct BRCFrameParams : mfxBRCFrameParam
902 {
903 mfxU16 picStruct;
904 mfxU32 OptimalFrameSizeInBytes;
905 mfxU32 optimalBufferFullness;
906 };
907
908 class DdiTask : public Reconstruct
909 {
910 public:
DdiTask()911 DdiTask()
912 : Reconstruct()
913 , m_pushed(0)
914 , m_type(0, 0)
915 , m_QPdelta(0)
916 , m_bQPDelta(false)
917 , m_QPmodulation(0)
918 , m_currGopRefDist(0)
919 , m_dpb()
920 , m_internalListCtrlPresent(false)
921 , m_internalListCtrlHasPriority(true)
922 , m_internalListCtrlRefModLTR(false)
923 , m_keyReference(false)
924 , m_initCpbRemoval(0)
925 , m_initCpbRemovalOffset(0)
926 , m_cpbRemoval(0, 0)
927 , m_dpbOutputDelay(0)
928 , m_encOrder(mfxU32(-1))
929 , m_encOrderIdr(0)
930 , m_encOrderI(0)
931
932 , m_viewIdx(0)
933 , m_idx(NO_INDEX)
934 , m_idxBs(NO_INDEX, NO_INDEX)
935 , m_idxBsOffset(0)
936 , m_idxRecon(NO_INDEX)
937 , m_idxInterLayerRecon(0)
938 , m_idxReconOffset(0)
939 , m_idrPicId(mfxU16(-1))
940 , m_subMbPartitionAllowed(0, 0)
941 , m_cqpValue(0, 0)
942 , m_insertAud(0, 0)
943 , m_insertSps(0, 0)
944 , m_insertPps(0, 0)
945 , m_AUStartsFromSlice(0, 0)
946 , m_nalRefIdc(0, 0)
947 , m_statusReportNumber(0, 0)
948
949 , m_pid(0)
950 , m_fillerSize(0, 0)
951 , m_addRepackSize(0, 0)
952 , m_maxIFrameSize(0)
953 , m_maxPBFrameSize(0)
954 , m_numMbPerSlice(0)
955 , m_numSlice(0, 0)
956 , m_numRoi(0)
957 #if MFX_VERSION > 1021
958 , m_roiMode(MFX_ROI_MODE_PRIORITY)
959 #endif // #if MFX_VERSION > 1021
960 , m_numDirtyRect(0)
961 , m_numMovingRect(0)
962 , m_did(0)
963 , m_qid(0)
964 , m_storeRefBasePicFlag(0)
965
966 , m_bs(0)
967 , m_bsDataLength(0, 0)
968 , m_numLeadingFF(0, 0)
969 , m_qpY(0, 0)
970 , m_mad(0, 0)
971 , m_minFrameSize (0)
972 , m_notProtected(false)
973 , m_nextLayerTask(0)
974 , m_repack(0)
975 , m_fractionalQP(0)
976 #ifdef ENABLE_APQ_LQ
977 , m_ALQOffset(0)
978 #endif
979 , m_midRaw(MID_INVALID)
980 , m_midRec(MID_INVALID)
981 , m_midBit(mfxMemId(MID_INVALID))
982 #if defined(MFX_ENABLE_MCTF_IN_AVC)
983 , m_midMCTF(mfxMemId(MID_INVALID))
984 , m_idxMCTF(NO_INDEX)
985 , m_cmMCTF(0)
986 #endif
987 , m_cmRaw(0)
988 , m_cmRawLa(0)
989 , m_cmMb(0)
990 , m_cmMbSys(0)
991 , m_cmRefMb(0)
992 , m_cmCurbe(0)
993 , m_cmRefs(0)
994 , m_cmRefsLa(0)
995 , m_event(0)
996 , m_vmeData(0)
997 , m_fwdRef(0)
998 , m_bwdRef(0)
999 , m_fieldPicFlag(0)
1000 , m_singleFieldMode(false)
1001 , m_fieldCounter(0)
1002 , m_timeStamp(0)
1003 , m_decodeTimeStamp(0)
1004 , m_minQP(0)
1005 , m_maxQP(0)
1006 , m_resetBRC(false)
1007
1008 , m_idxMBQP(NO_INDEX)
1009 , m_midMBQP(MID_INVALID)
1010 , m_isMBQP(false)
1011 , m_isUseRawRef(false)
1012 , m_isSkipped (false)
1013 , m_toRecode (false)
1014 , m_isMBControl(false)
1015 , m_midMBControl(MID_INVALID)
1016 , m_idxMBControl(NO_INDEX)
1017
1018 , m_cmRawForHist(0)
1019 , m_cmHist(0)
1020 , m_cmHistSys(0)
1021 , m_isENCPAK(false)
1022 , m_startTime(0)
1023 #ifdef MFX_ENABLE_MFE
1024 , m_beginTime(0)
1025 , m_endTime(0)
1026 , m_flushMfe(0)
1027 , m_mfeTimeToWait(0)
1028 , m_userTimeout(false)
1029 #endif
1030 , m_hwType(MFX_HW_UNKNOWN)
1031 , m_TCBRCTargetFrameSize(0)
1032 , m_SceneChange(0)
1033 #if defined(MFX_ENABLE_MCTF_IN_AVC)
1034 , m_doMCTFIntraFiltering(0)
1035 #endif
1036 , m_LowDelayPyramidLayer(0)
1037 , m_frameLtrOff(1)
1038 , m_frameLtrReassign(0)
1039 , m_LtrOrder(-1)
1040 , m_LtrQp(0)
1041 , m_RefOrder(-1)
1042 , m_RefQp(0)
1043 , m_bFrameReady(false)
1044 , m_idxScd(0)
1045 , m_wsSubSamplingEv(0)
1046 , m_wsSubSamplingTask(0)
1047 , m_wsGpuImage(0)
1048 , m_wsIdxGpuImage(0)
1049 , m_Yscd(0)
1050 {
1051 Zero(m_ctrl);
1052 Zero(m_internalListCtrl);
1053 Zero(m_handleRaw);
1054 #if defined(MFX_ENABLE_MCTF_IN_AVC)
1055 Zero(m_handleMCTF);
1056 #endif
1057 Zero(m_fid);
1058 Zero(m_pwt);
1059 Zero(m_brcFrameParams);
1060 Zero(m_brcFrameCtrl);
1061 m_FrameName[0] = 0;
1062 #ifndef MFX_AVC_ENCODING_UNIT_DISABLE
1063 m_collectUnitsInfo = false;
1064 m_headersCache[0].reserve(10);
1065 m_headersCache[1].reserve(10);
1066 #endif
1067 }
1068
1069 bool operator == (const DdiTask& task)
1070 {
1071 if(&task == this) return true;
1072 return false;
1073 }
1074
GetFrameType()1075 mfxU8 GetFrameType() const
1076 {
1077 return m_type[GetFirstField()];
1078 }
1079
1080 // 0 - no skip, 1 - normal, 2 - pavp
SkipFlag()1081 mfxU8 SkipFlag() const
1082 {
1083 if ( m_ctrl.SkipFrame == 0
1084 || (m_type.top & MFX_FRAMETYPE_I)
1085 || (m_type.bot & MFX_FRAMETYPE_I))
1086 return 0;
1087 return (mfxU8)m_ctrl.SkipFrame;
1088 }
1089
1090 // Checking timeout for TDR hang detection
CheckForTDRHang(mfxU32 curTime,mfxU32 timeout)1091 bool CheckForTDRHang(mfxU32 curTime, mfxU32 timeout) const
1092 {
1093 MFX_TRACE_D(curTime);
1094 MFX_TRACE_D(m_startTime);
1095 MFX_TRACE_D(timeout);
1096
1097 if (m_startTime && timeout && (curTime - m_startTime) > timeout)
1098 {
1099 MFX_TRACE_S("Possible TDR hang:");
1100 MFX_TRACE_D(((curTime - m_startTime) > timeout));
1101 return true;
1102 }
1103
1104 return false;
1105 }
isSEIHRDParam(mfxExtCodingOption const & extOpt,mfxExtCodingOption2 const & extOpt2)1106 inline bool isSEIHRDParam(mfxExtCodingOption const & extOpt, mfxExtCodingOption2 const & extOpt2)
1107 {
1108 return (((GetFrameType() & MFX_FRAMETYPE_IDR) ||
1109 ((GetFrameType() & MFX_FRAMETYPE_I) && (extOpt2.BufferingPeriodSEI == MFX_BPSEI_IFRAME))) &&
1110 (IsOn(extOpt.VuiNalHrdParameters) || IsOn(extOpt.VuiVclHrdParameters)));
1111 }
1112
InitBRCParams()1113 inline void InitBRCParams()
1114 {
1115 Zero(m_brcFrameParams);
1116 Zero(m_brcFrameCtrl);
1117
1118 m_brcFrameParams.FrameType = m_type[m_fid[0]];
1119 m_brcFrameParams.DisplayOrder = m_frameOrder;
1120 m_brcFrameParams.EncodedOrder = m_encOrder;
1121 m_brcFrameParams.PyramidLayer = (mfxU16)m_loc.level;
1122 m_brcFrameParams.LongTerm = (m_longTermFrameIdx != NO_INDEX_U8) ? 1 : 0;
1123 m_brcFrameParams.SceneChange = (mfxU16)m_SceneChange;
1124 if (!m_brcFrameParams.PyramidLayer && (m_type[m_fid[0]] & MFX_FRAMETYPE_P) && m_LowDelayPyramidLayer)
1125 m_brcFrameParams.PyramidLayer = (mfxU16)m_LowDelayPyramidLayer;
1126 m_brcFrameParams.picStruct = GetPicStructForEncode();
1127 }
1128
1129 mfxEncodeCtrl m_ctrl;
1130 DdiTask * m_pushed; // task which was pushed to queue when this task was chosen for encoding
1131 Pair<mfxU8> m_type; // encoding type (one for each field)
1132 mfxI16 m_QPdelta;
1133 bool m_bQPDelta;
1134 mfxU16 m_QPmodulation;
1135 mfxU32 m_currGopRefDist;
1136
1137 // all info about references
1138 // everything is in pair because task is a per-frame object
1139 Pair<ArrayDpbFrame> m_dpb;
1140 ArrayDpbFrame m_dpbPostEncoding; // dpb after encoding a frame (or 2 fields)
1141 Pair<ArrayU8x33> m_list0;
1142 Pair<ArrayU8x33> m_list1;
1143 Pair<ArrayRefListMod> m_refPicList0Mod;
1144 Pair<ArrayRefListMod> m_refPicList1Mod;
1145 Pair<mfxU32> m_initSizeList0;
1146 Pair<mfxU32> m_initSizeList1;
1147
1148 // currently used for dpb control when svc temporal layers enabled
1149 mfxExtAVCRefListCtrl m_internalListCtrl;
1150 bool m_internalListCtrlPresent;
1151 bool m_internalListCtrlHasPriority;
1152 bool m_internalListCtrlRefModLTR;
1153 bool m_keyReference; // frame should be stored in DPB as long as possible
1154
1155 mfxU32 m_initCpbRemoval; // initial_cpb_removal_delay
1156 mfxU32 m_initCpbRemovalOffset; // initial_cpb_removal_delay_offset
1157 PairU32 m_cpbRemoval; // one for each field
1158 mfxU32 m_dpbOutputDelay; // one for entire frame
1159 mfxU32 m_encOrder;
1160 mfxU32 m_encOrderIdr;
1161 mfxU32 m_encOrderI;
1162
1163 Pair<DecRefPicMarkingRepeatInfo> m_decRefPicMrkRep; // for sei_message() which repeat dec_ref_pic_marking() of previous frame
1164 Pair<DecRefPicMarkingInfo> m_decRefPicMrk; // dec_ref_pic_marking() for current frame
1165
1166 mfxU32 m_viewIdx;
1167 mfxU32 m_idx; // index in chain of raw surfaces (set only when sysmem at input)
1168 PairU32 m_idxBs; // index of bitstream surfaces, 2 - for interlaced frame (snb only)
1169 mfxU32 m_idxBsOffset; // offset for multi-view coding
1170 mfxU32 m_idxRecon; // index of reconstructed surface
1171 mfxU32 m_idxInterLayerRecon; // index of reconstructed surface for inter-layer prediction
1172 mfxU32 m_idxReconOffset; // offset for multi-view coding
1173 mfxU16 m_idrPicId;
1174 PairU8 m_subMbPartitionAllowed;
1175 PairU8 m_cqpValue;
1176 PairU8 m_insertAud;
1177 PairU8 m_insertSps;
1178 PairU8 m_insertPps;
1179 PairU8 m_AUStartsFromSlice;
1180 PairU8 m_nalRefIdc;
1181 PairU32 m_statusReportNumber;
1182 mfxU32 m_pid; // priority_id
1183 PairU32 m_fillerSize;
1184 // MVC BD {
1185 PairU32 m_addRepackSize; // for SNB/IVB: size of padding to compensate re-pack of AVC headers to MVC headers
1186 // MVC BD }
1187 mfxU32 m_maxIFrameSize;
1188 mfxU32 m_maxPBFrameSize;
1189
1190 mfxU16 m_numMbPerSlice;
1191 PairU16 m_numSlice;
1192
1193 ArrayRoi m_roi;
1194 mfxU16 m_numRoi;
1195 #if MFX_VERSION > 1021
1196 mfxU16 m_roiMode;
1197 #endif // MFX_VERSION > 1021
1198 ArrayRect m_dirtyRect;
1199 mfxU16 m_numDirtyRect;
1200 ArrayMovingRect m_movingRect;
1201 mfxU16 m_numMovingRect;
1202
1203 mfxU32 m_did; // dependency_id
1204 mfxU32 m_qid; // quality_id
1205 mfxU32 m_storeRefBasePicFlag; // for svc key picture
1206
1207 mfxBitstream * m_bs; // output bitstream
1208 PairU32 m_bsDataLength; // bitstream size reported by driver (0 - progr/top, 1 - bottom)
1209 PairU32 m_numLeadingFF; // driver may insert 0xff in the beginning of coded frame
1210 PairU8 m_qpY; // QpY reported by driver
1211 PairU32 m_mad; // MAD
1212 BiFrameLocation m_loc;
1213 IntraRefreshState m_IRState;
1214 mfxU32 m_minFrameSize;
1215
1216 char m_FrameName[32];
1217
1218 bool m_notProtected; // Driver returns not protected data
1219 DdiTask const * m_nextLayerTask; // set to 0 if no nextLayerResolutionChange
1220 mfxU32 m_repack;
1221 mfxI32 m_fractionalQP; //if m_fractionalQP > 0 set it value in QM matrices
1222 #ifdef ENABLE_APQ_LQ
1223 mfxI32 m_ALQOffset; // MBQP Offset for Lambda QP adjustment
1224 #endif
1225
1226 mfxMemId m_midRaw; // self-allocated input surface (when app gives input frames in system memory)
1227 mfxMemId m_midRec; // reconstruction
1228 Pair<mfxMemId> m_midBit; // output bitstream
1229 mfxHDLPair m_handleRaw; // native handle to raw surface (self-allocated or given by app)
1230 #if defined(MFX_ENABLE_MCTF_IN_AVC)
1231 mfxMemId m_midMCTF;
1232 mfxHDLPair m_handleMCTF; // Handle to MCTF denoised surface
1233 mfxU32 m_idxMCTF;
1234 CmSurface2D * m_cmMCTF;
1235 #endif
1236 CmSurface2D * m_cmRaw; // CM surface made of m_handleRaw
1237 CmSurface2D * m_cmRawLa; // down-sized input surface for Lookahead
1238 CmBufferUP * m_cmMb; // macroblock data, VME kernel output
1239 void * m_cmMbSys; // pointer to associated system memory buffer
1240 CmBufferUP * m_cmRefMb; // macroblock data, VME kernel output for backward ref
1241 CmBuffer * m_cmCurbe; // control structure for ME & HME kernels
1242 SurfaceIndex * m_cmRefs; // VmeSurfaceG75 for ME kernel
1243 SurfaceIndex * m_cmRefsLa; // VmeSurfaceG75 for 2X kernel
1244 CmEvent * m_event;
1245 VmeData * m_vmeData;
1246 DdiTask const * m_fwdRef;
1247 DdiTask const * m_bwdRef;
1248
1249 mfxU8 m_fieldPicFlag; // true for frames with interlaced content
1250 bool m_singleFieldMode; // true for FEI single-field processing mode
1251
1252 // m_fid is a remapper of field parity to field order and vise versa.
1253 // i.e. parity = m_fid[fieldId] and fieldId = m_fid[parity] (fieldId == m_fid[m_fid[fieldId]]).
1254 // It is useful to switch between these two representation, because DdiTask stores all information
1255 // according to parity, but all of the per-field extension buffers are attached according to field order
1256 // (the only exception is mfxExtAVCRefLists).
1257 mfxU8 m_fid[2]; // progressive fid=[0,0]; tff fid=[0,1]; bff fid=[1,0]
1258 mfxU8 m_fieldCounter;
1259 mfxU64 m_timeStamp;
1260 mfxI64 m_decodeTimeStamp;
1261
1262 mfxU8 m_minQP;
1263 mfxU8 m_maxQP;
1264 std::vector<mfxU8> m_disableDeblockingIdc[2];
1265 std::vector<mfxI8> m_sliceAlphaC0OffsetDiv2[2];
1266 std::vector<mfxI8> m_sliceBetaOffsetDiv2[2];
1267
1268 bool m_resetBRC;
1269
1270 mfxU32 m_idxMBQP;
1271 mfxMemId m_midMBQP;
1272 bool m_isMBQP;
1273 bool m_isUseRawRef;
1274 bool m_isSkipped;
1275 bool m_toRecode;
1276
1277 bool m_isMBControl;
1278 mfxMemId m_midMBControl;
1279 mfxU32 m_idxMBControl;
1280
1281
1282 CmSurface2D * m_cmRawForHist;
1283 CmBufferUP * m_cmHist; // Histogram data, kernel output
1284 void * m_cmHistSys;
1285 mfxExtPredWeightTable m_pwt[2]; // obtained from fade detection
1286
1287 bool m_isENCPAK;
1288
1289 std::vector<void*> m_userData;
1290 std::vector<SliceStructInfo> m_SliceInfo;
1291
1292 mfxU32 m_startTime;
1293 #ifdef MFX_ENABLE_MFE
1294 vm_tick m_beginTime;//where we start counting
1295 vm_tick m_endTime;//where we get bitstream
1296 mfxU16 m_flushMfe;//flush MFE frame buffer
1297 mfxU32 m_mfeTimeToWait;//set by user or used equal to frame rate latency by default
1298 bool m_userTimeout;
1299 #endif
1300 eMFXHWType m_hwType; // keep HW type information
1301
1302
1303 #ifndef MFX_AVC_ENCODING_UNIT_DISABLE
1304 bool m_collectUnitsInfo;
1305 mutable std::vector<mfxEncodedUnitInfo> m_headersCache[2]; //Headers for every field
1306 #endif
1307 mfxU32 m_TCBRCTargetFrameSize;
1308 mfxU32 m_SceneChange;
1309 #if defined(MFX_ENABLE_MCTF_IN_AVC)
1310 mfxU32 m_doMCTFIntraFiltering;
1311 #endif
1312 mfxU32 m_LowDelayPyramidLayer;
1313 mfxU32 m_frameLtrOff;
1314 mfxU32 m_frameLtrReassign;
1315 mfxI32 m_LtrOrder;
1316 mfxI32 m_LtrQp;
1317 mfxI32 m_RefOrder;
1318 mfxI32 m_RefQp;
1319
1320 bool m_bFrameReady;
1321 mfxU32 m_idxScd;
1322 CmEvent *m_wsSubSamplingEv;
1323 CmTask *m_wsSubSamplingTask;
1324 CmSurface2DUP *m_wsGpuImage;
1325 SurfaceIndex *m_wsIdxGpuImage;
1326 mfxU8 *m_Yscd;
1327
1328 BRCFrameParams m_brcFrameParams;
1329 mfxBRCFrameCtrl m_brcFrameCtrl;
1330 };
1331
1332 typedef std::list<DdiTask>::iterator DdiTaskIter;
1333 typedef std::list<DdiTask>::const_iterator DdiTaskCiter;
1334
1335 class TaskManager
1336 {
1337 public:
1338 TaskManager();
1339
1340 ~TaskManager();
1341
1342 void Init(
1343 VideoCORE * core,
1344 MfxVideoParam const & video,
1345 mfxU32 viewIdx);
1346
1347 void Reset(
1348 MfxVideoParam const & video); // w/o re-allocation
1349
1350 void Close();
1351
1352 mfxStatus AssignTask(
1353 mfxEncodeCtrl * ctrl,
1354 mfxFrameSurface1 * surface,
1355 mfxBitstream * bs,
1356 DdiTask *& newTask,
1357 mfxU16 requiredFrameType = MFX_FRAMETYPE_UNKNOWN); //use provided frame type istead of frame type generator
1358
1359 void ConfirmTask(
1360 DdiTask & task);
1361
1362 void CompleteTask(
1363 DdiTask & task);
1364
GetEncodeStat()1365 mfxEncodeStat const & GetEncodeStat() const { return m_stat; }
1366
1367 mfxU32 CountRunningTasks();
1368
1369 protected:
1370 void BuildRefPicLists(
1371 DdiTask & task,
1372 mfxU32 field); // 0 - top/progressive, 1 - bottom
1373
1374 void ModifyRefPicLists(
1375 DdiTask & task,
1376 mfxU32 fieldId) const;
1377
1378 void UpdateDpb(
1379 DdiTask & task,
1380 mfxU32 fieldId,
1381 ArrayDpbFrame & dpbPostEncoding);
1382
1383 void UpdateRefFrames(
1384 ArrayDpbFrame const & dpb,
1385 DdiTask const & task,
1386 mfxU32 field);
1387
1388 void SwitchLastB2P();
1389
1390 DdiTask* PushNewTask(
1391 mfxFrameSurface1 * surface,
1392 mfxEncodeCtrl * ctrl,
1393 PairU8 type,
1394 mfxU32 frameOrder);
1395
1396 mfxU32 CountL1Refs(
1397 Reconstruct const & bframe) const;
1398
1399 mfxU32 FindFrameWithMinFrameNumWrap() const;
1400
1401 void ProcessFields(
1402 mfxU32 field,
1403 ArrayDpbFrame const & dpb,
1404 ArrayU8x33 const & picListFrm,
1405 ArrayU8x33 & picListFld) const;
1406
1407 bool IsSubmitted(
1408 DdiTask const & task) const;
1409
1410 DdiTask * SelectNextBFrameFromTail();
1411 DdiTask * FindFrameToEncode();
1412
1413 private:
1414 TaskManager(TaskManager const &);
1415 TaskManager & operator =(TaskManager const &);
1416
1417 VideoCORE * m_core;
1418 UMC::Mutex m_mutex;
1419 MfxVideoParam m_video;
1420
1421 std::vector<DdiTask> m_tasks;
1422 std::vector<Surface> m_raws;
1423 std::vector<Surface> m_bitstreams;
1424 std::vector<Reconstruct> m_recons;
1425
1426 mfxEncodeStat m_stat;
1427 FrameTypeGenerator m_frameTypeGen;
1428 ArrayDpbFrame m_dpb;
1429 DecRefPicMarkingRepeatInfo m_decRefPicMrkRep;
1430
1431 mfxU16 m_frameNum;
1432 mfxU16 m_frameNumMax;
1433 mfxU32 m_frameOrder;
1434 mfxU32 m_frameOrderIdr; // most recent idr frame in encoding order
1435 mfxU32 m_frameOrderI; // most recent i frame in encoding order
1436 mfxU16 m_idrPicId;
1437 mfxU32 m_viewIdx;
1438 mfxU32 m_cpbRemoval; // similar to frame_num but increments every frame (reference or not)
1439 mfxU32 m_cpbRemovalBufferingPeriod; // cpbRemoval of picture with previous buffering period
1440 mfxU32 m_numReorderFrames;
1441 DdiTask * m_pushed;
1442 };
1443
1444 template <size_t N>
1445 class Regression
1446 {
1447 public:
1448 static const mfxU32 MAX_WINDOW = N;
1449
Regression()1450 Regression() {
1451 Zero(x);
1452 Zero(y);
1453 }
Reset(mfxU32 size,mfxF64 initX,mfxF64 initY)1454 void Reset(mfxU32 size, mfxF64 initX, mfxF64 initY) {
1455 windowSize = size;
1456 normX = initX;
1457 std::fill_n(x, windowSize, initX);
1458 std::fill_n(y, windowSize, initY);
1459 sumxx = initX * initX * windowSize;
1460 sumxy = initX * initY * windowSize;
1461 }
Add(mfxF64 newx,mfxF64 newy)1462 void Add(mfxF64 newx, mfxF64 newy) {
1463 newy = newy / newx * normX;
1464 newx = normX;
1465 sumxy += newx * newy - x[0] * y[0];
1466 sumxx += newx * newx - x[0] * x[0];
1467 std::copy(x + 1, x + windowSize, x);
1468 std::copy(y + 1, y + windowSize, y);
1469 x[windowSize - 1] = newx;
1470 y[windowSize - 1] = newy;
1471 }
GetCoeff()1472 mfxF64 GetCoeff() const {
1473 return sumxy / sumxx;
1474 }
1475
1476 //protected:
1477 public: // temporary for debugging and dumping
1478 mfxF64 x[N];
1479 mfxF64 y[N];
1480 mfxU32 windowSize;
1481 mfxF64 normX;
1482 mfxF64 sumxy;
1483 mfxF64 sumxx;
1484 };
1485
1486 class BrcIface
1487 {
1488 public:
~BrcIface()1489 virtual ~BrcIface() {};
1490 virtual mfxStatus Init(MfxVideoParam & video) = 0;
1491 virtual mfxStatus Reset(MfxVideoParam & video) = 0;
1492 virtual void Close() = 0;
1493 virtual void PreEnc(const BRCFrameParams& par, std::vector<VmeData *> const & vmeData) = 0;
1494 virtual void GetQp(const BRCFrameParams& par, mfxBRCFrameCtrl &frameCtrl) = 0;
1495 virtual void GetQpForRecode(const BRCFrameParams& par, mfxBRCFrameCtrl &frameCtrl) = 0;
1496 virtual mfxF32 GetFractionalQp(const BRCFrameParams& par) = 0;
1497 virtual void SetQp(const BRCFrameParams& par, mfxBRCFrameCtrl &frameCtrl) = 0;
1498 virtual mfxU32 Report(const BRCFrameParams& par, mfxU32 userDataLength, mfxU32 maxFrameSize, mfxBRCFrameCtrl &frameCtrl) = 0;
1499 virtual mfxU32 GetMinFrameSize() = 0;
1500
SetFrameVMEData(const mfxExtLAFrameStatistics *,mfxU32,mfxU32)1501 virtual mfxStatus SetFrameVMEData(const mfxExtLAFrameStatistics*, mfxU32 , mfxU32 ) {return MFX_ERR_NONE;}
1502 };
1503
1504 BrcIface * CreateBrc(MfxVideoParam const & video, MFX_ENCODE_CAPS const & hwCaps);
1505
1506 class Brc : public BrcIface
1507 {
1508 public:
1509 Brc(BrcIface * impl = 0)
1510 {
1511 m_impl.reset(impl);
1512 }
SetImpl(BrcIface * impl)1513 void SetImpl(BrcIface * impl)
1514 {
1515 m_impl.reset(impl);
1516 }
~Brc()1517 ~Brc()
1518 {
1519 }
Init(MfxVideoParam & video)1520 mfxStatus Init(MfxVideoParam & video)
1521 {
1522 return m_impl->Init(video);
1523 }
Reset(MfxVideoParam & video)1524 mfxStatus Reset(MfxVideoParam & video)
1525 {
1526 return m_impl->Reset(video);
1527 }
Close()1528 void Close()
1529 {
1530 m_impl->Close();
1531 }
PreEnc(const BRCFrameParams & par,std::vector<VmeData * > const & vmeData)1532 void PreEnc(const BRCFrameParams& par, std::vector<VmeData *> const & vmeData)
1533 {
1534 m_impl->PreEnc(par, vmeData);
1535 }
GetQp(const BRCFrameParams & par,mfxBRCFrameCtrl & frameCtrl)1536 void GetQp(const BRCFrameParams& par, mfxBRCFrameCtrl &frameCtrl)
1537 {
1538 m_impl->GetQp(par, frameCtrl);
1539 }
GetQpForRecode(const BRCFrameParams & par,mfxBRCFrameCtrl & frameCtrl)1540 void GetQpForRecode(const BRCFrameParams& par, mfxBRCFrameCtrl &frameCtrl)
1541 {
1542 m_impl->GetQpForRecode(par, frameCtrl);
1543 }
GetFractionalQp(const BRCFrameParams & par)1544 mfxF32 GetFractionalQp(const BRCFrameParams& par)
1545 {
1546 return m_impl->GetFractionalQp(par);
1547 }
SetQp(const BRCFrameParams & par,mfxBRCFrameCtrl & frameCtrl)1548 void SetQp(const BRCFrameParams& par, mfxBRCFrameCtrl &frameCtrl)
1549 {
1550 m_impl->SetQp(par, frameCtrl);
1551 }
Report(const BRCFrameParams & par,mfxU32 userDataLength,mfxU32 maxFrameSize,mfxBRCFrameCtrl & frameCtrl)1552 mfxU32 Report(const BRCFrameParams& par, mfxU32 userDataLength, mfxU32 maxFrameSize, mfxBRCFrameCtrl &frameCtrl)
1553 {
1554 return m_impl->Report(par, userDataLength, maxFrameSize, frameCtrl);
1555 }
GetMinFrameSize()1556 mfxU32 GetMinFrameSize()
1557 {
1558 return m_impl->GetMinFrameSize();
1559 }
SetFrameVMEData(const mfxExtLAFrameStatistics * pLAOutput,mfxU32 width,mfxU32 height)1560 mfxStatus SetFrameVMEData(const mfxExtLAFrameStatistics * pLAOutput, mfxU32 width, mfxU32 height)
1561 {
1562 return m_impl->SetFrameVMEData(pLAOutput,width,height);
1563 }
1564 private:
1565 std::unique_ptr<BrcIface> m_impl;
1566 };
1567
1568 class UmcBrc : public BrcIface
1569 {
1570 public:
~UmcBrc()1571 ~UmcBrc() { Close(); }
1572
1573 mfxStatus Init(MfxVideoParam & video);
Reset(MfxVideoParam &)1574 mfxStatus Reset(MfxVideoParam & ) { return MFX_ERR_NONE; };
1575 void Close();
1576
1577 void GetQp(const BRCFrameParams& par, mfxBRCFrameCtrl &frameCtrl);
1578 void GetQpForRecode(const BRCFrameParams& par, mfxBRCFrameCtrl &frameCtrl);
1579
1580 mfxF32 GetFractionalQp(const BRCFrameParams& par);
1581
1582 void SetQp(const BRCFrameParams& par, mfxBRCFrameCtrl &frameCtrl);
1583
1584 void PreEnc(const BRCFrameParams& par, std::vector<VmeData *> const & vmeData);
1585
1586 mfxU32 Report(const BRCFrameParams& par, mfxU32 userDataLength, mfxU32 maxFrameSize, mfxBRCFrameCtrl &frameCtrl);
1587
1588 mfxU32 GetMinFrameSize();
1589
1590 private:
1591 UMC::H264BRC m_impl;
1592 mfxU32 m_lookAhead;
1593 };
1594
1595 class Hrd
1596 {
1597 public:
1598 Hrd();
1599
1600 void Setup(MfxVideoParam const & par);
1601
1602 void Reset(MfxVideoParam const & par);
1603
1604 void RemoveAccessUnit(
1605 mfxU32 size,
1606 mfxU32 interlace,
1607 mfxU32 bufferingPeriod);
1608
1609 mfxU32 GetInitCpbRemovalDelay() const;
1610
1611 mfxU32 GetInitCpbRemovalDelayOffset() const;
1612 mfxU32 GetMaxFrameSize(mfxU32 bufferingPeriod) const;
1613
1614 private:
1615 mfxU32 m_bitrate;
1616 mfxU32 m_rcMethod;
1617 mfxU32 m_hrdIn90k; // size of hrd buffer in 90kHz units
1618
1619 double m_tick; // clock tick
1620 double m_trn_cur; // nominal removal time
1621 double m_taf_prv; // final arrival time of prev unit
1622
1623 bool m_bIsHrdRequired;
1624 };
1625
1626 struct sLAThresholds
1627 {
1628 mfxU32 minFramesForClassicLA; // number of frames is needed for classic LA, if lookAhead < minFramesForClassicLA -> short LA
1629 mfxU32 minFramesForStat; // number of frames at the start of stream which must be analyzed with fixed rate
1630 mfxU32 minCostCalcPeriod; // minimum number of frames to calulate cost. costCalcPeriod >= lookAhead, costCalcPeriod < rateCalcPeriod
1631 mfxF64 maxRateRatioLocal; // maximum allowed ratio = realRate/initialRate, real rate is calculated per costCalcPeriod
1632 mfxF64 minRateRatioLocal; // minimum allowed ratio = realRate/initialRate, real rate is calculated per costCalcPeriod
1633 mfxF64 maxAvgRateRatio; // maximum allowed ratio = avgRate/initialRate, avg rate is calculated per rateCalcPeriod
1634 mfxF64 minAvgRateRatio; // minimum allowed ratio = avgRate/initialRate, avg rate is calculated per rateCalcPeriod
1635 };
1636
1637 class LookAheadBrc2 : public BrcIface
1638 {
1639 public:
~LookAheadBrc2()1640 ~LookAheadBrc2() { Close(); }
1641
1642 mfxStatus Init (MfxVideoParam & video);
Reset(MfxVideoParam &)1643 mfxStatus Reset(MfxVideoParam & ) { return MFX_ERR_NONE; };
1644
1645 void Close();
1646
1647 void GetQp(const BRCFrameParams& par, mfxBRCFrameCtrl &frameCtrl);
1648 void GetQpForRecode(const BRCFrameParams& par, mfxBRCFrameCtrl &frameCtrl);
GetFractionalQp(const BRCFrameParams &)1649 mfxF32 GetFractionalQp(const BRCFrameParams& ) { assert(0); return 26.0f; }
1650
1651
1652 void PreEnc(const BRCFrameParams& par, std::vector<VmeData *> const & vmeData);
1653
1654 mfxU32 Report(const BRCFrameParams& par, mfxU32 userDataLength, mfxU32 maxFrameSize, mfxBRCFrameCtrl &frameCtrl);
1655
GetMinFrameSize()1656 mfxU32 GetMinFrameSize() { return 0; }
1657 void SetQp(const BRCFrameParams& par, mfxBRCFrameCtrl &frameCtrl);
1658
1659 public:
1660 struct LaFrameData
1661 {
1662 mfxU32 encOrder;
1663 mfxI32 poc;
1664 mfxI32 deltaQp;
1665 mfxF64 estRate[52];
1666 mfxF64 estRateTotal[52];
1667 mfxU32 interCost;
1668 mfxU32 intraCost;
1669 mfxU32 propCost;
1670 mfxU32 bframe;
1671 };
1672
1673 protected:
1674 sLAThresholds m_thresholds;
1675 mfxU32 m_lookAhead;
1676 mfxU32 m_lookAheadDep;
1677 mfxU16 m_LaScaleFactor;
1678 mfxU32 m_strength;
1679 mfxU32 m_totNumMb;
1680 mfxF64 m_initTargetRate;
1681 mfxF64 m_currRate;
1682 mfxU32 m_framesBehind;
1683 mfxF64 m_bitsBehind;
1684 mfxI32 m_curBaseQp;
1685 mfxI32 m_curQp;
1686 mfxU16 m_qpUpdateRange;
1687 //mfxF32 m_coef;
1688 mfxF64 m_fr;
1689 mfxU16 m_AsyncDepth;
1690 mfxU16 m_first;
1691 mfxU16 m_skipped;
1692 mfxU8 m_QPMin[3]; // for I, P and B
1693 mfxU8 m_QPMax[3]; // for I, P and B
1694 mfxU32 m_MaxframeSize[3];
1695 mfxU32 m_maxFrameSizeForRec;
1696 mfxU32 m_rateCalcPeriod;
1697 mfxU32 m_costCalcPeriod;
1698
1699 AVGBitrate* m_AvgBitrate; //sliding window
1700 std::unique_ptr<Hrd> m_hrd;
1701
1702 std::vector<LaFrameData> m_laData;
1703 std::vector<LaFrameData> m_laDataStat;
1704 Regression<20> m_rateCoeffHistory[52];
1705
1706 void ClearStat(mfxU32 frameOrder);
1707 void SaveStat(mfxU32 frameOrder);
1708 };
1709
1710 class VMEBrc : public BrcIface
1711 {
1712 public:
~VMEBrc()1713 ~VMEBrc() { Close(); }
1714
1715 mfxStatus Init(MfxVideoParam & video);
Reset(MfxVideoParam &)1716 mfxStatus Reset(MfxVideoParam & ) { return MFX_ERR_NONE; }
1717 void Close();
1718
1719 void GetQp(const BRCFrameParams& par, mfxBRCFrameCtrl &frameCtrl);
1720 void GetQpForRecode(const BRCFrameParams& par, mfxBRCFrameCtrl &frameCtrl);
1721
GetFractionalQp(const BRCFrameParams &)1722 mfxF32 GetFractionalQp(const BRCFrameParams& ) { assert(0); return 26.0f; }
1723
SetQp(const BRCFrameParams &,mfxBRCFrameCtrl &)1724 void SetQp(const BRCFrameParams& , mfxBRCFrameCtrl & ) { assert(0); }
1725
1726 void PreEnc(const BRCFrameParams& par, std::vector<VmeData *> const & vmeData);
1727
1728 mfxU32 Report(const BRCFrameParams& par, mfxU32 userDataLength, mfxU32 maxFrameSize, mfxBRCFrameCtrl &frameCtrl);
1729
GetMinFrameSize()1730 mfxU32 GetMinFrameSize() { return 0; }
1731
1732 mfxStatus SetFrameVMEData(const mfxExtLAFrameStatistics *, mfxU32 widthMB, mfxU32 heightMB );
1733
1734
1735 public:
1736 struct LaFrameData
1737 {
1738 mfxU32 encOrder;
1739 mfxU32 dispOrder;
1740 mfxI32 poc;
1741 mfxI32 deltaQp;
1742 mfxF64 estRate[52];
1743 mfxF64 estRateTotal[52];
1744 mfxU32 interCost;
1745 mfxU32 intraCost;
1746 mfxU32 propCost;
1747 mfxU32 bframe;
1748 bool bNotUsed;
1749 };
1750
1751 protected:
1752 mfxU32 m_lookAhead;
1753 mfxU16 m_LaScaleFactor;
1754 mfxU32 m_strength;
1755 mfxU32 m_totNumMb;
1756 mfxF64 m_initTargetRate;
1757 mfxF64 m_targetRateMin;
1758 mfxF64 m_targetRateMax;
1759 mfxU32 m_framesBehind;
1760 mfxF64 m_bitsBehind;
1761 mfxI32 m_curBaseQp;
1762 mfxI32 m_curQp;
1763 mfxU16 m_qpUpdateRange;
1764 mfxF64 m_fr;
1765 mfxU16 m_skipped;
1766 mfxU8 m_QPMin[3]; // for I, P and B
1767 mfxU8 m_QPMax[3]; // for I, P and B
1768 mfxU32 m_maxFrameSize;
1769
1770
1771 AVGBitrate* m_AvgBitrate;
1772
1773 std::list <LaFrameData> m_laData;
1774 Regression<20> m_rateCoeffHistory[52];
1775 };
1776
1777 class LookAheadCrfBrc : public BrcIface
1778 {
1779 public:
~LookAheadCrfBrc()1780 ~LookAheadCrfBrc() { Close(); }
1781
1782 mfxStatus Init(MfxVideoParam & video);
Reset(MfxVideoParam &)1783 mfxStatus Reset(MfxVideoParam & ) {return MFX_ERR_NONE;};
1784
Close()1785 void Close() {}
1786
1787 void GetQp(const BRCFrameParams& par, mfxBRCFrameCtrl &frameCtrl);
1788 void GetQpForRecode(const BRCFrameParams& par, mfxBRCFrameCtrl &frameCtrl);
GetFractionalQp(const BRCFrameParams &)1789 mfxF32 GetFractionalQp(const BRCFrameParams& /*par*/) { assert(0); return 26.0f; }
1790
SetQp(const BRCFrameParams &,mfxBRCFrameCtrl &)1791 void SetQp(const BRCFrameParams& /*par*/, mfxBRCFrameCtrl & /*frameCtrl*/) { assert(0); }
1792
1793 void PreEnc(const BRCFrameParams& par, std::vector<VmeData *> const & vmeData);
1794
1795 mfxU32 Report(const BRCFrameParams& par, mfxU32 userDataLength, mfxU32 maxFrameSize, mfxBRCFrameCtrl &frameCtrl);
1796
GetMinFrameSize()1797 mfxU32 GetMinFrameSize() { return 0; }
1798
1799 protected:
1800 mfxU32 m_lookAhead;
1801 mfxI32 m_crfQuality;
1802 mfxI32 m_curQp;
1803 mfxU32 m_totNumMb;
1804 mfxU32 m_intraCost;
1805 mfxU32 m_interCost;
1806 mfxU32 m_propCost;
1807 mfxU8 m_QPMin[3]; // for I, P and B
1808 mfxU8 m_QPMax[3]; // for I, P and B
1809 };
1810 class H264SWBRC : public BrcIface
1811 {
1812 public:
H264SWBRC()1813 H264SWBRC():
1814 m_minSize(0),
1815 m_pBRC(0)
1816 {
1817 memset(&m_BRCLocal,0, sizeof(m_BRCLocal));
1818 }
~H264SWBRC()1819 virtual ~H264SWBRC()
1820 {
1821 Close();
1822 }
1823
1824
Init(MfxVideoParam & video)1825 mfxStatus Init(MfxVideoParam &video)
1826 {
1827 mfxStatus sts = MFX_ERR_NONE;
1828 mfxExtBRC * extBRC = GetExtBuffer(video);
1829
1830
1831 if (extBRC->pthis)
1832 {
1833 m_pBRC = extBRC;
1834 }
1835 else
1836 {
1837 sts = HEVCExtBRC::Create(m_BRCLocal);
1838 m_pBRC = &m_BRCLocal;
1839 }
1840 sts = m_pBRC->Init(m_pBRC->pthis, &video);
1841 return sts;
1842 }
Close()1843 void Close()
1844 {
1845 m_pBRC->Close(m_pBRC->pthis);
1846 HEVCExtBRC::Destroy(m_BRCLocal);
1847 }
Reset(MfxVideoParam & video)1848 mfxStatus Reset(MfxVideoParam &video )
1849 {
1850 return m_pBRC->Reset(m_pBRC->pthis,&video);
1851 }
Report(const BRCFrameParams & par,mfxU32,mfxU32,mfxBRCFrameCtrl & frameCtrl)1852 mfxU32 Report(const BRCFrameParams& par, mfxU32 /*userDataLength*/, mfxU32 /*maxFrameSize*/, mfxBRCFrameCtrl &frameCtrl)
1853 {
1854 mfxBRCFrameStatus frame_sts = {};
1855 mfxBRCFrameParam frame_par = *((mfxBRCFrameParam*)&par);
1856
1857 mfxStatus sts = m_pBRC->Update(m_pBRC->pthis,&frame_par, &frameCtrl, &frame_sts);
1858 MFX_CHECK(sts == MFX_ERR_NONE, (mfxU32)UMC::BRC_ERROR); // BRC_ERROR
1859
1860 m_minSize = frame_sts.MinFrameSize;
1861
1862 switch (frame_sts.BRCStatus)
1863 {
1864 case ::MFX_BRC_OK:
1865 return UMC::BRC_OK;
1866 case ::MFX_BRC_BIG_FRAME:
1867 return UMC::BRC_ERR_BIG_FRAME;
1868 case ::MFX_BRC_SMALL_FRAME:
1869 return UMC::BRC_ERR_SMALL_FRAME;
1870 case ::MFX_BRC_PANIC_BIG_FRAME:
1871 return UMC::BRC_ERR_BIG_FRAME | UMC::BRC_NOT_ENOUGH_BUFFER;
1872 case ::MFX_BRC_PANIC_SMALL_FRAME:
1873 return UMC::BRC_ERR_SMALL_FRAME| UMC::BRC_NOT_ENOUGH_BUFFER;
1874 }
1875 return MFX_BRC_OK;
1876 }
GetQp(const BRCFrameParams & par,mfxBRCFrameCtrl & frameCtrl)1877 void GetQp(const BRCFrameParams& par, mfxBRCFrameCtrl &frameCtrl)
1878 {
1879 mfxBRCFrameParam frame_par = *((mfxBRCFrameParam*)&par);
1880 m_pBRC->GetFrameCtrl(m_pBRC->pthis,&frame_par, &frameCtrl);
1881 frameCtrl.QpY = (mfxU8)mfx::clamp(frameCtrl.QpY, 1, 51);
1882 }
GetQpForRecode(const BRCFrameParams & par,mfxBRCFrameCtrl & frameCtrl)1883 void GetQpForRecode(const BRCFrameParams& par, mfxBRCFrameCtrl &frameCtrl)
1884 {
1885 GetQp(par, frameCtrl);
1886 }
1887
SetQp(const BRCFrameParams &,mfxBRCFrameCtrl &)1888 void SetQp(const BRCFrameParams& /*par*/, mfxBRCFrameCtrl &/*frameCtrl*/)
1889 {
1890 }
GetMinFrameSize()1891 mfxU32 GetMinFrameSize()
1892 {
1893 return m_minSize;
1894
1895 }
GetFractionalQp(const BRCFrameParams &)1896 mfxF32 GetFractionalQp(const BRCFrameParams& /*par*/) { assert(0); return 26.0f; }
1897
PreEnc(const BRCFrameParams &,std::vector<VmeData * > const &)1898 virtual void PreEnc(const BRCFrameParams& /*par*/, std::vector<VmeData *> const & /* vmeData */) {}
SetFrameVMEData(const mfxExtLAFrameStatistics *,mfxU32,mfxU32)1899 virtual mfxStatus SetFrameVMEData(const mfxExtLAFrameStatistics*, mfxU32 , mfxU32 )
1900 {
1901 return MFX_ERR_UNDEFINED_BEHAVIOR;
1902 }
IsVMEBRC()1903 virtual bool IsVMEBRC() {return false;}
1904
1905 private:
1906 mfxU32 m_minSize;
1907 mfxExtBRC * m_pBRC;
1908 mfxExtBRC m_BRCLocal;
1909
1910 };
1911
1912
1913 #if defined(MFX_ENABLE_ENCTOOLS)
1914
IsNotDefined(mfxU16 param)1915 inline bool IsNotDefined(mfxU16 param)
1916 {
1917 return (param == MFX_CODINGOPTION_UNKNOWN);
1918
1919 }
IsEncToolsOptOn(mfxExtEncToolsConfig & config)1920 inline bool IsEncToolsOptOn(mfxExtEncToolsConfig &config)
1921 {
1922 return
1923 (IsOn(config.AdaptiveI) ||
1924 IsOn(config.AdaptiveB) ||
1925 IsOn(config.AdaptiveRefP) ||
1926 IsOn(config.AdaptiveRefB) ||
1927 IsOn(config.SceneChange) ||
1928 IsOn(config.AdaptiveLTR) ||
1929 IsOn(config.AdaptivePyramidQuantP) ||
1930 IsOn(config.AdaptivePyramidQuantB) ||
1931 IsOn(config.AdaptiveQuantMatrices) ||
1932 IsOn(config.BRCBufferHints) ||
1933 IsOn(config.BRC));
1934
1935 }
ResetEncToolsPar(mfxExtEncToolsConfig & config,mfxU16 value)1936 inline void ResetEncToolsPar(mfxExtEncToolsConfig &config, mfxU16 value)
1937 {
1938 config.AdaptiveI =
1939 config.AdaptiveB =
1940 config.AdaptiveRefP =
1941 config.AdaptiveRefB =
1942 config.SceneChange =
1943 config.AdaptiveLTR =
1944 config.AdaptivePyramidQuantP =
1945 config.AdaptivePyramidQuantB =
1946 config.AdaptiveQuantMatrices =
1947 config.BRCBufferHints =
1948 config.BRC = value;
1949
1950 }
InitCtrl(mfxVideoParam const & par,mfxEncToolsCtrl * ctrl)1951 static mfxStatus InitCtrl(mfxVideoParam const & par, mfxEncToolsCtrl *ctrl)
1952 {
1953 MFX_CHECK_NULL_PTR1(ctrl);
1954
1955 mfxExtCodingOption *CO = (mfxExtCodingOption *)GetExtBuffer(par.ExtParam, par.NumExtParam, MFX_EXTBUFF_CODING_OPTION);
1956 mfxExtCodingOption2 *CO2 = (mfxExtCodingOption2 *)GetExtBuffer(par.ExtParam, par.NumExtParam, MFX_EXTBUFF_CODING_OPTION2);
1957 mfxExtCodingOption3 *CO3 = (mfxExtCodingOption3 *)GetExtBuffer(par.ExtParam, par.NumExtParam, MFX_EXTBUFF_CODING_OPTION3);
1958 MFX_CHECK_NULL_PTR3(CO, CO2, CO3);
1959
1960
1961 ctrl->CodecId = par.mfx.CodecId;
1962 ctrl->CodecProfile = par.mfx.CodecProfile;
1963 ctrl->CodecLevel = par.mfx.CodecLevel;
1964
1965 ctrl->FrameInfo = par.mfx.FrameInfo;
1966 ctrl->IOPattern = par.IOPattern;
1967 ctrl->MaxDelayInFrames = CO2->LookAheadDepth;
1968
1969 ctrl->MaxGopSize = par.mfx.GopPicSize;
1970 ctrl->MaxGopRefDist = par.mfx.GopRefDist;
1971 ctrl->MaxIDRDist = par.mfx.GopPicSize * (par.mfx.IdrInterval + 1);
1972 ctrl->BRefType = CO2->BRefType;
1973
1974 ctrl->ScenarioInfo = CO3->ScenarioInfo;
1975
1976 // Rate control info
1977 mfxU32 mult = par.mfx.BRCParamMultiplier ? par.mfx.BRCParamMultiplier : 1;
1978 bool BRC = (par.mfx.RateControlMethod == MFX_RATECONTROL_CBR ||
1979 par.mfx.RateControlMethod == MFX_RATECONTROL_VBR);
1980
1981 ctrl->RateControlMethod = par.mfx.RateControlMethod; //CBR, VBR, CRF,CQP
1982
1983
1984 if (!BRC)
1985 {
1986 ctrl->QPLevel[0] = par.mfx.QPI;
1987 ctrl->QPLevel[1] = par.mfx.QPP;
1988 ctrl->QPLevel[2] = par.mfx.QPB;
1989 }
1990
1991 else
1992 {
1993 ctrl->TargetKbps = par.mfx.TargetKbps*mult;
1994 ctrl->MaxKbps = par.mfx.MaxKbps*mult;
1995
1996 ctrl->HRDConformance = MFX_BRC_NO_HRD;
1997 if (!IsOff(CO->NalHrdConformance) && !IsOff(CO->VuiNalHrdParameters))
1998 ctrl->HRDConformance = MFX_BRC_HRD_STRONG;
1999 else if (IsOn(CO->NalHrdConformance) && IsOff(CO->VuiNalHrdParameters))
2000 ctrl->HRDConformance = MFX_BRC_HRD_WEAK;
2001
2002
2003 if (ctrl->HRDConformance)
2004 {
2005 ctrl->BufferSizeInKB = par.mfx.BufferSizeInKB*mult; //if HRDConformance is ON
2006 ctrl->InitialDelayInKB = par.mfx.InitialDelayInKB*mult; //if HRDConformance is ON
2007 }
2008 else
2009 {
2010 ctrl->ConvergencePeriod = 0; //if HRDConformance is OFF, 0 - the period is whole stream,
2011 ctrl->Accuracy = 10; //if HRDConformance is OFF
2012 }
2013 ctrl->WinBRCMaxAvgKbps = CO3->WinBRCMaxAvgKbps*mult;
2014 ctrl->WinBRCSize = CO3->WinBRCSize;
2015 ctrl->MaxFrameSizeInBytes[0] = CO3->MaxFrameSizeI ? CO3->MaxFrameSizeI : CO2->MaxFrameSize; // MaxFrameSize limitation
2016 ctrl->MaxFrameSizeInBytes[1] = CO3->MaxFrameSizeP ? CO3->MaxFrameSizeP : CO2->MaxFrameSize;
2017 ctrl->MaxFrameSizeInBytes[2] = CO2->MaxFrameSize;
2018
2019 ctrl->MinQPLevel[0] = CO2->MinQPI; //QP range limitations
2020 ctrl->MinQPLevel[1] = CO2->MinQPP;
2021 ctrl->MinQPLevel[2] = CO2->MinQPB;
2022
2023 ctrl->MaxQPLevel[0] = CO2->MaxQPI; //QP range limitations
2024 ctrl->MaxQPLevel[1] = CO2->MaxQPP;
2025 ctrl->MaxQPLevel[2] = CO2->MaxQPB;
2026
2027 ctrl->PanicMode = CO3->BRCPanicMode;
2028
2029 }
2030 if (ctrl->NumExtParam > 1)
2031 {
2032 ctrl->ExtParam[0] = GetExtBuffer(par.ExtParam, par.NumExtParam, MFX_EXTBUFF_ENCTOOLS_DEVICE);
2033 ctrl->ExtParam[1] = GetExtBuffer(par.ExtParam, par.NumExtParam, MFX_EXTBUFF_ENCTOOLS_ALLOCATOR);
2034 }
2035
2036 return MFX_ERR_NONE;
2037
2038 }
2039 class H264EncTools
2040 {
2041 public:
2042
~H264EncTools()2043 virtual ~H264EncTools()
2044 {
2045 Close();
2046 }
2047
2048
isEncToolNeeded(MfxVideoParam & video)2049 static bool isEncToolNeeded(MfxVideoParam &video)
2050 {
2051 if (!(video.mfx.RateControlMethod == MFX_RATECONTROL_CBR || video.mfx.RateControlMethod == MFX_RATECONTROL_VBR || video.mfx.RateControlMethod == MFX_RATECONTROL_CQP))
2052 return false;
2053
2054 mfxEncTools *encTools = GetExtBuffer(video);
2055 mfxExtEncToolsConfig *config = GetExtBuffer(video);
2056
2057 if (!(encTools && encTools->Context) && (!config))
2058 return false;
2059
2060 mfxExtEncToolsConfig tmpConfig = {};
2061 if (config)
2062 tmpConfig = *config;
2063
2064 GetRequiredFunc(video, tmpConfig);
2065
2066 return IsEncToolsOptOn(tmpConfig);
2067 }
IsPreEncNeeded()2068 bool IsPreEncNeeded()
2069 {
2070 if (m_pEncTools && m_EncToolCtrl.ScenarioInfo != MFX_SCENARIO_GAME_STREAMING)
2071 {
2072 return
2073 (IsOn(m_EncToolConfig.AdaptiveI) ||
2074 IsOn(m_EncToolConfig.AdaptiveB) ||
2075 IsOn(m_EncToolConfig.AdaptiveRefP) ||
2076 IsOn(m_EncToolConfig.AdaptiveRefB) ||
2077 IsOn(m_EncToolConfig.SceneChange) ||
2078 IsOn(m_EncToolConfig.AdaptiveLTR) ||
2079 IsOn(m_EncToolConfig.AdaptivePyramidQuantP) ||
2080 IsOn(m_EncToolConfig.AdaptivePyramidQuantB));
2081 }
2082 return false;
2083 }
IsLookAhead()2084 inline bool IsLookAhead()
2085 {
2086 if (m_pEncTools && m_EncToolCtrl.ScenarioInfo == MFX_SCENARIO_GAME_STREAMING)
2087 {
2088 return
2089 (IsOn(m_EncToolConfig.AdaptiveI) ||
2090 IsOn(m_EncToolConfig.AdaptiveB) ||
2091 IsOn(m_EncToolConfig.SceneChange) ||
2092 IsOn(m_EncToolConfig.AdaptivePyramidQuantP) ||
2093 IsOn(m_EncToolConfig.BRCBufferHints) ||
2094 IsOn(m_EncToolConfig.AdaptiveQuantMatrices));
2095 }
2096 return false;
2097 }
IsAdaptiveGOP()2098 inline bool IsAdaptiveGOP()
2099 {
2100 return (m_pEncTools != 0 &&
2101 (IsOn(m_EncToolConfig.AdaptiveI) ||
2102 IsOn(m_EncToolConfig.AdaptiveB)));
2103 }
IsAdaptiveQP()2104 inline bool IsAdaptiveQP()
2105 {
2106 return (m_pEncTools != 0 &&
2107 (IsOn(m_EncToolConfig.AdaptivePyramidQuantP) ||
2108 IsOn(m_EncToolConfig.AdaptivePyramidQuantB)));
2109 }
IsAdaptiveRef()2110 inline bool IsAdaptiveRef()
2111 {
2112 return (m_pEncTools != 0 &&
2113 (IsOn(m_EncToolConfig.AdaptiveRefP) ||
2114 IsOn(m_EncToolConfig.AdaptiveRefB)));
2115 }
IsAdaptiveLTR()2116 inline bool IsAdaptiveLTR()
2117 {
2118 return (m_pEncTools != 0 &&
2119 IsOn(m_EncToolConfig.AdaptiveLTR));
2120 }
IsBRC()2121 inline bool IsBRC()
2122 {
2123 return (m_pEncTools != 0 &&
2124 IsOn(m_EncToolConfig.BRC));
2125 }
2126
GetPreEncDelay(const MfxVideoParam & par)2127 static mfxU32 GetPreEncDelay(const MfxVideoParam &par)
2128 {
2129 MfxVideoParam video = par;
2130 if (!isEncToolNeeded(video))
2131 return 0;
2132
2133 bool bCreated = false;
2134
2135 mfxEncTools *encTools = 0;
2136 mfxExtEncToolsConfig supportedConfig = {};
2137 mfxExtEncToolsConfig requiredConfig = {};
2138 mfxEncToolsCtrl ctrl = {};
2139
2140 MFX_CHECK_STS(CreateEncTools(video, encTools, bCreated));
2141 MFX_CHECK_STS(InitCtrl(video, &ctrl));
2142
2143 encTools->GetSupportedConfig(encTools->Context, &supportedConfig,&ctrl);
2144
2145 CorrectVideoParams(video, supportedConfig);
2146 GetRequiredFunc(video, requiredConfig);
2147
2148 mfxU32 numFramesForDelay = 0;
2149
2150 encTools->GetDelayInFrames(encTools->Context, &requiredConfig, &ctrl,&numFramesForDelay);
2151
2152 if (bCreated)
2153 MFXVideoENCODE_DestroyEncTools(encTools);
2154
2155 return numFramesForDelay;
2156 }
2157
Query(MfxVideoParam & video)2158 static mfxStatus Query(MfxVideoParam &video)
2159 {
2160 mfxStatus sts = MFX_ERR_NONE;
2161
2162 mfxExtEncToolsConfig supportedConfig = {};
2163 mfxEncToolsCtrl ctrl = {};
2164
2165 mfxEncTools *encTools = 0;
2166 bool bCreated = false;
2167
2168 MFX_CHECK_STS(CreateEncTools(video, encTools, bCreated));
2169 MFX_CHECK_STS(InitCtrl(video, &ctrl));
2170
2171 encTools->GetSupportedConfig(encTools->Context, &supportedConfig,&ctrl);
2172
2173 if (CorrectVideoParams(video, supportedConfig))
2174 sts = MFX_WRN_INCOMPATIBLE_VIDEO_PARAM;
2175
2176 if (bCreated)
2177 MFXVideoENCODE_DestroyEncTools(encTools);
2178
2179 return sts;
2180 }
2181
Init(MfxVideoParam & video)2182 mfxStatus Init(MfxVideoParam &video)
2183 {
2184 mfxExtEncToolsConfig requiredConf = {};
2185 mfxExtEncToolsConfig supportedConf = {};
2186
2187 memset(&m_EncToolCtrl, 0, sizeof(mfxEncToolsCtrl));
2188 m_EncToolCtrl.ExtParam = m_ExtParam;
2189 m_EncToolCtrl.NumExtParam = 2;
2190
2191 mfxStatus sts = InitCtrl(video, &m_EncToolCtrl);
2192 MFX_CHECK_STS(sts);
2193
2194 sts = CreateEncTools(video, m_pEncTools, m_bEncToolsCreated);
2195 MFX_CHECK_STS(sts);
2196
2197 m_pEncTools->GetSupportedConfig(m_pEncTools->Context, &supportedConf, &m_EncToolCtrl);
2198
2199 if (CorrectVideoParams(video, supportedConf))
2200 return MFX_ERR_INCOMPATIBLE_VIDEO_PARAM;
2201
2202 GetRequiredFunc(video, requiredConf);
2203
2204 sts = m_pEncTools->Init(m_pEncTools->Context, &requiredConf, &m_EncToolCtrl);
2205 MFX_CHECK_STS(sts);
2206
2207 sts = m_pEncTools->GetActiveConfig(m_pEncTools->Context, &m_EncToolConfig);
2208 MFX_CHECK_STS(sts);
2209
2210 mfxExtEncToolsConfig *pConfig = (mfxExtEncToolsConfig *)GetExtBuffer(video.ExtParam, video.NumExtParam, MFX_EXTBUFF_ENCTOOLS_CONFIG);
2211 if (pConfig)
2212 {
2213 mfxExtBuffer header = pConfig->Header;
2214 *pConfig = m_EncToolConfig;
2215 pConfig->Header = header;
2216 }
2217
2218
2219 return MFX_ERR_NONE;
2220 }
2221
Close()2222 void Close()
2223 {
2224 if (m_pEncTools)
2225 {
2226 m_pEncTools->Close(m_pEncTools->Context);
2227 }
2228 if (m_bEncToolsCreated)
2229 MFXVideoENCODE_DestroyEncTools(m_pEncTools);
2230
2231 m_bEncToolsCreated = false;
2232 }
Reset(MfxVideoParam & video)2233 mfxStatus Reset(MfxVideoParam &video)
2234 {
2235 MFX_CHECK(m_pEncTools != 0, MFX_ERR_NOT_INITIALIZED);
2236
2237 mfxEncToolsCtrl newCtrl = {};
2238 MFX_CHECK_STS(InitCtrl(video, &newCtrl));
2239
2240 MFX_CHECK_STS(m_pEncTools->Reset(m_pEncTools->Context, &m_EncToolConfig, &newCtrl));
2241 m_EncToolCtrl = newCtrl;
2242
2243 return MFX_ERR_NONE;
2244 }
2245
SubmitForPreEnc(mfxU32 displayOrder,mfxFrameSurface1 * pSurface)2246 mfxStatus SubmitForPreEnc(mfxU32 displayOrder, mfxFrameSurface1 *pSurface)
2247 {
2248 MFX_CHECK(m_pEncTools != 0, MFX_ERR_NOT_INITIALIZED);
2249 MFX_CHECK(IsOn(m_EncToolConfig.AdaptiveI) ||
2250 IsOn(m_EncToolConfig.AdaptiveB) ||
2251 IsOn(m_EncToolConfig.AdaptivePyramidQuantP) ||
2252 IsOn(m_EncToolConfig.AdaptivePyramidQuantB) ||
2253 IsOn(m_EncToolConfig.AdaptiveLTR) ||
2254 IsOn(m_EncToolConfig.AdaptiveRefB) ||
2255 IsOn(m_EncToolConfig.AdaptiveRefP) ||
2256 IsOn(m_EncToolConfig.SceneChange) ||
2257 IsOn(m_EncToolConfig.AdaptivePyramidQuantP) ||
2258 IsOn(m_EncToolConfig.BRCBufferHints) ||
2259 IsOn(m_EncToolConfig.AdaptiveQuantMatrices)
2260 , MFX_ERR_NOT_INITIALIZED);
2261
2262 mfxEncToolsTaskParam par = {};
2263 par.DisplayOrder = displayOrder;
2264 std::vector<mfxExtBuffer*> extParams;
2265
2266 mfxEncToolsFrameToAnalyze extFrameData = {};
2267 if (pSurface)
2268 {
2269 extFrameData.Header.BufferId = MFX_EXTBUFF_ENCTOOLS_FRAME_TO_ANALYZE;
2270 extFrameData.Header.BufferSz = sizeof(extFrameData);
2271 extFrameData.Surface = pSurface;
2272 extParams.push_back((mfxExtBuffer *)&extFrameData);
2273 }
2274
2275 par.ExtParam = &extParams[0];
2276 par.NumExtParam = (mfxU16)extParams.size();
2277
2278 return m_pEncTools->Submit(m_pEncTools->Context, &par);
2279 }
2280
QueryPreEncRes(mfxU32 displayOrder,mfxEncToolsHintPreEncodeGOP & preEncodeGOP)2281 mfxStatus QueryPreEncRes(mfxU32 displayOrder, mfxEncToolsHintPreEncodeGOP &preEncodeGOP)
2282 {
2283 MFX_CHECK(m_pEncTools != 0, MFX_ERR_NOT_INITIALIZED);
2284 MFX_CHECK(IsOn(m_EncToolConfig.AdaptiveI) ||
2285 IsOn(m_EncToolConfig.AdaptiveB) ||
2286 IsOn(m_EncToolConfig.AdaptivePyramidQuantP) ||
2287 IsOn(m_EncToolConfig.AdaptivePyramidQuantB)
2288 , MFX_ERR_NOT_INITIALIZED);
2289
2290 mfxEncToolsTaskParam par = {};
2291 par.DisplayOrder = displayOrder;
2292 std::vector<mfxExtBuffer*> extParams;
2293 memset(&preEncodeGOP, 0, sizeof(preEncodeGOP));
2294 preEncodeGOP.Header.BufferId = MFX_EXTBUFF_ENCTOOLS_HINT_GOP;
2295 preEncodeGOP.Header.BufferSz = sizeof(preEncodeGOP);
2296
2297 extParams.push_back((mfxExtBuffer *)&preEncodeGOP);
2298
2299 par.ExtParam = &extParams[0];
2300 par.NumExtParam = (mfxU16)extParams.size();
2301
2302
2303 mfxStatus sts = MFX_ERR_NONE;
2304 sts = m_pEncTools->Query(m_pEncTools->Context, &par, 5000);
2305 return sts;
2306 }
2307
QueryPreEncARef(mfxU32 displayOrder,mfxEncToolsHintPreEncodeARefFrames & preEncodeARef)2308 mfxStatus QueryPreEncARef(mfxU32 displayOrder, mfxEncToolsHintPreEncodeARefFrames &preEncodeARef)
2309 {
2310 MFX_CHECK(m_pEncTools != 0, MFX_ERR_NOT_INITIALIZED);
2311 MFX_CHECK(IsOn(m_EncToolConfig.AdaptiveLTR)||
2312 IsOn(m_EncToolConfig.AdaptiveRefB)||
2313 IsOn(m_EncToolConfig.AdaptiveRefP), MFX_ERR_NOT_INITIALIZED);
2314
2315 mfxEncToolsTaskParam par = {};
2316 par.DisplayOrder = displayOrder;
2317 std::vector<mfxExtBuffer*> extParams;
2318 preEncodeARef = {};
2319 preEncodeARef.Header.BufferId = MFX_EXTBUFF_ENCTOOLS_HINT_AREF;
2320 preEncodeARef.Header.BufferSz = sizeof(preEncodeARef);
2321
2322 extParams.push_back((mfxExtBuffer *)&preEncodeARef);
2323
2324 par.ExtParam = extParams.data();
2325 par.NumExtParam = (mfxU16)extParams.size();
2326
2327 mfxStatus sts = MFX_ERR_NONE;
2328 sts = m_pEncTools->Query(m_pEncTools->Context, &par, 5000);
2329 return sts;
2330 }
2331
SubmitFrameForEncoding(DdiTask & task)2332 mfxStatus SubmitFrameForEncoding(DdiTask &task)
2333 {
2334 MFX_CHECK(m_pEncTools != 0, MFX_ERR_NOT_INITIALIZED);
2335 mfxEncToolsTaskParam par = {};
2336 BRCFrameParams *frame_par = &task.m_brcFrameParams;
2337 par.DisplayOrder = frame_par->DisplayOrder;
2338 std::vector<mfxExtBuffer*> extParams;
2339 mfxEncToolsBRCFrameParams extFrameStruct = {};
2340 extFrameStruct.Header.BufferId = MFX_EXTBUFF_ENCTOOLS_BRC_FRAME_PARAM ;
2341 extFrameStruct.Header.BufferSz = sizeof(extFrameStruct);
2342 extFrameStruct.EncodeOrder = frame_par->EncodedOrder;
2343 extFrameStruct.FrameType = frame_par->FrameType;
2344 extFrameStruct.PyramidLayer = frame_par->PyramidLayer;
2345 extParams.push_back((mfxExtBuffer *)&extFrameStruct);
2346
2347 if (frame_par->OptimalFrameSizeInBytes | frame_par->optimalBufferFullness)
2348 {
2349 mfxEncToolsBRCBufferHint extBRCHints = {};
2350 extBRCHints.Header.BufferId = MFX_EXTBUFF_ENCTOOLS_BRC_BUFFER_HINT;
2351 extBRCHints.Header.BufferSz = sizeof(extBRCHints);
2352 extBRCHints.OptimalFrameSizeInBytes = frame_par->OptimalFrameSizeInBytes;
2353 //extBRCHints.OptimalBufferFullness = frame_par->optimalBufferFullness;
2354 extParams.push_back((mfxExtBuffer *)&extBRCHints);
2355 }
2356
2357 if ((task.m_bQPDelta && task.m_QPdelta) || (task.m_QPmodulation != MFX_QP_MODULATION_NOT_DEFINED))
2358 {
2359 mfxEncToolsHintPreEncodeGOP gopHints = {};
2360 gopHints.Header.BufferId = MFX_EXTBUFF_ENCTOOLS_HINT_GOP;
2361 gopHints.Header.BufferSz = sizeof(gopHints);
2362 if (task.m_bQPDelta && task.m_QPdelta)
2363 gopHints.QPDelta = task.m_QPdelta;
2364 if (task.m_QPmodulation != MFX_QP_MODULATION_NOT_DEFINED)
2365 gopHints.QPModulation = task.m_QPmodulation;
2366 extParams.push_back((mfxExtBuffer *)&gopHints);
2367 }
2368
2369 par.ExtParam = &extParams[0];
2370 par.NumExtParam = (mfxU16)extParams.size();
2371
2372 mfxStatus sts = MFX_ERR_NONE;
2373 sts = m_pEncTools->Submit(m_pEncTools->Context, &par);
2374 return sts;
2375 }
2376
GetFrameCtrl(mfxBRCFrameCtrl * frame_ctrl,mfxU32 dispOrder)2377 mfxStatus GetFrameCtrl(mfxBRCFrameCtrl *frame_ctrl, mfxU32 dispOrder)
2378 {
2379 MFX_CHECK(m_pEncTools != 0, MFX_ERR_NOT_INITIALIZED);
2380 mfxEncToolsTaskParam par = {};
2381 par.DisplayOrder = dispOrder;
2382 std::vector<mfxExtBuffer*> extParams;
2383
2384 mfxEncToolsBRCQuantControl extFrameQP = {} ;
2385 extFrameQP.Header.BufferId = MFX_EXTBUFF_ENCTOOLS_BRC_QUANT_CONTROL;
2386 extFrameQP.Header.BufferSz = sizeof(extFrameQP);
2387
2388 extParams.push_back((mfxExtBuffer *)&extFrameQP);
2389
2390 mfxEncToolsBRCHRDPos extHRDPos = {};
2391 extHRDPos.Header.BufferId = MFX_EXTBUFF_ENCTOOLS_BRC_HRD_POS;
2392 extHRDPos.Header.BufferSz = sizeof(extHRDPos);
2393 extParams.push_back((mfxExtBuffer *)&extHRDPos);
2394
2395 par.ExtParam = &extParams[0];
2396 par.NumExtParam = (mfxU16)extParams.size();
2397
2398 mfxStatus sts;
2399 sts = m_pEncTools->Query(m_pEncTools->Context, &par, 5000);
2400 MFX_CHECK_STS(sts);
2401
2402 frame_ctrl->QpY = extFrameQP.QpY;
2403 frame_ctrl->MaxFrameSize = extFrameQP.MaxFrameSize;
2404 std::copy(extFrameQP.DeltaQP, extFrameQP.DeltaQP + 8, frame_ctrl->DeltaQP);
2405 frame_ctrl->MaxNumRepak = extFrameQP.NumDeltaQP;
2406
2407 frame_ctrl->InitialCpbRemovalDelay = extHRDPos.InitialCpbRemovalDelay;
2408 frame_ctrl->InitialCpbRemovalOffset = extHRDPos.InitialCpbRemovalDelayOffset;
2409
2410 return sts;
2411 }
2412
SubmitEncodeResult(mfxBRCFrameParam * frame_par,mfxU32 qpY)2413 mfxStatus SubmitEncodeResult(mfxBRCFrameParam *frame_par, mfxU32 qpY)
2414 {
2415 MFX_CHECK(m_pEncTools != 0, MFX_ERR_NOT_INITIALIZED);
2416 mfxEncToolsTaskParam par;
2417 par.DisplayOrder = frame_par->DisplayOrder;
2418
2419 std::vector<mfxExtBuffer*> extParams;
2420 mfxEncToolsBRCEncodeResult extEncRes;
2421 extEncRes.Header.BufferId = MFX_EXTBUFF_ENCTOOLS_BRC_ENCODE_RESULT;
2422 extEncRes.Header.BufferSz = sizeof(extEncRes);
2423 extEncRes.CodedFrameSize = frame_par->CodedFrameSize;
2424 extEncRes.QpY = (mfxU16)qpY;
2425 extEncRes.NumRecodesDone = frame_par->NumRecode;
2426
2427 extParams.push_back((mfxExtBuffer *)&extEncRes);
2428
2429 par.ExtParam = &extParams[0];
2430 par.NumExtParam = (mfxU16)extParams.size();
2431
2432 mfxStatus sts;
2433 sts = m_pEncTools->Submit(m_pEncTools->Context, &par);
2434 MFX_CHECK_STS(sts);
2435 return sts;
2436 }
2437
GetEncodeStatus(mfxBRCFrameStatus * frame_status,mfxU32 dispOrder)2438 mfxStatus GetEncodeStatus(mfxBRCFrameStatus *frame_status, mfxU32 dispOrder)
2439 {
2440 MFX_CHECK(m_pEncTools != 0, MFX_ERR_NOT_INITIALIZED);
2441
2442 mfxEncToolsTaskParam par;
2443 par.DisplayOrder = dispOrder;
2444
2445 std::vector<mfxExtBuffer*> extParams;
2446 mfxEncToolsBRCStatus extSts;
2447 extSts.Header.BufferId = MFX_EXTBUFF_ENCTOOLS_BRC_STATUS;
2448 extSts.Header.BufferSz = sizeof(extSts);
2449 extParams.push_back((mfxExtBuffer *)&extSts);
2450 par.ExtParam = &extParams[0];
2451 par.NumExtParam = (mfxU16)extParams.size();
2452
2453 mfxStatus sts;
2454 sts = m_pEncTools->Query(m_pEncTools->Context, &par, 5000);
2455
2456 *frame_status = extSts.FrameStatus;
2457 return sts;
2458 }
2459
2460 protected:
CheckSCConditions(MfxVideoParam & video)2461 static bool CheckSCConditions(MfxVideoParam &video)
2462 {
2463 return ((video.mfx.GopRefDist == 0 ||
2464 video.mfx.GopRefDist == 1 ||
2465 video.mfx.GopRefDist == 2 ||
2466 video.mfx.GopRefDist == 4 ||
2467 video.mfx.GopRefDist == 8) &&
2468 (video.mfx.FrameInfo.PicStruct == 0 ||
2469 video.mfx.FrameInfo.PicStruct == MFX_PICSTRUCT_PROGRESSIVE) &&
2470 video.calcParam.numTemporalLayer == 0);
2471
2472 }
2473
GetRequiredFunc(MfxVideoParam & video,mfxExtEncToolsConfig & config)2474 static void GetRequiredFunc(MfxVideoParam &video, mfxExtEncToolsConfig &config)
2475 {
2476 /*mfxExtCodingOption2 &extOpt2 = GetExtBufferRef(video);*/
2477 mfxExtCodingOption3 &extOpt3 = GetExtBufferRef(video);
2478 mfxExtEncToolsConfig *pConfig = (mfxExtEncToolsConfig *)GetExtBuffer(video.ExtParam, video.NumExtParam, MFX_EXTBUFF_ENCTOOLS_CONFIG);
2479 if (pConfig)
2480 config = *pConfig;
2481
2482 /* currently, adaptive pyramid quantization and EncTools' own BRC are enabled, other features are disabled */
2483
2484 if (extOpt3.ScenarioInfo != MFX_SCENARIO_GAME_STREAMING)
2485 {
2486 if (CheckSCConditions(video))
2487 {
2488 /*
2489 bool bGopStrict = (video.mfx.GopOptFlag & MFX_GOP_STRICT);
2490 config.AdaptiveI = IsNotDefined(config.AdaptiveI) ?
2491 (IsNotDefined(extOpt2.AdaptiveI) ? (mfxU16)(bGopStrict ? MFX_CODINGOPTION_OFF: MFX_CODINGOPTION_ON) : extOpt2.AdaptiveI) : config.AdaptiveI;
2492 config.AdaptiveB = IsNotDefined(config.AdaptiveB) ?
2493 (IsNotDefined(extOpt2.AdaptiveB) ? config.AdaptiveI : extOpt2.AdaptiveB) :
2494 config.AdaptiveB;
2495
2496 config.AdaptivePyramidQuantP = IsNotDefined(config.AdaptivePyramidQuantP) ?
2497 config.AdaptiveI : config.AdaptivePyramidQuantP;
2498 config.AdaptivePyramidQuantB = IsNotDefined(config.AdaptivePyramidQuantB) ?
2499 config.AdaptiveI : config.AdaptivePyramidQuantB;
2500
2501 mfxU16 bAdaptRef = config.AdaptiveI;
2502 mfxExtCodingOptionDDI const * extDdi = GetExtBuffer(video);
2503 if (extDdi->NumActiveRefP == 1)
2504 bAdaptRef = (mfxU16)MFX_CODINGOPTION_OFF;
2505
2506 config.AdaptiveRefB = IsNotDefined(config.AdaptiveRefB) ?
2507 bAdaptRef : config.AdaptiveRefB;
2508
2509 config.AdaptiveRefP = IsNotDefined(config.AdaptiveRefP) ?
2510 bAdaptRef : config.AdaptiveRefP;
2511
2512 config.AdaptiveLTR = IsNotDefined(config.AdaptiveLTR) ?
2513 bAdaptRef : config.AdaptiveLTR;
2514 */
2515
2516 config.AdaptivePyramidQuantP = config.AdaptivePyramidQuantB = MFX_CODINGOPTION_ON;
2517
2518 }
2519 /*
2520 config.BRC = IsNotDefined(config.BRC) ?
2521 ((video.mfx.RateControlMethod == MFX_RATECONTROL_CBR ||
2522 video.mfx.RateControlMethod == MFX_RATECONTROL_VBR) ?
2523 (mfxU16)MFX_CODINGOPTION_ON : (mfxU16)MFX_CODINGOPTION_OFF) : config.BRC;
2524 */
2525
2526 config.BRC = (video.mfx.RateControlMethod == MFX_RATECONTROL_CBR || video.mfx.RateControlMethod == MFX_RATECONTROL_VBR) ?
2527 (mfxU16)MFX_CODINGOPTION_ON : (mfxU16)MFX_CODINGOPTION_OFF;
2528 }
2529
2530 }
CheckFlag(mfxU16 & tested,mfxU16 ref,mfxU32 & errCount)2531 static void CheckFlag(mfxU16 &tested, mfxU16 ref, mfxU32 &errCount)
2532 {
2533 if (IsOn(tested) && IsOff(ref))
2534 {
2535 tested = MFX_CODINGOPTION_OFF;
2536 errCount++;
2537 }
2538 }
CheckFlag(mfxU16 & tested,bool bAllowed,mfxU32 & errCount)2539 static void CheckFlag(mfxU16 &tested, bool bAllowed, mfxU32 &errCount)
2540 {
2541 if (IsOn(tested) && (!bAllowed))
2542 {
2543 tested = MFX_CODINGOPTION_OFF;
2544 errCount++;
2545 }
2546 }
2547
CorrectVideoParams(MfxVideoParam & video,mfxExtEncToolsConfig & supportedConfig)2548 static mfxU32 CorrectVideoParams(MfxVideoParam &video, mfxExtEncToolsConfig& supportedConfig)
2549 {
2550 mfxExtCodingOption2 &extOpt2 = GetExtBufferRef(video);
2551 mfxExtCodingOptionDDI * extDdi = GetExtBuffer(video);
2552
2553 mfxExtBRC* extBRC = GetExtBuffer(video);
2554 mfxU32 numChanges = 0;
2555 mfxExtEncToolsConfig *pConfig = (mfxExtEncToolsConfig *)GetExtBuffer(video.ExtParam, video.NumExtParam, MFX_EXTBUFF_ENCTOOLS_CONFIG);
2556
2557 if (pConfig)
2558 {
2559 bool bEncToolsCnd = ((video.mfx.FrameInfo.PicStruct == 0 ||
2560 video.mfx.FrameInfo.PicStruct == MFX_PICSTRUCT_PROGRESSIVE) &&
2561 video.calcParam.numTemporalLayer == 0);
2562 bool bGopStrict = ((video.mfx.GopOptFlag & MFX_GOP_STRICT) != 0);
2563 bool bMultiRef = (extDdi->NumActiveRefP != 1);
2564
2565 CheckFlag(pConfig->AdaptiveI, bEncToolsCnd && (!bGopStrict), numChanges);
2566
2567 bool bAddLim = !IsOff(pConfig->AdaptiveI); // additional limititation in current implementation
2568 CheckFlag(pConfig->AdaptiveB, bEncToolsCnd && (!bGopStrict) && bAddLim, numChanges);
2569 CheckFlag(pConfig->AdaptivePyramidQuantB, bEncToolsCnd, numChanges);
2570 CheckFlag(pConfig->AdaptivePyramidQuantP, bEncToolsCnd, numChanges);
2571
2572 CheckFlag(pConfig->AdaptiveRefP, bEncToolsCnd && bMultiRef && bAddLim, numChanges);
2573 CheckFlag(pConfig->AdaptiveRefB, bEncToolsCnd && bMultiRef && bAddLim, numChanges);
2574 CheckFlag(pConfig->AdaptiveLTR, bEncToolsCnd && bMultiRef && bAddLim, numChanges);
2575 CheckFlag(pConfig->SceneChange, bEncToolsCnd, numChanges);
2576 CheckFlag(pConfig->BRCBufferHints, bEncToolsCnd, numChanges);
2577 CheckFlag(pConfig->AdaptiveQuantMatrices, bEncToolsCnd, numChanges);
2578 CheckFlag(pConfig->BRC, bEncToolsCnd, numChanges);
2579
2580 CheckFlag(pConfig->AdaptiveI, supportedConfig.AdaptiveI, numChanges);
2581 CheckFlag(pConfig->AdaptiveB, supportedConfig.AdaptiveB, numChanges);
2582 CheckFlag(pConfig->AdaptivePyramidQuantB, supportedConfig.AdaptivePyramidQuantB, numChanges);
2583 CheckFlag(pConfig->AdaptivePyramidQuantP, supportedConfig.AdaptivePyramidQuantP, numChanges);
2584 CheckFlag(pConfig->AdaptiveRefP, supportedConfig.AdaptiveRefP, numChanges);
2585 CheckFlag(pConfig->AdaptiveRefB, supportedConfig.AdaptiveRefB, numChanges);
2586 CheckFlag(pConfig->AdaptiveLTR, supportedConfig.AdaptiveLTR, numChanges);
2587 CheckFlag(pConfig->SceneChange, supportedConfig.SceneChange, numChanges);
2588 CheckFlag(pConfig->BRCBufferHints, supportedConfig.BRCBufferHints, numChanges);
2589 CheckFlag(pConfig->AdaptiveQuantMatrices, supportedConfig.AdaptiveQuantMatrices, numChanges);
2590 CheckFlag(pConfig->BRC, supportedConfig.BRC, numChanges);
2591 }
2592 CheckFlag(extOpt2.AdaptiveI, supportedConfig.AdaptiveI, numChanges);
2593 CheckFlag(extOpt2.AdaptiveB, supportedConfig.AdaptiveB, numChanges);
2594 //ExtBRC isn't compatible with EncTools
2595
2596 if (extBRC && (extBRC->pthis || extBRC->Init || extBRC->Close || extBRC->Update || extBRC->Reset))
2597 {
2598 extBRC->pthis = 0;
2599 extBRC->Init = 0;
2600 extBRC->Close = 0;
2601 extBRC->Update = 0;
2602 extBRC->Reset = 0;
2603 numChanges++;
2604 }
2605 if (IsOn(extOpt2.ExtBRC))
2606 {
2607 extOpt2.ExtBRC = MFX_CODINGOPTION_UNKNOWN;
2608 numChanges++;
2609 }
2610
2611 return numChanges;
2612 }
CreateEncTools(MfxVideoParam & video,mfxEncTools * & encTools,bool & bCreated)2613 static mfxStatus CreateEncTools(MfxVideoParam &video, mfxEncTools * &encTools, bool &bCreated)
2614 {
2615 encTools = GetExtBuffer(video);
2616 bCreated = false;
2617 if (!encTools->Context)
2618 {
2619 encTools = MFXVideoENCODE_CreateEncTools();
2620 MFX_CHECK(encTools != 0, MFX_ERR_INVALID_VIDEO_PARAM);
2621 bCreated = true;
2622 }
2623 return MFX_ERR_NONE;
2624 }
2625
2626 private:
2627
2628 mfxEncTools* m_pEncTools = nullptr;
2629 bool m_bEncToolsCreated = false;
2630 mfxEncToolsCtrl m_EncToolCtrl = {};
2631 mfxExtEncToolsConfig m_EncToolConfig = {};
2632 mfxExtBuffer* m_ExtParam[2] = {};
2633
2634 };
2635 #endif
2636
2637
2638
2639 class DdiTask2ndField
2640 {
2641 public:
2642 DdiTask * m_1stFieldTask;
2643 DdiTask m_2ndFieldTask;
2644 };
2645
2646 // should be called from one thread
2647 // yields tasks in cyclic manner
2648 class CyclicTaskPool
2649 {
2650 public:
2651 void Init(mfxU32 size);
2652
2653 DdiTask2ndField * GetFreeTask();
2654
2655 private:
2656 std::vector<DdiTask2ndField> m_pool;
2657 std::vector<DdiTask2ndField>::iterator m_next;
2658 };
2659
2660 struct MbData
2661 {
2662 mfxU32 intraCost;
2663 mfxU32 interCost;
2664 mfxU32 propCost;
2665 mfxU8 w0;
2666 mfxU8 w1;
2667 mfxU16 dist;
2668 mfxU16 rate;
2669 mfxU16 lumaCoeffSum[4];
2670 mfxU8 lumaCoeffCnt[4];
2671 mfxI16Pair costCenter0;
2672 mfxI16Pair costCenter1;
2673 struct
2674 {
2675 mfxU32 intraMbFlag : 1;
2676 mfxU32 skipMbFlag : 1;
2677 mfxU32 mbType : 5;
2678 mfxU32 reserved0 : 1;
2679 mfxU32 subMbShape : 8;
2680 mfxU32 subMbPredMode : 8;
2681 mfxU32 reserved1 : 8;
2682 };
2683 mfxI16Pair mv[2]; // in sig-sag scan
2684 };
2685
2686 class CmContext;
2687
2688 struct VmeData
2689 {
VmeDataVmeData2690 VmeData()
2691 : used(false)
2692 , poc(mfxU32(-1))
2693 , pocL0(mfxU32(-1))
2694 , pocL1(mfxU32(-1))
2695 , encOrder(0)
2696 , intraCost(0)
2697 , interCost(0)
2698 , propCost(0) { }
2699
2700 bool used;
2701 mfxU32 poc;
2702 mfxU32 pocL0;
2703 mfxU32 pocL1;
2704 mfxU32 encOrder;
2705 mfxU32 intraCost;
2706 mfxU32 interCost;
2707 mfxU32 propCost;
2708 std::vector<MbData> mb;
2709 };
2710
2711
2712 class AsyncRoutineEmulator
2713 {
2714 public:
2715 enum {
2716 STG_ACCEPT_FRAME,
2717 STG_START_SCD,
2718 STG_WAIT_SCD,
2719 STG_START_MCTF,
2720 STG_WAIT_MCTF,
2721 STG_START_LA,
2722 STG_WAIT_LA,
2723 STG_START_HIST,
2724 STG_WAIT_HIST,
2725 STG_START_ENCODE,
2726 STG_WAIT_ENCODE,
2727 STG_COUNT
2728 };
2729
2730 enum {
2731 STG_BIT_CALL_EMULATOR = 0,
2732 STG_BIT_ACCEPT_FRAME = 1 << STG_ACCEPT_FRAME,
2733 STG_BIT_START_SCD = 1 << STG_START_SCD,
2734 STG_BIT_WAIT_SCD = 1 << STG_WAIT_SCD,
2735 STG_BIT_START_MCTF = 1 << STG_START_MCTF,
2736 STG_BIT_WAIT_MCTF = 1 << STG_WAIT_MCTF,
2737 STG_BIT_START_LA = 1 << STG_START_LA,
2738 STG_BIT_WAIT_LA = 1 << STG_WAIT_LA,
2739 STG_BIT_START_HIST = 1 << STG_START_HIST,
2740 STG_BIT_WAIT_HIST = 1 << STG_WAIT_HIST,
2741 STG_BIT_START_ENCODE = 1 << STG_START_ENCODE,
2742 STG_BIT_WAIT_ENCODE = 1 << STG_WAIT_ENCODE,
2743 STG_BIT_RESTART = 1 << STG_COUNT
2744 };
2745
2746 AsyncRoutineEmulator();
2747
2748 AsyncRoutineEmulator(MfxVideoParam const & video, mfxU32 adaptGopDelay);
2749
2750 void Init(MfxVideoParam const & video, mfxU32 adaptGopDelay);
2751
2752 mfxU32 GetTotalGreediness() const;
2753
2754 mfxU32 GetStageGreediness(mfxU32 i) const;
2755
2756 mfxU32 Go(bool hasInput);
2757
2758 protected:
2759 mfxU32 CheckStageOutput(mfxU32 stage);
2760
2761 private:
2762 mfxU32 m_stageGreediness[STG_COUNT];
2763 mfxU32 m_queueFullness[STG_COUNT + 1];
2764 mfxU32 m_queueFlush[STG_COUNT + 1];
2765 };
2766
2767 struct LAOutObject;
2768
2769 using ns_asc::ASC;
2770
2771 class ImplementationAvc : public VideoENCODE
2772 {
2773 public:
2774 struct FrameTypeAdapt
2775 {
FrameTypeAdaptFrameTypeAdapt2776 FrameTypeAdapt(CmDevice* cmDevice, int width, int height)
2777 : m_frameNum(0)
2778 , m_isAdapted(0)
2779 , m_surface(0)
2780 , m_cmDevice(cmDevice)
2781
2782 , intraCost(0)
2783 , interCost(0)
2784 , intraDist(0)
2785 , interDist(0)
2786 , totalDist(0)
2787 , numIntraMb(0)
2788 {
2789 int numMB = width*height/256;
2790 mb.resize(numMB);
2791
2792 m_surface4X.Reset(m_cmDevice, width/4, height/4, CM_SURFACE_FORMAT_NV12);
2793 }
2794
2795 mfxU32 m_frameNum;
2796 mfxU32 m_isAdapted;
2797 mfxU16 m_frameType;
2798 mfxEncodeCtrl* m_ctrl;
2799 mfxFrameSurface1* m_surface;
2800 CmSurface m_surface4X;
2801 CmDevice* m_cmDevice;
2802
2803 mfxU32 intraCost;
2804 mfxU32 interCost;
2805 mfxU32 intraDist;
2806 mfxU32 interDist;
2807 mfxU32 totalDist;
2808 mfxU32 numIntraMb;
2809 std::vector<MbData> mb;
2810 //std::vector<LAOutObject> m_mb;
2811 };
2812
2813 public:
2814 static mfxStatus Query(
2815 VideoCORE * core,
2816 mfxVideoParam * in,
2817 mfxVideoParam * out,
2818 void * state = 0);
2819
2820 static mfxStatus QueryIOSurf(
2821 VideoCORE * core,
2822 mfxVideoParam * par,
2823 mfxFrameAllocRequest * request);
2824
2825 ImplementationAvc(VideoCORE * core);
2826
2827 virtual ~ImplementationAvc();
2828
2829 virtual mfxStatus Init(mfxVideoParam * par);
2830
Close()2831 virtual mfxStatus Close() { return MFX_ERR_NONE; }
2832
2833 virtual mfxStatus Reset(mfxVideoParam * par);
2834
2835 virtual mfxStatus GetVideoParam(mfxVideoParam * par);
2836
2837 virtual mfxStatus GetFrameParam(mfxFrameParam * par);
2838
2839 virtual mfxStatus GetEncodeStat(mfxEncodeStat * stat);
2840
EncodeFrameCheck(mfxEncodeCtrl *,mfxFrameSurface1 *,mfxBitstream *,mfxFrameSurface1 **,mfxEncodeInternalParams *)2841 virtual mfxStatus EncodeFrameCheck(
2842 mfxEncodeCtrl *,
2843 mfxFrameSurface1 *,
2844 mfxBitstream *,
2845 mfxFrameSurface1 **,
2846 mfxEncodeInternalParams *)
2847 {
2848 return MFX_ERR_UNSUPPORTED;
2849 }
2850
2851 virtual mfxStatus EncodeFrameCheck(
2852 mfxEncodeCtrl * ctrl,
2853 mfxFrameSurface1 * surface,
2854 mfxBitstream * bs,
2855 mfxFrameSurface1 ** reordered_surface,
2856 mfxEncodeInternalParams * internalParams,
2857 MFX_ENTRY_POINT * entryPoints,
2858 mfxU32 & numEntryPoints);
2859
2860 virtual mfxStatus EncodeFrameCheckNormalWay(
2861 mfxEncodeCtrl * ctrl,
2862 mfxFrameSurface1 * surface,
2863 mfxBitstream * bs,
2864 mfxFrameSurface1 ** reordered_surface,
2865 mfxEncodeInternalParams * internalParams,
2866 MFX_ENTRY_POINT * entryPoints,
2867 mfxU32 & numEntryPoints);
2868
EncodeFrame(mfxEncodeCtrl *,mfxEncodeInternalParams *,mfxFrameSurface1 *,mfxBitstream *)2869 virtual mfxStatus EncodeFrame(
2870 mfxEncodeCtrl *,
2871 mfxEncodeInternalParams *,
2872 mfxFrameSurface1 *,
2873 mfxBitstream *)
2874 {
2875 return MFX_ERR_UNSUPPORTED;
2876 }
2877
CancelFrame(mfxEncodeCtrl *,mfxEncodeInternalParams *,mfxFrameSurface1 *,mfxBitstream *)2878 virtual mfxStatus CancelFrame(
2879 mfxEncodeCtrl *,
2880 mfxEncodeInternalParams *,
2881 mfxFrameSurface1 *,
2882 mfxBitstream *)
2883 {
2884 return MFX_ERR_UNSUPPORTED;
2885 }
2886
2887 protected:
2888 #if defined(MFX_ENABLE_MCTF_IN_AVC)
2889 std::shared_ptr<CMC>
2890 amtMctf;
2891
2892 mfxStatus SubmitToMctf(
2893 DdiTask * pTask
2894 );
2895 mfxStatus QueryFromMctf(
2896 void *pParam
2897 );
2898 #endif
2899 ASC amtScd;
2900 mfxStatus SCD_Put_Frame(
2901 DdiTask & newTask);
2902 mfxStatus SCD_Get_FrameType(
2903 DdiTask & newTask);
2904 mfxStatus CalculateFrameCmplx(
2905 DdiTask const &task,
2906 mfxU32 &raca128);
2907 mfxStatus Prd_LTR_Operation(
2908 DdiTask & task);
2909 void AssignFrameTypes(
2910 DdiTask & newTask);
2911 mfxStatus BuildPPyr(
2912 DdiTask & task,
2913 mfxU32 pyrWidth,
2914 bool bLastFrameUsing,
2915 bool bResetPyr);
2916 void setFrameInfo(DdiTask & task,
2917 mfxU32 fid);
2918 void AssignDecodeTimeStamp(
2919 DdiTask & task);
2920 void PreserveTimeStamp(
2921 mfxU64 timeStamp);
2922 mfxStatus UpdateBitstream(
2923 DdiTask & task,
2924 mfxU32 fid); // 0 - top/progressive, 1 - bottom
2925
2926 #ifndef MFX_AVC_ENCODING_UNIT_DISABLE
2927 void FillEncodingUnitsInfo(
2928 DdiTask &task,
2929 mfxU8 *sbegin,
2930 mfxU8 *send,
2931 mfxExtEncodedUnitsInfo *encUnitsInfo,
2932 mfxU32 fid);
2933 #endif
2934
2935 mfxStatus AsyncRoutine(
2936 mfxBitstream * bs);
2937
2938 mfxStatus CheckSliceSize(DdiTask &task, bool &bToRecode);
2939 mfxStatus CheckBufferSize(DdiTask &task, bool &bToRecode, mfxU32 bsDataLength, mfxBitstream * bs);
2940 mfxStatus CheckBRCStatus(DdiTask &task, bool &bToRecode, mfxU32 bsDataLength);
2941 mfxStatus FillPreEncParams(DdiTask &task);
2942 void OnNewFrame();
2943 void SubmitScd();
2944 void OnScdQueried();
2945 void OnScdFinished();
2946
2947 void SubmitAdaptiveGOP();
2948 bool OnAdaptiveGOPSubmitted();
2949
2950 void SubmitMCTF();
2951 void OnMctfQueried();
2952 void OnMctfFinished();
2953
2954 void OnLookaheadSubmitted(DdiTaskIter task);
2955
2956 void OnLookaheadQueried();
2957
2958 void OnHistogramSubmitted();
2959
2960 void OnHistogramQueried();
2961
2962 void OnEncodingSubmitted(DdiTaskIter task);
2963
2964 void OnEncodingQueried(DdiTaskIter task);
2965
2966 void BrcPreEnc(DdiTask const & task);
2967
2968 static mfxStatus AsyncRoutineHelper(
2969 void * state,
2970 void * param,
2971 mfxU32 threadNumber,
2972 mfxU32 callNumber);
2973
2974 void RunPreMe(
2975 MfxVideoParam const & video,
2976 DdiTask const & task);
2977
2978 void SubmitLookahead(
2979 DdiTask & task);
2980
2981 mfxStatus QueryLookahead(
2982 DdiTask & task);
2983
2984 mfxStatus QueryStatus(
2985 DdiTask & task,
2986 mfxU32 ffid);
2987
2988
2989 mfxStatus MiniGopSize(
2990 mfxEncodeCtrl** ctrl,
2991 mfxFrameSurface1** surface,
2992 mfxU16* requiredFrameType);
2993
2994 mfxStatus MiniGopSize1(
2995 mfxEncodeCtrl** ctrl,
2996 mfxFrameSurface1** surface,
2997 mfxU16* requiredFrameType);
2998
2999 mfxStatus ProcessAndCheckNewParameters(
3000 MfxVideoParam & newPar,
3001 bool & isBRCReset,
3002 bool & isIdrRequired,
3003 mfxVideoParam const * newParIn = 0);
3004
3005 void DestroyDanglingCmResources();
3006
3007 VideoCORE * m_core;
3008 CmDevicePtr m_cmDevice;
3009 MfxVideoParam m_video;
3010 MfxVideoParam m_videoInit; // m_video may change by Reset, m_videoInit doesn't change
3011 mfxEncodeStat m_stat;
3012
3013 std::list<std::pair<mfxBitstream *, mfxU32> > m_listOfPairsForFieldOutputMode;
3014
3015 AsyncRoutineEmulator m_emulatorForSyncPart;
3016 AsyncRoutineEmulator m_emulatorForAsyncPart;
3017
3018 SliceDivider m_sliceDivider;
3019
3020 std::list<DdiTask> m_free;
3021 std::list<DdiTask> m_incoming;
3022 std::list<DdiTask> m_ScDetectionStarted;
3023 std::list<DdiTask> m_ScDetectionFinished;
3024 std::list<DdiTask> m_MctfStarted;
3025 std::list<DdiTask> m_MctfFinished;
3026 std::list<DdiTask> m_reordering;
3027 std::list<DdiTask> m_lookaheadStarted;
3028 std::list<DdiTask> m_lookaheadFinished;
3029 std::list<DdiTask> m_histRun;
3030 std::list<DdiTask> m_histWait;
3031 std::list<DdiTask> m_encoding;
3032 std::list<mfxU64> m_timeStamps;
3033 UMC::Mutex m_listMutex;
3034 DdiTask m_lastTask;
3035 mfxU32 m_stagesToGo;
3036 mfxU32 m_bDeferredFrame;
3037
3038 mfxU32 m_fieldCounter;
3039 mfxStatus m_1stFieldStatus;
3040 mfxU32 m_frameOrder;
3041 mfxU32 m_baseLayerOrder;
3042 mfxU32 m_frameOrderIdrInDisplayOrder; // frame order of last IDR frame (in display order)
3043 mfxU32 m_frameOrderIntraInDisplayOrder; // frame order of last I frame (in display order)
3044 mfxU32 m_frameOrderIPInDisplayOrder; // frame order of last I or P frame (in display order)
3045 mfxU32 m_frameOrderPyrStart; // frame order of the first frame of pyramid
3046 mfxU32 m_miniGopCount;
3047 mfxU32 m_frameOrderStartTScalStructure; // starting point of temporal scalability structure
3048
3049 // parameters for Intra refresh
3050 mfxI64 m_baseLayerOrderStartIntraRefresh; // starting point of Intra refresh cycles (could be negative)
3051 mfxU16 m_intraStripeWidthInMBs; // width of Intra MB stripe (column or row depending on refresh type)
3052
3053 mfxU32 m_enabledSwBrc;
3054 Brc m_brc;
3055 Hrd m_hrd;
3056 #if defined(MFX_ENABLE_ENCTOOLS)
3057 H264EncTools m_encTools;
3058 bool m_enabledEncTools;
3059 #endif
3060 mfxU32 m_maxBsSize;
3061
3062 std::unique_ptr<DriverEncoder> m_ddi;
3063
3064 std::vector<mfxU32> m_recFrameOrder;
3065
3066 mfxU32 m_recNonRef[2];
3067
3068 #if defined(MFX_ENABLE_MCTF_IN_AVC)
3069 MfxFrameAllocResponse m_mctf;
3070 #endif
3071 MfxFrameAllocResponse m_scd;
3072 MfxFrameAllocResponse m_raw;
3073 MfxFrameAllocResponse m_rawSkip;
3074 MfxFrameAllocResponse m_rawLa;
3075 MfxFrameAllocResponse m_mb;
3076 MfxFrameAllocResponse m_curbe;
3077 MfxFrameAllocResponse m_rawSys;
3078 MfxFrameAllocResponse m_rec;
3079 MfxFrameAllocResponse m_bit;
3080 MfxFrameAllocResponse m_opaqResponse; // Response for opaq
3081 MfxFrameAllocResponse m_histogram;
3082
3083 MFX_ENCODE_CAPS m_caps;
3084 mfxStatus m_failedStatus;
3085 mfxU32 m_inputFrameType;
3086 mfxU32 m_NumSlices;
3087
3088 MfxFrameAllocResponse m_mbqp;
3089 bool m_useMBQPSurf;
3090
3091 MfxFrameAllocResponse m_mbControl;
3092 bool m_useMbControlSurfs;
3093
3094 std::vector<mfxU8> m_tmpBsBuf;
3095 PreAllocatedVector m_sei;
3096
3097 eMFXHWType m_currentPlatform;
3098 eMFXVAType m_currentVaType;
3099 bool m_useWAForHighBitrates;
3100 bool m_isENCPAK;
3101 bool m_resetBRC;
3102
3103 // bitrate reset for SNB
3104
3105 std::unique_ptr<CmContext> m_cmCtx;
3106 std::vector<VmeData> m_vmeDataStorage;
3107 std::vector<VmeData *> m_tmpVmeData;
3108
3109
3110 std::list<DdiTask> m_adaptiveGOPBuffered;
3111 std::list<DdiTask> m_adaptiveGOPSubmitted;
3112 std::list<DdiTask> m_adaptiveGOPFinished;
3113 std::list<DdiTask> m_adaptiveGOPReady;
3114 mfxU32 m_LowDelayPyramidLayer;
3115 mfxI32 m_LtrQp;
3116 mfxI32 m_LtrOrder;
3117 mfxI32 m_RefQp;
3118 mfxI32 m_RefOrder;
3119
3120 };
3121
3122
3123 struct NalUnit
3124 {
NalUnitNalUnit3125 NalUnit() : begin(0), end(0), type(0), numZero(0)
3126 {}
3127
NalUnitNalUnit3128 NalUnit(mfxU8 * b, mfxU8 * e, mfxU8 t, mfxU8 z) : begin(b), end(e), type(t), numZero(z)
3129 {}
3130
3131 mfxU8 * begin;
3132 mfxU8 * end;
3133 mfxU8 type;
3134 mfxU32 numZero;
3135 };
3136
3137 NalUnit GetNalUnit(mfxU8 * begin, mfxU8 * end);
3138
3139 class NaluIterator
3140 {
3141 public:
NaluIterator()3142 NaluIterator()
3143 : m_begin(0)
3144 , m_end(0)
3145 {}
3146
NaluIterator(mfxU8 * begin,mfxU8 * end)3147 NaluIterator(mfxU8 * begin, mfxU8 * end)
3148 : m_nalu(GetNalUnit(begin, end))
3149 , m_begin(m_nalu.end)
3150 , m_end(end)
3151 {
3152 }
3153
NaluIterator(NalUnit const & nalu,mfxU8 * end)3154 NaluIterator(NalUnit const & nalu, mfxU8 * end)
3155 : m_nalu(nalu)
3156 , m_begin(nalu.end)
3157 , m_end(end)
3158 {
3159 }
3160
3161 NalUnit & operator *()
3162 {
3163 return m_nalu;
3164 }
3165
3166 NalUnit * operator ->()
3167 {
3168 return &m_nalu;
3169 }
3170
3171 NaluIterator & operator++()
3172 {
3173 m_nalu = GetNalUnit(m_begin, m_end);
3174 m_begin = m_nalu.end;
3175 return *this;
3176 }
3177
3178 NaluIterator operator++(int)
3179 {
3180 NaluIterator tmp;
3181 ++*this;
3182 return tmp;
3183 }
3184
3185 bool operator ==(NaluIterator const & right) const
3186 {
3187 return m_nalu.begin == right.m_nalu.begin && m_nalu.end == right.m_nalu.end;
3188 }
3189
3190 bool operator !=(NaluIterator const & right) const
3191 {
3192 return !(*this == right);
3193 }
3194
3195 private:
3196 NalUnit m_nalu;
3197 mfxU8 * m_begin;
3198 mfxU8 * m_end;
3199 };
3200
3201 struct BitstreamDesc
3202 {
BitstreamDescBitstreamDesc3203 BitstreamDesc() : begin(0), end(0)
3204 {}
3205
3206 mfxU8 * begin;
3207 mfxU8 * end;
3208 NalUnit aud; // byte range within [begin, end)
3209 NalUnit sps; // byte range within [begin, end)
3210 NalUnit pps; // byte range within [begin, end)
3211 NalUnit sei; // first sei if multi sei nal units present
3212 NalUnit slice; // first slice if multi-sliced
3213 };
3214
3215
3216 class InputBitstream
3217 {
3218 public:
3219 InputBitstream(
3220 mfxU8 const * buf,
3221 size_t size,
3222 bool hasStartCode = true,
3223 bool doEmulationControl = true);
3224
3225 InputBitstream(
3226 mfxU8 const * buf,
3227 mfxU8 const * bufEnd,
3228 bool hasStartCode = true,
3229 bool doEmulationControl = true);
3230
3231 mfxU32 NumBitsRead() const;
3232 mfxU32 NumBitsLeft() const;
3233
3234 mfxU32 GetBit();
3235 mfxU32 GetBits(mfxU32 nbits);
3236 mfxU32 GetUe();
3237 mfxI32 GetSe();
3238
3239 private:
3240 mfxU8 const * m_buf;
3241 mfxU8 const * m_ptr;
3242 mfxU8 const * m_bufEnd;
3243 mfxU32 m_bitOff;
3244 bool m_doEmulationControl;
3245 };
3246
3247 class OutputBitstream
3248 {
3249 public:
3250 OutputBitstream(mfxU8 * buf, size_t size, bool emulationControl = true);
3251 OutputBitstream(mfxU8 * buf, mfxU8 * bufEnd, bool emulationControl = true);
3252
3253 mfxU32 GetNumBits() const;
3254
3255 void PutBit(mfxU32 bit);
3256 void PutBits(mfxU32 val, mfxU32 nbits);
3257 void PutUe(mfxU32 val);
3258 void PutSe(mfxI32 val);
3259 void PutRawBytes(mfxU8 const * begin, mfxU8 const * end); // startcode emulation is not controlled
3260 void PutFillerBytes(mfxU8 filler, mfxU32 nbytes); // startcode emulation is not controlled
3261 void PutTrailingBits();
3262
3263 private:
3264 mfxU8 * m_buf;
3265 mfxU8 * m_ptr;
3266 mfxU8 * m_bufEnd;
3267 mfxU32 m_bitOff;
3268 bool m_emulationControl;
3269 };
3270
3271 class CabacPackerSimple : public OutputBitstream
3272 {
3273 public:
3274 CabacPackerSimple(mfxU8 * buf, mfxU8 * bufEnd, bool emulationControl = true);
3275 void EncodeBin(mfxU8 * ctx, mfxU8 bin);
3276 void TerminateEncode();
3277 private:
3278 void PutBitC(mfxU32 B);
3279 void RenormE();
3280
3281 mfxU32 m_codILow;
3282 mfxU32 m_codIRange;
3283 mfxU32 m_bitsOutstanding;
3284 mfxU32 m_BinCountsInNALunits;
3285 bool m_firstBitFlag;
3286 };
3287
3288 void PutSeiHeader(
3289 OutputBitstream & bs,
3290 mfxU32 payloadType,
3291 mfxU32 payloadSize);
3292
3293 void PutSeiMessage(
3294 OutputBitstream & bs,
3295 mfxExtAvcSeiBufferingPeriod const & msg);
3296
3297 void PutSeiMessage(
3298 OutputBitstream & bs,
3299 mfxExtPictureTimingSEI const & extPt,
3300 mfxExtAvcSeiPicTiming const & msg);
3301
3302 void PutSeiMessage(
3303 OutputBitstream & bs,
3304 mfxExtAvcSeiDecRefPicMrkRep const & msg);
3305
3306 void PutSeiMessage(
3307 OutputBitstream & bs,
3308 mfxExtAvcSeiRecPoint const & msg);
3309
3310 mfxU32 PutScalableInfoSeiMessage(
3311 OutputBitstream & obs,
3312 MfxVideoParam const & par);
3313
3314 // MVC BD {
3315 // Put MVC scalable nested SEI
3316 void PutSeiMessage(
3317 OutputBitstream & bs,
3318 mfxU32 needBufferingPeriod,
3319 mfxU32 needPicTimingSei,
3320 mfxU32 fillerSize,
3321 MfxVideoParam const & video,
3322 mfxExtAvcSeiBufferingPeriod const & msg_bp,
3323 mfxExtPictureTimingSEI const & extPt,
3324 mfxExtAvcSeiPicTiming const & msg_pt);
3325 // MVC BD }
3326
3327
3328
3329 mfxU8 const * SkipStartCode(mfxU8 const * begin, mfxU8 const * end);
3330 mfxU8 * SkipStartCode(mfxU8 * begin, mfxU8 * end);
3331
3332 ArrayRefListMod CreateRefListMod(
3333 ArrayDpbFrame const & dpb,
3334 std::vector<Reconstruct> const & recons,
3335 ArrayU8x33 initList,
3336 ArrayU8x33 const & modList,
3337 mfxU32 curViewIdx,
3338 mfxI32 curPicNum,
3339 bool optimize = true);
3340
3341 mfxU8 * CheckedMFX_INTERNAL_CPY(
3342 mfxU8 * dbegin,
3343 mfxU8 * dend,
3344 mfxU8 const * sbegin,
3345 mfxU8 const * send);
3346
3347 mfxU8 * CheckedMemset(
3348 mfxU8 * dbegin,
3349 mfxU8 * dend,
3350 mfxU8 value,
3351 mfxU32 size);
3352
3353 void ReadRefPicListModification(InputBitstream & reader);
3354
3355 void ReadDecRefPicMarking(
3356 InputBitstream & reader,
3357 bool idrPicFlag);
3358
3359 void WriteRefPicListModification(
3360 OutputBitstream & writer,
3361 ArrayRefListMod const & refListMod);
3362
3363 void WriteDecRefPicMarking(
3364 OutputBitstream & writer,
3365 DecRefPicMarkingInfo const & marking,
3366 bool idrPicFlag);
3367
3368 mfxU8 * RePackSlice(
3369 mfxU8 * dbegin,
3370 mfxU8 * dend,
3371 mfxU8 * sbegin,
3372 mfxU8 * send,
3373 MfxVideoParam const & par,
3374 DdiTask const & task,
3375 mfxU32 fieldId);
3376
3377 enum
3378 {
3379 RPLM_ST_PICNUM_SUB = 0,
3380 RPLM_ST_PICNUM_ADD = 1,
3381 RPLM_LT_PICNUM = 2,
3382 RPLM_END = 3,
3383 RPLM_INTERVIEW_SUB = 4,
3384 RPLM_INTERVIEW_ADD = 5,
3385 };
3386
3387 enum
3388 {
3389 MMCO_END = 0,
3390 MMCO_ST_TO_UNUSED = 1,
3391 MMCO_LT_TO_UNUSED = 2,
3392 MMCO_ST_TO_LT = 3,
3393 MMCO_SET_MAX_LT_IDX = 4,
3394 MMCO_ALL_TO_UNUSED = 5,
3395 MMCO_CURR_TO_LT = 6,
3396 };
3397
3398
3399 void PrepareSeiMessageBuffer(
3400 MfxVideoParam const & video,
3401 DdiTask const & task,
3402 mfxU32 fieldId, // 0 - top/progressive, 1 - bottom
3403 PreAllocatedVector & sei);
3404
3405 void PrepareSeiMessageBufferDepView(
3406 MfxVideoParam const & video,
3407 DdiTask const & task,
3408 mfxU32 fieldId, // 0 - top/progressive, 1 - bottom
3409 PreAllocatedVector & sei);
3410
3411
3412 bool IsInplacePatchNeeded(
3413 MfxVideoParam const & par,
3414 DdiTask const & task,
3415 mfxU32 fieldId);
3416
3417 bool IsSlicePatchNeeded(
3418 DdiTask const & task,
3419 mfxU32 fieldId);
3420
3421 mfxStatus CopyBitstream(
3422 VideoCORE & core,
3423 MfxVideoParam const & video,
3424 DdiTask const & task,
3425 mfxU32 fieldId,
3426 mfxU8 * bsData,
3427 mfxU32 bsSizeAvail);
3428
3429 mfxU32 GetMaxSliceSize(
3430 mfxU8 * sbegin, // contents of source buffer may be modified
3431 mfxU8 * send,
3432 mfxU32 &num);
3433
3434
3435 mfxStatus UpdateSliceInfo(
3436 mfxU8 * sbegin, // contents of source buffer may be modified
3437 mfxU8 * send,
3438 mfxU32 maxSliceSize,
3439 DdiTask& task,
3440 bool& bRecoding);
3441
3442 mfxU8 * PatchBitstream(
3443 MfxVideoParam const & video,
3444 DdiTask const & task,
3445 mfxU32 fieldId,
3446 mfxU8 * sbegin, // contents of source buffer may be modified
3447 mfxU8 * send,
3448 mfxU8 * dbegin,
3449 mfxU8 * dend);
3450 mfxU8 * InsertSVCNAL(
3451 DdiTask const & task,
3452 mfxU32 fieldId,
3453 mfxU8 * sbegin, // contents of source buffer may be modified
3454 mfxU8 * send,
3455 mfxU8 * dbegin,
3456 mfxU8 * dend);
3457
3458 mfxU8 * AddEmulationPreventionAndCopy(
3459 mfxU8 * sbegin,
3460 mfxU8 * send,
3461 mfxU8 * dbegin,
3462 mfxU8 * dend);
3463
3464 mfxStatus FillSliceInfo(
3465 DdiTask & task,
3466 mfxU32 MaxSliceSize,
3467 mfxU32 FrameSize,
3468 mfxU32 widthLa,
3469 mfxU32 heightLa);
3470
3471 mfxStatus CorrectSliceInfo(
3472 DdiTask & task,
3473 mfxU32 sliceWeight,
3474 mfxU32 widthLa,
3475 mfxU32 heightLa);
3476
3477 mfxStatus CorrectSliceInfoForsed(
3478 DdiTask & task,
3479 mfxU32 widthLa,
3480 mfxU32 heightLa);
3481
3482
3483
3484 mfxU32 CalcBiWeight(
3485 DdiTask const & task,
3486 mfxU32 indexL0,
3487 mfxU32 indexL1);
3488
3489
3490 mfxI32 GetPicNum(
3491 ArrayDpbFrame const & dpb,
3492 mfxU8 ref);
3493
3494 mfxI32 GetPicNumF(
3495 ArrayDpbFrame const & dpb,
3496 mfxU8 ref);
3497
3498 mfxU8 GetLongTermPicNum(
3499 ArrayDpbFrame const & dpb,
3500 mfxU8 ref);
3501
3502 mfxU32 GetLongTermPicNumF(
3503 ArrayDpbFrame const & dpb,
3504 mfxU8 ref);
3505
3506 mfxI32 GetPoc(
3507 ArrayDpbFrame const & dpb,
3508 mfxU8 ref);
3509
3510 DdiTaskIter ReorderFrame(
3511 ArrayDpbFrame const & dpb,
3512 DdiTaskIter begin,
3513 DdiTaskIter end);
3514
3515 DdiTaskIter ReorderFrame(
3516 ArrayDpbFrame const & dpb,
3517 DdiTaskIter begin,
3518 DdiTaskIter end,
3519 bool gopStrict,
3520 bool flush,
3521 bool closeGopForSceneChange);
3522
3523 DdiTaskIter FindFrameToStartEncode(
3524 MfxVideoParam const & video,
3525 DdiTaskIter begin,
3526 DdiTaskIter end);
3527
3528 DdiTaskIter FindFrameToWaitEncode(
3529 DdiTaskIter begin,
3530 DdiTaskIter end);
3531 DdiTaskIter FindFrameToWaitEncodeNext(
3532 DdiTaskIter begin,
3533 DdiTaskIter end,
3534 DdiTaskIter cur);
3535
3536 PairU8 GetFrameType(
3537 MfxVideoParam const & video,
3538 mfxU32 frameOrder);
3539
3540 IntraRefreshState GetIntraRefreshState(
3541 MfxVideoParam const & video,
3542 mfxU32 frameOrderInGop,
3543 mfxEncodeCtrl const * ctrl,
3544 mfxU16 intraStripeWidthInMBs,
3545 SliceDivider & divider,
3546 MFX_ENCODE_CAPS caps);
3547
3548 mfxStatus UpdateIntraRefreshWithoutIDR(
3549 MfxVideoParam const & oldPar,
3550 MfxVideoParam const & newPar,
3551 mfxU32 frameOrder,
3552 mfxI64 oldStartFrame,
3553 mfxI64 & updatedStartFrame,
3554 mfxU16 & updatedStripeWidthInMBs,
3555 SliceDivider & divider,
3556 MFX_ENCODE_CAPS caps);
3557
3558 BiFrameLocation GetBiFrameLocation(
3559 MfxVideoParam const & video,
3560 mfxU32 frameOrder,
3561 mfxU32 currGopRefDist,
3562 mfxU32 miniGOPCount);
3563
3564 void UpdateDpbFrames(
3565 DdiTask & task,
3566 mfxU32 field,
3567 mfxU32 frameNumMax);
3568
3569 void InitRefPicList(
3570 DdiTask & task,
3571 mfxU32 field);
3572
3573 void ModifyRefPicLists(
3574 MfxVideoParam const & video,
3575 DdiTask & task,
3576 mfxU32 fieldId);
3577
3578 void MarkDecodedRefPictures(
3579 MfxVideoParam const & video,
3580 DdiTask & task,
3581 mfxU32 fid);
3582
3583 ArrayRefListMod CreateRefListMod(
3584 ArrayDpbFrame const & dpb,
3585 ArrayU8x33 initList,
3586 ArrayU8x33 const & modList,
3587 mfxU32 curViewIdx,
3588 mfxI32 curPicNum,
3589 bool optimize);
3590
3591 void ConfigureTask(
3592 DdiTask & task,
3593 DdiTask const & prevTask,
3594 MfxVideoParam const & video,
3595 MFX_ENCODE_CAPS const & caps);
3596
3597 mfxStatus GetNativeHandleToRawSurface(
3598 VideoCORE & core,
3599 MfxVideoParam const & video,
3600 DdiTask const & task,
3601 mfxHDLPair & handle);
3602
3603 bool IsFrameToSkip(DdiTask& task, MfxFrameAllocResponse & poolRec, std::vector<mfxU32> fo, bool bSWBRC);
3604 mfxStatus CodeAsSkipFrame( VideoCORE& core,
3605 MfxVideoParam const & video,
3606 DdiTask& task,
3607 MfxFrameAllocResponse & pool,
3608 MfxFrameAllocResponse & poolRec);
3609 mfxStatus CopyRawSurfaceToVideoMemory(
3610 VideoCORE & core,
3611 MfxVideoParam const & video,
3612 DdiTask const & task);
3613
3614 mfxHDL ConvertMidToNativeHandle(
3615 VideoCORE & core,
3616 mfxMemId mid,
3617 bool external = false);
3618
3619 void AnalyzeVmeData(
3620 DdiTaskIter begin,
3621 DdiTaskIter end,
3622 mfxU32 width,
3623 mfxU32 height);
3624
3625 void CalcPredWeightTable(
3626 DdiTask & task,
3627 mfxU32 MaxNum_WeightedPredL0,
3628 mfxU32 MaxNum_WeightedPredL1);
3629
3630
3631 struct FindByFrameOrder
3632 {
FindByFrameOrderFindByFrameOrder3633 FindByFrameOrder(mfxU32 frameOrder) : m_frameOrder(frameOrder) {}
3634
operatorFindByFrameOrder3635 template <class T> bool operator ()(T const & task) const
3636 {
3637 return task.m_frameOrder == m_frameOrder;
3638 }
3639
3640 mfxU32 m_frameOrder;
3641 };
3642
3643 bool OrderByFrameNumWrap(DpbFrame const & lhs, DpbFrame const & rhs);
3644 bool OrderByFrameNumWrapKeyRef(DpbFrame const & lhs, DpbFrame const & rhs);
3645
find_if_ptr(T & container,P pred)3646 template <class T, class P> typename T::pointer find_if_ptr(T & container, P pred)
3647 {
3648 typename T::iterator i = std::find_if(container.begin(), container.end(), pred);
3649 return (i == container.end()) ? 0 : &*i;
3650 }
3651
find_if_ptr2(T & container1,T & container2,P pred)3652 template <class T, class P> typename T::pointer find_if_ptr2(T & container1, T & container2, P pred)
3653 {
3654 typename T::pointer p = find_if_ptr(container1, pred);
3655 if (p == 0)
3656 p = find_if_ptr(container2, pred);
3657 return p;
3658 }
find_if_ptr3(T & container1,T & container2,T & container3,P pred)3659 template <class T, class P> typename T::pointer find_if_ptr3(T & container1, T & container2, T & container3, P pred)
3660 {
3661 typename T::pointer p = find_if_ptr(container1, pred);
3662 if (p == 0)
3663 p = find_if_ptr(container2, pred);
3664 if (p == 0)
3665 p = find_if_ptr(container3, pred);
3666
3667 return p;
3668 }
find_if_ptr4(T & container1,T & container2,T & container3,T & container4,P pred)3669 template <class T, class P> typename T::pointer find_if_ptr4(T & container1, T & container2, T & container3, T & container4, P pred)
3670 {
3671 typename T::pointer p = find_if_ptr(container1, pred);
3672 if (p == 0)
3673 p = find_if_ptr(container2, pred);
3674 if (p == 0)
3675 p = find_if_ptr(container3, pred);
3676 if (p == 0)
3677 p = find_if_ptr(container4, pred);
3678
3679 return p;
3680 }
3681 }; // namespace MfxHwH264Encode
3682
3683 #endif // _MFX_H264_ENCODE_HW_UTILS_H_
3684 #endif // MFX_ENABLE_H264_VIDEO_ENCODE_HW
3685