1 /*
2 * Copyright (c) 2019-2021, Intel Corporation
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included
12 * in all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
15 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20 * OTHER DEALINGS IN THE SOFTWARE.
21 */
22
23 //!
24 //! \file sw_filter_pipe.cpp
25 //! \brief Defines the common interface for vp features manager
26 //! \details The vp manager is further sub-divided by vp type
27 //! this file is for the base interface which is shared by all components.
28 //!
29 #include "sw_filter_pipe.h"
30 #include "vp_obj_factories.h"
31 #include "vp_feature_manager.h"
32 #include "sw_filter_handle.h"
33
34 using namespace vp;
35
36 /****************************************************************************************************/
37 /* SwFilterSubPipe */
38 /****************************************************************************************************/
39
SwFilterSubPipe()40 SwFilterSubPipe::SwFilterSubPipe()
41 {
42 }
43
~SwFilterSubPipe()44 SwFilterSubPipe::~SwFilterSubPipe()
45 {
46 Clean();
47 }
48
Clean()49 MOS_STATUS SwFilterSubPipe::Clean()
50 {
51 VP_FUNC_CALL();
52
53 for (auto &filterSet : m_OrderedFilters)
54 {
55 if (filterSet)
56 {
57 // Loop orderred feature set.
58 VP_PUBLIC_CHK_STATUS_RETURN(filterSet->Clean());
59 MOS_Delete(filterSet);
60 }
61 }
62 m_OrderedFilters.clear();
63
64 // Process remaining unordered features
65 VP_PUBLIC_CHK_STATUS_RETURN(m_UnorderedFilters.Clean());
66
67 return MOS_STATUS_SUCCESS;
68 }
69
Update(VP_SURFACE * inputSurf,VP_SURFACE * outputSurf)70 MOS_STATUS SwFilterSubPipe::Update(VP_SURFACE *inputSurf, VP_SURFACE *outputSurf)
71 {
72 VP_FUNC_CALL();
73
74 for (auto &featureSet : m_OrderedFilters)
75 {
76 if (featureSet)
77 {
78 VP_PUBLIC_CHK_STATUS_RETURN(featureSet->Update(inputSurf, outputSurf, *this));
79 }
80 }
81 VP_PUBLIC_CHK_STATUS_RETURN(m_UnorderedFilters.Update(inputSurf, outputSurf, *this));
82
83 return MOS_STATUS_SUCCESS;
84 }
85
AddFeatureGraphRTLog()86 MOS_STATUS SwFilterSubPipe::AddFeatureGraphRTLog()
87 {
88 VP_FUNC_CALL();
89
90 for (auto &featureSet : m_OrderedFilters)
91 {
92 if (featureSet)
93 {
94 VP_PUBLIC_CHK_STATUS_RETURN(featureSet->AddFeatureGraphRTLog());
95 }
96 }
97 VP_PUBLIC_CHK_STATUS_RETURN(m_UnorderedFilters.AddFeatureGraphRTLog());
98
99 return MOS_STATUS_SUCCESS;
100 }
101
GetSwFilter(FeatureType type)102 SwFilter *SwFilterSubPipe::GetSwFilter(FeatureType type)
103 {
104 VP_FUNC_CALL();
105
106 // Search unordered filters firstly.
107 SwFilter *swFilter = m_UnorderedFilters.GetSwFilter(type);
108
109 if (swFilter)
110 {
111 return swFilter;
112 }
113
114 for (auto &swFilterSet : m_OrderedFilters)
115 {
116 swFilter = swFilterSet->GetSwFilter(type);
117 if (swFilter)
118 {
119 return swFilter;
120 }
121 }
122
123 return nullptr;
124 }
125
AddSwFilterOrdered(SwFilter * swFilter,bool useNewSwFilterSet)126 MOS_STATUS SwFilterSubPipe::AddSwFilterOrdered(SwFilter *swFilter, bool useNewSwFilterSet)
127 {
128 VP_FUNC_CALL();
129
130 VP_PUBLIC_CHK_NULL_RETURN(swFilter);
131
132 MOS_STATUS status = MOS_STATUS_SUCCESS;
133 SwFilterSet *swFilterSet = nullptr;
134 auto &pipe = m_OrderedFilters;
135
136 if (useNewSwFilterSet || pipe.empty())
137 {
138 swFilterSet = MOS_New(SwFilterSet);
139 useNewSwFilterSet = true;
140 }
141 else
142 {
143 swFilterSet = pipe[pipe.size() - 1];
144 }
145 VP_PUBLIC_CHK_NULL_RETURN(swFilterSet);
146
147 status = swFilterSet->AddSwFilter(swFilter);
148
149 if (MOS_FAILED(status))
150 {
151 if (useNewSwFilterSet)
152 {
153 MOS_Delete(swFilterSet);
154 }
155 return status;
156 }
157
158 pipe.push_back(swFilterSet);
159 swFilterSet->SetLocation(&pipe);
160
161 return MOS_STATUS_SUCCESS;
162 }
163
AddSwFilterUnordered(SwFilter * swFilter)164 MOS_STATUS SwFilterSubPipe::AddSwFilterUnordered(SwFilter *swFilter)
165 {
166 VP_FUNC_CALL();
167
168 VP_PUBLIC_CHK_NULL_RETURN(swFilter);
169 return m_UnorderedFilters.AddSwFilter(swFilter);
170 }
171
172 /****************************************************************************************************/
173 /* SwFilterPipe */
174 /****************************************************************************************************/
175
SwFilterPipe(VpInterface & vpInterface)176 SwFilterPipe::SwFilterPipe(VpInterface &vpInterface) : m_vpInterface(vpInterface)
177 {
178 m_surfacesSetting.Clean();
179 }
180
~SwFilterPipe()181 SwFilterPipe::~SwFilterPipe()
182 {
183 Clean();
184 }
185
Initialize(VP_PIPELINE_PARAMS & params,FeatureRule & featureRule)186 MOS_STATUS SwFilterPipe::Initialize(VP_PIPELINE_PARAMS ¶ms, FeatureRule &featureRule)
187 {
188 VP_FUNC_CALL();
189
190 Clean();
191
192 uint32_t i = 0;
193 for (i = 0; i < params.uSrcCount; ++i)
194 {
195 if (nullptr == params.pSrc[i])
196 {
197 Clean();
198 return MOS_STATUS_INVALID_PARAMETER;
199 }
200 VP_SURFACE *surf = m_vpInterface.GetAllocator().AllocateVpSurface(*params.pSrc[i]);
201 if (nullptr == surf)
202 {
203 Clean();
204 MT_ERR2(MT_VP_HAL_SWWFILTER, MT_CODE_LINE, __LINE__, MT_ERROR_CODE, MOS_STATUS_NULL_POINTER);
205 return MOS_STATUS_NULL_POINTER;
206 }
207
208 surf->Palette = params.pSrc[i]->Palette;
209
210 m_InputSurfaces.push_back(surf);
211
212 // Keep m_pastSurface/m_futureSurface same size as m_InputSurfaces.
213 VP_SURFACE *pastSurface = nullptr;
214 if (params.pSrc[i]->uBwdRefCount > 0 && params.pSrc[i]->pBwdRef &&
215 params.pSrc[i]->FrameID != params.pSrc[i]->pBwdRef->FrameID)
216 {
217 pastSurface = m_vpInterface.GetAllocator().AllocateVpSurface(*params.pSrc[i]->pBwdRef);
218 }
219 VP_SURFACE *futureSurface = nullptr;
220 if (params.pSrc[i]->uFwdRefCount > 0 && params.pSrc[i]->pFwdRef &&
221 params.pSrc[i]->FrameID != params.pSrc[i]->pFwdRef->FrameID)
222 {
223 futureSurface = m_vpInterface.GetAllocator().AllocateVpSurface(*params.pSrc[i]->pFwdRef);
224 }
225 m_pastSurface.push_back(pastSurface);
226 m_futureSurface.push_back(futureSurface);
227 m_linkedLayerIndex.push_back(0);
228
229 // Initialize m_InputPipes.
230 SwFilterSubPipe *pipe = MOS_New(SwFilterSubPipe);
231 if (nullptr == pipe)
232 {
233 Clean();
234 return MOS_STATUS_NULL_POINTER;
235 }
236 m_InputPipes.push_back(pipe);
237 }
238
239 for (i = 0; i < params.uDstCount; ++i)
240 {
241 if (nullptr == params.pTarget[i])
242 {
243 Clean();
244 return MOS_STATUS_INVALID_PARAMETER;
245 }
246 VP_SURFACE *surf = m_vpInterface.GetAllocator().AllocateVpSurface(*params.pTarget[i]);
247 if (nullptr == surf)
248 {
249 Clean();
250 MT_ERR2(MT_VP_HAL_SWWFILTER, MT_CODE_LINE, __LINE__, MT_ERROR_CODE, MOS_STATUS_NULL_POINTER);
251 return MOS_STATUS_NULL_POINTER;
252 }
253 m_OutputSurfaces.push_back(surf);
254
255 // Initialize m_OutputPipes.
256 SwFilterSubPipe *pipe = MOS_New(SwFilterSubPipe);
257 if (nullptr == pipe)
258 {
259 Clean();
260 return MOS_STATUS_NULL_POINTER;
261 }
262 m_OutputPipes.push_back(pipe);
263 }
264
265 UpdateSwFilterPipeType();
266
267 MOS_STATUS status = ConfigFeatures(params, featureRule);
268 if (MOS_FAILED(status))
269 {
270 Clean();
271 return status;
272 }
273
274 return MOS_STATUS_SUCCESS;
275 }
276
Initialize(VEBOX_SFC_PARAMS & params)277 MOS_STATUS SwFilterPipe::Initialize(VEBOX_SFC_PARAMS ¶ms)
278 {
279 VP_FUNC_CALL();
280
281 Clean();
282
283 // Initialize input surface.
284 {
285 if (nullptr == params.input.surface)
286 {
287 Clean();
288 return MOS_STATUS_INVALID_PARAMETER;
289 }
290 // The value of plane offset are different between vp and codec. updatePlaneOffset need be set to true when create vp surface
291 // with mos surface from codec hal.
292 VP_SURFACE *input = m_vpInterface.GetAllocator().AllocateVpSurface(*params.input.surface, params.input.colorSpace,
293 params.input.chromaSiting, params.input.rcSrc,
294 params.output.rcDst, SURF_IN_PRIMARY, true);
295 if (nullptr == input)
296 {
297 Clean();
298 return MOS_STATUS_NULL_POINTER;
299 }
300 m_InputSurfaces.push_back(input);
301 // Keep m_PastSurface same size as m_InputSurfaces.
302 m_pastSurface.push_back(nullptr);
303 m_futureSurface.push_back(nullptr);
304 m_linkedLayerIndex.push_back(0);
305
306 // Initialize m_InputPipes.
307 SwFilterSubPipe *pipe = MOS_New(SwFilterSubPipe);
308 if (nullptr == pipe)
309 {
310 Clean();
311 return MOS_STATUS_NULL_POINTER;
312 }
313 m_InputPipes.push_back(pipe);
314 }
315
316 // Initialize output surface.
317 {
318 if (nullptr == params.output.surface)
319 {
320 Clean();
321 return MOS_STATUS_INVALID_PARAMETER;
322 }
323
324 RECT recOutput = {0, 0, (int32_t)params.output.surface->dwWidth, (int32_t)params.output.surface->dwHeight};
325 // The value of plane offset are different between vp and codec. updatePlaneOffset need be set to true when create vp surface
326 // with mos surface from codec hal.
327 VP_SURFACE *output = m_vpInterface.GetAllocator().AllocateVpSurface(*params.output.surface, params.output.colorSpace,
328 params.output.chromaSiting, recOutput,
329 recOutput, SURF_OUT_RENDERTARGET, true);
330 if (nullptr == output)
331 {
332 Clean();
333 return MOS_STATUS_NULL_POINTER;
334 }
335 m_OutputSurfaces.push_back(output);
336
337 // Initialize m_OutputPipes.
338 SwFilterSubPipe *pipe = MOS_New(SwFilterSubPipe);
339 if (nullptr == pipe)
340 {
341 Clean();
342 return MOS_STATUS_NULL_POINTER;
343 }
344 m_OutputPipes.push_back(pipe);
345 }
346
347 UpdateSwFilterPipeType();
348
349 MOS_STATUS status = ConfigFeatures(params);
350 if (MOS_FAILED(status))
351 {
352 Clean();
353 return status;
354 }
355
356 return MOS_STATUS_SUCCESS;
357 }
358
UpdateSwFilterPipeType()359 void SwFilterPipe::UpdateSwFilterPipeType()
360 {
361 VP_FUNC_CALL();
362
363 m_swFilterPipeType = SwFilterPipeTypeInvalid;
364
365 if (1 == m_InputSurfaces.size() && 1 == m_OutputSurfaces.size())
366 {
367 m_swFilterPipeType = SwFilterPipeType1To1;
368 }
369 else if (m_InputSurfaces.size() > 1 && 1 == m_OutputSurfaces.size())
370 {
371 m_swFilterPipeType = SwFilterPipeTypeNTo1;
372 }
373 else if (1 == m_InputSurfaces.size() && m_OutputSurfaces.size() > 1)
374 {
375 m_swFilterPipeType = SwFilterPipeType1ToN;
376 }
377 else if (0 == m_InputSurfaces.size() && 1 == m_OutputSurfaces.size())
378 {
379 m_swFilterPipeType = SwFilterPipeType0To1;
380 }
381 }
382
Clean()383 MOS_STATUS SwFilterPipe::Clean()
384 {
385 VP_FUNC_CALL();
386
387 // Do not unregister features in Clean, which will be reused until swFilterPipe being destroyed.
388 m_swFilterPipeType = SwFilterPipeTypeInvalid;
389
390 CleanFeatures();
391
392 std::vector<SwFilterSubPipe *> *pipes[] = {&m_InputPipes, &m_OutputPipes};
393 for (auto pipe : pipes)
394 {
395 while (!pipe->empty())
396 {
397 auto p = pipe->back();
398 MOS_Delete(p);
399 pipe->pop_back();
400 }
401 }
402
403 std::vector<VP_SURFACE *> *surfacesArray[] = {&m_InputSurfaces, &m_OutputSurfaces, &m_pastSurface, &m_futureSurface};
404 for (auto surfaces : surfacesArray)
405 {
406 while (!surfaces->empty())
407 {
408 auto p = surfaces->back();
409 m_vpInterface.GetAllocator().DestroyVpSurface(p);
410 surfaces->pop_back();
411 }
412 }
413 m_linkedLayerIndex.clear();
414
415 m_isExePipe = false;
416
417 return MOS_STATUS_SUCCESS;
418 }
419
IsEmpty()420 bool SwFilterPipe::IsEmpty()
421 {
422 VP_FUNC_CALL();
423
424 for (auto pipe : m_InputPipes)
425 {
426 if (!pipe->IsEmpty())
427 {
428 return false;
429 }
430 }
431
432 for (auto pipe : m_OutputPipes)
433 {
434 if (!pipe->IsEmpty())
435 {
436 return false;
437 }
438 }
439
440 return true;
441 }
442
IsPrimaryEmpty()443 bool SwFilterPipe::IsPrimaryEmpty()
444 {
445 VP_FUNC_CALL();
446
447 uint32_t index;
448 auto pipe = GetSwFilterPrimaryPipe(index);
449
450 if (pipe->IsEmpty())
451 {
452 return true;
453 }
454
455 return false;
456 }
457
ConfigFeaturesToPipe(VP_PIPELINE_PARAMS & params,FeatureRule & featureRule,bool isInputPipe)458 MOS_STATUS SwFilterPipe::ConfigFeaturesToPipe(VP_PIPELINE_PARAMS ¶ms, FeatureRule &featureRule, bool isInputPipe)
459 {
460 VP_FUNC_CALL();
461
462 std::vector<SwFilterSubPipe *> &pipes = isInputPipe ? m_InputPipes : m_OutputPipes;
463 std::vector<FeatureSubRule> &rulePipes = isInputPipe ? featureRule.m_InputPipes : featureRule.m_OutputPipes;
464 SwFilter *swFilter = nullptr;
465 // Loop all input surfaces.
466 for (uint32_t pipeIndex = 0; pipeIndex < pipes.size(); ++pipeIndex)
467 {
468 // Get a copy list for feature handler.
469 auto featureHander = *m_vpInterface.GetSwFilterHandlerMap();
470
471 if (pipeIndex < rulePipes.size())
472 {
473 auto &featurePipe = rulePipes[pipeIndex];
474
475 for (auto &featureSet : featurePipe.m_Rule)
476 {
477 // Loop orderred feature set.
478 bool useNewSwFilterSet = true;
479 for (auto &feature : featureSet.m_Features)
480 {
481 // Loop all features in feature set.
482 SwFilterFeatureHandler *handler = featureHander.find(feature)->second;
483 VP_PUBLIC_CHK_NULL_RETURN(handler);
484 VP_PUBLIC_CHK_STATUS_RETURN(handler->CreateSwFilter(swFilter, params, isInputPipe, pipeIndex, m_swFilterPipeType));
485 if (swFilter)
486 {
487 VP_PUBLIC_CHK_STATUS_RETURN(AddSwFilterOrdered(swFilter, isInputPipe, pipeIndex, useNewSwFilterSet));
488 featureHander.erase(feature);
489 useNewSwFilterSet = false;
490 }
491 // nullptr == swFilter means no such feature in params, which is also the valid case.
492 }
493 }
494 }
495
496 // Process remaining unordered features
497 for (auto &handler : featureHander)
498 {
499 VP_PUBLIC_CHK_STATUS_RETURN(handler.second->CreateSwFilter(swFilter, params, isInputPipe, pipeIndex, m_swFilterPipeType));
500 if (swFilter)
501 {
502 VP_PUBLIC_CHK_STATUS_RETURN(AddSwFilterUnordered(swFilter, isInputPipe, pipeIndex));
503 MT_LOG4(MT_VP_HAL_SWWFILTER_ADD, MT_NORMAL, MT_VP_HAL_PIPE_ISINPUT, isInputPipe, MT_VP_HAL_PIPE_INDEX, pipeIndex,
504 MT_VP_HAL_FEATUERTYPE, swFilter->GetFeatureType(), MT_VP_HAL_ENGINECAPS, int64_t(swFilter->GetFilterEngineCaps().value));
505 }
506 }
507 }
508
509 return MOS_STATUS_SUCCESS;
510 }
511
ConfigFeatures(VP_PIPELINE_PARAMS & params,FeatureRule & featureRule)512 MOS_STATUS SwFilterPipe::ConfigFeatures(VP_PIPELINE_PARAMS ¶ms, FeatureRule &featureRule)
513 {
514 VP_FUNC_CALL();
515
516 MOS_STATUS status1 = ConfigFeaturesToPipe(params, featureRule, true);
517 MOS_STATUS status2 = ConfigFeaturesToPipe(params, featureRule, false);
518
519 // Return the status for the failure one.
520 return MOS_STATUS_SUCCESS == status1 ? status2 : status1;
521 }
522
ConfigFeatures(VEBOX_SFC_PARAMS & params)523 MOS_STATUS SwFilterPipe::ConfigFeatures(VEBOX_SFC_PARAMS ¶ms)
524 {
525 VP_FUNC_CALL();
526
527 std::vector<SwFilterSubPipe *> &pipes = m_InputPipes;
528
529 SwFilter *swFilter = nullptr;
530 // Loop all input surfaces.
531 for (uint32_t pipeIndex = 0; pipeIndex < pipes.size(); ++pipeIndex)
532 {
533 auto featureHander = m_vpInterface.GetSwFilterHandlerMap();
534 // Process remaining unordered features
535 if (featureHander)
536 {
537 for (auto handler = featureHander->begin(); handler != featureHander->end(); handler++)
538 {
539 VP_PUBLIC_CHK_STATUS_RETURN(handler->second->CreateSwFilter(swFilter, params));
540 if (swFilter)
541 {
542 VP_PUBLIC_CHK_STATUS_RETURN(AddSwFilterUnordered(swFilter, true, 0));
543 }
544 }
545 }
546 else
547 {
548 VP_PUBLIC_ASSERTMESSAGE("No VP Feature Manager Created");
549 return MOS_STATUS_UNIMPLEMENTED;
550 }
551 }
552
553 return MOS_STATUS_SUCCESS;
554 }
555
UpdateFeatures(bool isInputPipe,uint32_t pipeIndex,VP_EXECUTE_CAPS * caps)556 MOS_STATUS SwFilterPipe::UpdateFeatures(bool isInputPipe, uint32_t pipeIndex, VP_EXECUTE_CAPS *caps)
557 {
558 VP_FUNC_CALL();
559
560 auto &pipes = isInputPipe ? m_InputPipes : m_OutputPipes;
561 auto &surfaces = isInputPipe ? m_InputSurfaces : m_OutputSurfaces;
562
563 if (pipeIndex >= pipes.size() || pipeIndex >= surfaces.size() || 0 == m_OutputPipes.size() ||
564 m_InputPipes.size() != m_InputSurfaces.size() || m_OutputPipes.size() != m_OutputSurfaces.size())
565 {
566 return MOS_STATUS_INVALID_PARAMETER;
567 }
568
569 // Always use index 0 for the pipe whose pipeIndex not being specified.
570 auto inputPipe = isInputPipe ? m_InputPipes[pipeIndex] : (m_InputPipes.size() > 0 ? m_InputPipes[0] : nullptr);
571 auto outputPipe = isInputPipe ? m_OutputPipes[0] : m_OutputPipes[pipeIndex];
572
573 auto inputSurf = isInputPipe ? m_InputSurfaces[pipeIndex] : (m_InputSurfaces.size() > 0 ? m_InputSurfaces[0] : nullptr);
574 auto outputSurf = isInputPipe ? m_OutputSurfaces[0] : m_OutputSurfaces[pipeIndex];
575
576 if (nullptr == outputPipe || nullptr == outputSurf)
577 {
578 return MOS_STATUS_INVALID_PARAMETER;
579 }
580
581 // Input surface/pipe may be empty for some feature.
582 if (inputPipe)
583 {
584 if (caps && caps->bComposite)
585 {
586 // Always keep csc filter in fc pipe. The csc filter for multi-pass intermediate surface case will be added here.
587 if (nullptr == inputPipe->GetSwFilter(FeatureTypeCsc))
588 {
589 auto handler = m_vpInterface.GetSwFilterHandler(FeatureTypeCsc);
590 VP_PUBLIC_CHK_NULL_RETURN(handler);
591 SwFilterCsc* swfilter = dynamic_cast<SwFilterCsc *>(handler->CreateSwFilter());
592 VP_PUBLIC_CHK_NULL_RETURN(swfilter);
593 swfilter->Configure(inputSurf, outputSurf, *caps);
594 inputPipe->AddSwFilterUnordered(swfilter);
595 }
596 }
597
598 VP_PUBLIC_CHK_STATUS_RETURN(inputPipe->Update(inputSurf, outputSurf));
599 }
600
601 VP_PUBLIC_CHK_STATUS_RETURN(outputPipe->Update(inputSurf, outputSurf));
602
603 return MOS_STATUS_SUCCESS;
604 }
605
CleanFeaturesFromPipe(bool isInputPipe,uint32_t index)606 MOS_STATUS SwFilterPipe::CleanFeaturesFromPipe(bool isInputPipe, uint32_t index)
607 {
608 VP_FUNC_CALL();
609
610 MOS_STATUS status = MOS_STATUS_SUCCESS;
611 std::vector<SwFilterSubPipe *> &pipes = isInputPipe ? m_InputPipes : m_OutputPipes;
612
613 if (index < pipes.size() && pipes[index])
614 {
615 return pipes[index]->Clean();
616 }
617
618 return MOS_STATUS_INVALID_PARAMETER;
619 }
620
CleanFeaturesFromPipe(bool isInputPipe)621 MOS_STATUS SwFilterPipe::CleanFeaturesFromPipe(bool isInputPipe)
622 {
623 VP_FUNC_CALL();
624
625 MOS_STATUS status = MOS_STATUS_SUCCESS;
626 std::vector<SwFilterSubPipe *> &pipes = isInputPipe ? m_InputPipes : m_OutputPipes;
627 for (uint32_t pipeIndex = 0; pipeIndex < pipes.size(); ++pipeIndex)
628 {
629 MOS_STATUS tmpStat = CleanFeaturesFromPipe(isInputPipe, pipeIndex);
630 if (MOS_FAILED(tmpStat))
631 {
632 VP_PUBLIC_ASSERTMESSAGE("CleanFeaturesFromPipe failed for pipe %d with status = %08x.", pipeIndex, tmpStat);
633 // Always record first failure.
634 status = MOS_FAILED(status) ? status : tmpStat;
635 }
636 }
637
638 // Do not clear pipe here since it should align with m_InputSurfaces/m_OutputSurfaces.
639
640 return status;
641 }
642
CleanFeatures()643 MOS_STATUS SwFilterPipe::CleanFeatures()
644 {
645 VP_FUNC_CALL();
646
647 MOS_STATUS status1 = CleanFeaturesFromPipe(true);
648 MOS_STATUS status2 = CleanFeaturesFromPipe(false);
649
650 // Return the status for the failure one.
651 return MOS_STATUS_SUCCESS == status1 ? status2 : status1;
652 }
653
GetSwFilter(bool isInputPipe,int index,FeatureType type)654 SwFilter *SwFilterPipe::GetSwFilter(bool isInputPipe, int index, FeatureType type)
655 {
656 VP_FUNC_CALL();
657
658 SwFilterSubPipe * pipe = GetSwFilterSubPipe(isInputPipe, index);
659 if (nullptr == pipe)
660 {
661 // May come here for ClearView case.
662 VP_PUBLIC_NORMALMESSAGE("Invalid parameter! No sub pipe exists!");
663 return nullptr;
664 }
665
666 return pipe->GetSwFilter(type);
667 }
668
GetSwFilterSubPipe(bool isInputPipe,int index)669 SwFilterSubPipe* SwFilterPipe::GetSwFilterSubPipe(bool isInputPipe, int index)
670 {
671 VP_FUNC_CALL();
672
673 SwFilterSubPipe* pSubPipe = nullptr;
674 auto& pipes = isInputPipe ? m_InputPipes : m_OutputPipes;
675
676 if ((uint32_t)index < pipes.size())
677 {
678 pSubPipe = pipes[index];
679 }
680 return pSubPipe;
681 }
682
GetSwFilterPrimaryPipe(uint32_t & index)683 SwFilterSubPipe* SwFilterPipe::GetSwFilterPrimaryPipe(uint32_t& index)
684 {
685 VP_FUNC_CALL();
686
687 SwFilterSubPipe* pSubPipe = nullptr;
688
689 index = 0;
690
691 if (m_InputPipes.size() == 0)
692 {
693 return nullptr;
694 }
695
696 for (auto item : m_InputSurfaces)
697 {
698
699 if (item->SurfType == SURF_IN_PRIMARY)
700 {
701 pSubPipe = m_InputPipes[index];
702 return pSubPipe;
703 }
704 ++index;
705 }
706 return pSubPipe;
707 }
708
709 // useNewSwFilterSet: true if insert new swFilterSet in pipe, otherwise, reuse the last one in pipe.
AddSwFilterOrdered(SwFilter * swFilter,bool isInputPipe,int index,bool useNewSwFilterSet)710 MOS_STATUS SwFilterPipe::AddSwFilterOrdered(SwFilter *swFilter, bool isInputPipe, int index, bool useNewSwFilterSet)
711 {
712 VP_FUNC_CALL();
713
714 VP_PUBLIC_CHK_NULL_RETURN(swFilter);
715
716 SwFilterSubPipe *pSubPipe = GetSwFilterSubPipe(isInputPipe, index);
717 VP_PUBLIC_CHK_NULL_RETURN(pSubPipe);
718
719 VP_PUBLIC_CHK_STATUS_RETURN(pSubPipe->AddSwFilterOrdered(swFilter, useNewSwFilterSet));
720 swFilter->SetExePipeFlag(m_isExePipe);
721
722 return MOS_STATUS_SUCCESS;
723 }
724
AddSwFilterUnordered(SwFilter * swFilter,bool isInputPipe,int index)725 MOS_STATUS SwFilterPipe::AddSwFilterUnordered(SwFilter *swFilter, bool isInputPipe, int index)
726 {
727 VP_FUNC_CALL();
728
729 VP_PUBLIC_CHK_NULL_RETURN(swFilter);
730
731 SwFilterSubPipe *pSubPipe = GetSwFilterSubPipe(isInputPipe, index);
732
733 if (nullptr == pSubPipe && !isInputPipe)
734 {
735 auto& pipes = m_OutputPipes;
736 SwFilterSubPipe *pipe = MOS_New(SwFilterSubPipe);
737 VP_PUBLIC_CHK_NULL_RETURN(pipe);
738 if ((size_t)index <= pipes.size())
739 {
740 for (int32_t i = (int)pipes.size(); i <= index; ++i)
741 {
742 pipes.push_back(nullptr);
743 }
744 }
745 pipes[index] = pipe;
746 pSubPipe = GetSwFilterSubPipe(isInputPipe, index);
747 }
748
749 VP_PUBLIC_CHK_NULL_RETURN(pSubPipe);
750
751 VP_PUBLIC_CHK_STATUS_RETURN(pSubPipe->AddSwFilterUnordered(swFilter));
752 swFilter->SetExePipeFlag(m_isExePipe);
753
754 return MOS_STATUS_SUCCESS;
755 }
756
RemoveSwFilter(SwFilter * swFilter)757 MOS_STATUS SwFilterPipe::RemoveSwFilter(SwFilter *swFilter)
758 {
759 VP_FUNC_CALL();
760
761 VP_PUBLIC_CHK_NULL_RETURN(swFilter);
762
763 SwFilterSet *swFilterSet = swFilter->GetLocation();
764 VP_PUBLIC_CHK_NULL_RETURN(swFilterSet);
765
766 VP_PUBLIC_CHK_STATUS_RETURN(swFilterSet->RemoveSwFilter(swFilter));
767
768 // Delete swFilterSet if needed.
769 auto pipe = swFilterSet->GetLocation();
770 if (pipe && swFilterSet->IsEmpty())
771 {
772 for (auto it = pipe->begin(); it != pipe->end(); ++it)
773 {
774 if (*it == swFilterSet)
775 {
776 pipe->erase(it);
777 break;
778 }
779 }
780 swFilterSet->SetLocation(nullptr);
781
782 MOS_Delete(swFilterSet);
783 }
784 return MOS_STATUS_SUCCESS;
785 }
786
GetSurface(bool isInputSurface,uint32_t index)787 VP_SURFACE *SwFilterPipe::GetSurface(bool isInputSurface, uint32_t index)
788 {
789 VP_FUNC_CALL();
790
791 if (isInputSurface)
792 {
793 return index < m_InputSurfaces.size() ? m_InputSurfaces[index] : nullptr;
794 }
795 else
796 {
797 return index < m_OutputSurfaces.size() ? m_OutputSurfaces[index] : nullptr;
798 }
799 }
800
GetPastSurface(uint32_t index)801 VP_SURFACE *SwFilterPipe::GetPastSurface(uint32_t index)
802 {
803 VP_FUNC_CALL();
804
805 return index < m_pastSurface.size() ? m_pastSurface[index] : nullptr;
806 }
807
GetFutureSurface(uint32_t index)808 VP_SURFACE *SwFilterPipe::GetFutureSurface(uint32_t index)
809 {
810 VP_FUNC_CALL();
811
812 return index < m_futureSurface.size() ? m_futureSurface[index] : nullptr;
813 }
814
SetPastSurface(uint32_t index,VP_SURFACE * surf)815 MOS_STATUS SwFilterPipe::SetPastSurface(uint32_t index, VP_SURFACE *surf)
816 {
817 VP_FUNC_CALL();
818
819 if (index >= m_pastSurface.size())
820 {
821 return MOS_STATUS_INVALID_PARAMETER;
822 }
823 m_pastSurface[index] = surf;
824 return MOS_STATUS_SUCCESS;
825 }
826
SetFutureSurface(uint32_t index,VP_SURFACE * surf)827 MOS_STATUS SwFilterPipe::SetFutureSurface(uint32_t index, VP_SURFACE *surf)
828 {
829 VP_FUNC_CALL();
830
831 if (index >= m_futureSurface.size())
832 {
833 return MOS_STATUS_INVALID_PARAMETER;
834 }
835 m_futureSurface[index] = surf;
836 return MOS_STATUS_SUCCESS;
837 }
838
RemovePastSurface(uint32_t index)839 VP_SURFACE *SwFilterPipe::RemovePastSurface(uint32_t index)
840 {
841 VP_FUNC_CALL();
842
843 if (index >= m_pastSurface.size())
844 {
845 return nullptr;
846 }
847 VP_SURFACE *surf = m_pastSurface[index];
848 m_pastSurface[index] = nullptr;
849 return surf;
850 }
851
RemoveFutureSurface(uint32_t index)852 VP_SURFACE *SwFilterPipe::RemoveFutureSurface(uint32_t index)
853 {
854 VP_FUNC_CALL();
855
856 if (index >= m_futureSurface.size())
857 {
858 return nullptr;
859 }
860 VP_SURFACE *surf = m_futureSurface[index];
861 m_futureSurface[index] = nullptr;
862 return surf;
863 }
864
DestroySurface(bool isInputSurface,uint32_t index)865 MOS_STATUS SwFilterPipe::DestroySurface(bool isInputSurface, uint32_t index)
866 {
867 VP_SURFACE *surf = SwFilterPipe::RemoveSurface(isInputSurface, index);
868 VP_PUBLIC_CHK_NULL_RETURN(surf);
869 m_vpInterface.GetAllocator().DestroyVpSurface(surf);
870 return MOS_STATUS_SUCCESS;
871 }
872
RemoveSurface(bool isInputSurface,uint32_t index)873 VP_SURFACE *SwFilterPipe::RemoveSurface(bool isInputSurface, uint32_t index)
874 {
875 VP_FUNC_CALL();
876
877 auto &surfaces = isInputSurface ? m_InputSurfaces : m_OutputSurfaces;
878
879 if (index < surfaces.size())
880 {
881 VP_SURFACE *surf = surfaces[index];
882 surfaces[index] = nullptr;
883
884 if (isInputSurface)
885 {
886 // Keep m_pastSurface and m_futureSurface same status as m_InputSurfaces.
887 if (m_pastSurface[index])
888 {
889 m_vpInterface.GetAllocator().DestroyVpSurface(m_pastSurface[index]);
890 }
891 if (m_futureSurface[index])
892 {
893 m_vpInterface.GetAllocator().DestroyVpSurface(m_futureSurface[index]);
894 }
895 if (m_linkedLayerIndex[index])
896 {
897 m_linkedLayerIndex[index] = 0;
898 }
899 }
900
901 return surf;
902 }
903 return nullptr;
904 }
905
ReplaceSurface(VP_SURFACE * surf,bool isInputSurface,uint32_t index)906 VP_SURFACE *SwFilterPipe::ReplaceSurface(VP_SURFACE *surf, bool isInputSurface, uint32_t index)
907 {
908 VP_FUNC_CALL();
909
910 auto &surfaces = isInputSurface ? m_InputSurfaces : m_OutputSurfaces;
911
912 if (index < surfaces.size())
913 {
914 VP_SURFACE *ret = surfaces[index];
915 surfaces[index] = surf;
916 return ret;
917 }
918 return nullptr;
919 }
920
AddSurface(VP_SURFACE * & surf,bool isInputSurface,uint32_t index)921 MOS_STATUS SwFilterPipe::AddSurface(VP_SURFACE *&surf, bool isInputSurface, uint32_t index)
922 {
923 VP_FUNC_CALL();
924
925 auto &surfaces = isInputSurface ? m_InputSurfaces : m_OutputSurfaces;
926 auto &pipes = isInputSurface ? m_InputPipes : m_OutputPipes;
927
928 for (uint32_t i = surfaces.size(); i <= index; ++i)
929 {
930 surfaces.push_back(nullptr);
931 if (isInputSurface)
932 {
933 // Keep m_PastSurface same size as m_InputSurfaces.
934 m_pastSurface.push_back(nullptr);
935 m_futureSurface.push_back(nullptr);
936 m_linkedLayerIndex.push_back(0);
937 }
938 }
939
940 if (index >= surfaces.size())
941 {
942 return MOS_STATUS_INVALID_PARAMETER;
943 }
944
945 if (nullptr != surfaces[index])
946 {
947 return MOS_STATUS_INVALID_PARAMETER;
948 }
949
950 for (uint32_t i = pipes.size(); i <= index; ++i)
951 {
952 pipes.push_back(nullptr);
953 }
954
955 if (index >= surfaces.size())
956 {
957 return MOS_STATUS_INVALID_PARAMETER;
958 }
959
960 if (nullptr == pipes[index])
961 {
962 SwFilterSubPipe *pipe = MOS_New(SwFilterSubPipe);
963 VP_PUBLIC_CHK_NULL_RETURN(pipe);
964 pipes[index] = pipe;
965 }
966
967 surfaces[index] = surf;
968 return MOS_STATUS_SUCCESS;
969 }
970
971 template<class T>
RemoveUnusedLayers(std::vector<uint32_t> & indexForRemove,std::vector<T> & layers)972 MOS_STATUS RemoveUnusedLayers(std::vector<uint32_t> &indexForRemove, std::vector<T> &layers)
973 {
974 VP_FUNC_CALL();
975
976 if (indexForRemove.size() == 0)
977 {
978 return MOS_STATUS_SUCCESS;
979 }
980
981 if (sizeof(T) < sizeof(int))
982 {
983 VP_PUBLIC_CHK_STATUS_RETURN(MOS_STATUS_INVALID_PARAMETER);
984 }
985 const int keyForDelete = 0xabcdabcd;
986 for (uint32_t index : indexForRemove)
987 {
988 if (index >= layers.size())
989 {
990 VP_PUBLIC_CHK_STATUS_RETURN(MOS_STATUS_INVALID_PARAMETER);
991 }
992 // Mark the items to be removed.
993 *(int *)&layers[index] = keyForDelete;
994 }
995
996 for (auto it = layers.begin(); it != layers.end();)
997 {
998 if (keyForDelete == *(int *)&(*it))
999 {
1000 it = layers.erase(it);
1001 }
1002 else
1003 {
1004 ++it;
1005 }
1006 }
1007
1008 return MOS_STATUS_SUCCESS;
1009 }
1010
1011 template<class T>
RemoveUnusedLayers(std::vector<uint32_t> & indexForRemove,std::vector<T * > & layers,bool freeObj)1012 MOS_STATUS RemoveUnusedLayers(std::vector<uint32_t> &indexForRemove, std::vector<T*> &layers, bool freeObj)
1013 {
1014 VP_FUNC_CALL();
1015
1016 if (indexForRemove.size() == 0)
1017 {
1018 return MOS_STATUS_SUCCESS;
1019 }
1020
1021 if (freeObj)
1022 {
1023 std::map<T*, T*> objForRemove;
1024 for (uint32_t index : indexForRemove)
1025 {
1026 if (index >= layers.size())
1027 {
1028 VP_PUBLIC_CHK_STATUS_RETURN(MOS_STATUS_INVALID_PARAMETER);
1029 }
1030 objForRemove.insert(std::make_pair(layers[index], layers[index]));
1031 layers[index] = nullptr;
1032 }
1033 for (auto it : objForRemove)
1034 {
1035 MOS_Delete(it.second);
1036 }
1037 }
1038
1039 return RemoveUnusedLayers(indexForRemove, layers);
1040 }
1041
RemoveUnusedLayers(bool bUpdateInput)1042 MOS_STATUS SwFilterPipe::RemoveUnusedLayers(bool bUpdateInput)
1043 {
1044 VP_FUNC_CALL();
1045
1046 // If bUpdateInput == true, surfaces1 is input layers, which will be updated, and surfaces2 is output layers,
1047 // otherwise, surfaces1 is output layers, which will be updated, and surfaces2 is input layers.
1048 auto &surfaces1 = bUpdateInput ? m_InputSurfaces : m_OutputSurfaces;
1049 auto &surfaces2 = !bUpdateInput ? m_InputSurfaces : m_OutputSurfaces;
1050 auto &pipes = bUpdateInput ? m_InputPipes : m_OutputPipes;
1051
1052 std::vector<uint32_t> indexForRemove;
1053 uint32_t i = 0;
1054 bool isInputNullValid = (!bUpdateInput && pipes.size()>0 && !pipes[0]->IsEmpty());
1055
1056 for (i = 0; i < surfaces1.size(); ++i)
1057 {
1058 if (nullptr == surfaces1[i] || (!isInputNullValid && 0 == surfaces2.size()) ||
1059 1 == surfaces2.size() && nullptr == surfaces2[0])
1060 {
1061 indexForRemove.push_back(i);
1062 CleanFeaturesFromPipe(bUpdateInput, i);
1063 }
1064 }
1065
1066 VP_PUBLIC_CHK_STATUS_RETURN(::RemoveUnusedLayers(indexForRemove, surfaces1, false));
1067 if (bUpdateInput)
1068 {
1069 // Keep m_pastSurface same size as m_InputSurfaces.
1070 VP_PUBLIC_CHK_STATUS_RETURN(::RemoveUnusedLayers(indexForRemove, m_pastSurface, false));
1071 // Keep m_futureSurface same size as m_InputSurfaces.
1072 VP_PUBLIC_CHK_STATUS_RETURN(::RemoveUnusedLayers(indexForRemove, m_futureSurface, false));
1073 // Keep m_linkedLayerIndex same size as m_InputSurfaces.
1074 VP_PUBLIC_CHK_STATUS_RETURN(::RemoveUnusedLayers(indexForRemove, m_linkedLayerIndex));
1075 }
1076
1077 VP_PUBLIC_CHK_STATUS_RETURN(::RemoveUnusedLayers(indexForRemove, pipes, true));
1078
1079 return MOS_STATUS_SUCCESS;
1080 }
1081
Update(VP_EXECUTE_CAPS * caps)1082 MOS_STATUS SwFilterPipe::Update(VP_EXECUTE_CAPS *caps)
1083 {
1084 VP_FUNC_CALL();
1085
1086 uint32_t i = 0;
1087
1088 VP_PUBLIC_CHK_STATUS_RETURN(RemoveUnusedLayers(true));
1089 VP_PUBLIC_CHK_STATUS_RETURN(RemoveUnusedLayers(false));
1090
1091 for (i = 0; i < m_InputPipes.size(); ++i)
1092 {
1093 VP_PUBLIC_CHK_STATUS_RETURN(UpdateFeatures(true, i, caps));
1094 }
1095
1096 for (i = 0; i < m_OutputPipes.size(); ++i)
1097 {
1098 VP_PUBLIC_CHK_STATUS_RETURN(UpdateFeatures(false, i));
1099 }
1100
1101 UpdateSwFilterPipeType();
1102
1103 return MOS_STATUS_SUCCESS;
1104 }
1105
GetSurfaceCount(bool isInputSurface)1106 uint32_t SwFilterPipe::GetSurfaceCount(bool isInputSurface)
1107 {
1108 VP_FUNC_CALL();
1109
1110 return isInputSurface ? m_InputSurfaces.size() : m_OutputSurfaces.size();
1111 }
1112
IsAllInputPipeEmpty()1113 bool SwFilterPipe::IsAllInputPipeEmpty()
1114 {
1115 for (uint32_t i = 0; i < GetSurfaceCount(true); ++i)
1116 {
1117 SwFilterSubPipe *inputPipe = GetSwFilterSubPipe(true, i);
1118 if (inputPipe && !inputPipe->IsEmpty())
1119 {
1120 return false;
1121 }
1122 }
1123
1124 return true;
1125 }
1126
IsAllInputPipeSurfaceFeatureEmpty()1127 bool SwFilterPipe::IsAllInputPipeSurfaceFeatureEmpty()
1128 {
1129 for (uint32_t i = 0; i < GetSurfaceCount(true); ++i)
1130 {
1131 SwFilterSubPipe *inputPipe = GetSwFilterSubPipe(true, i);
1132 if (inputPipe && !inputPipe->IsSurfaceFeatureEmpty())
1133 {
1134 return false;
1135 }
1136 }
1137
1138 return true;
1139 }
1140
IsAllInputPipeSurfaceFeatureEmpty(std::vector<int> & layerIndexes)1141 bool SwFilterPipe::IsAllInputPipeSurfaceFeatureEmpty(std::vector<int> &layerIndexes)
1142 {
1143 for (uint32_t i = 0; i < layerIndexes.size(); ++i)
1144 {
1145 uint32_t executedIndex = layerIndexes[i];
1146 SwFilterSubPipe *inputPipe = GetSwFilterSubPipe(true, executedIndex);
1147 if (inputPipe && !inputPipe->IsSurfaceFeatureEmpty())
1148 {
1149 return false;
1150 }
1151 }
1152
1153 return true;
1154 }
1155
AddRTLog()1156 MOS_STATUS SwFilterPipe::AddRTLog()
1157 {
1158 VP_FUNC_CALL();
1159
1160 uint32_t i = 0;
1161 MT_LOG1(MT_VP_FEATURE_GRAPH_GET_RENDERTARGETTYPE, MT_NORMAL, MT_VP_FEATURE_GRAPH_RENDERTARGETTYPE, GetRenderTargetType())
1162 MT_LOG1(MT_VP_FEATURE_GRAPH_INPUTSWFILTER, MT_NORMAL, MT_VP_FEATURE_GRAPH_FILTER_SWFILTERPIPE_COUNT, (int64_t)m_InputPipes.size());
1163 for (i = 0; i < m_InputPipes.size(); ++i)
1164 {
1165 VP_PUBLIC_CHK_STATUS_RETURN(AddFeatureGraphRTLog(true, i));
1166 }
1167 MT_LOG1(MT_VP_FEATURE_GRAPH_OUTPUTSWFILTER, MT_NORMAL, MT_VP_FEATURE_GRAPH_FILTER_SWFILTERPIPE_COUNT, (int64_t)m_OutputPipes.size());
1168 for (i = 0; i < m_OutputPipes.size(); ++i)
1169 {
1170 VP_PUBLIC_CHK_STATUS_RETURN(AddFeatureGraphRTLog(false, i));
1171 }
1172
1173 return MOS_STATUS_SUCCESS;
1174 }
1175
AddFeatureGraphRTLog(bool isInputPipe,uint32_t pipeIndex)1176 MOS_STATUS SwFilterPipe::AddFeatureGraphRTLog(bool isInputPipe, uint32_t pipeIndex)
1177 {
1178 VP_FUNC_CALL();
1179
1180 // Always use index 0 for the pipe whose pipeIndex not being specified.
1181 auto inputPipe = m_InputPipes.size() > 0 ? (isInputPipe ? m_InputPipes[pipeIndex] : m_InputPipes[0]) : nullptr;
1182 auto outputPipe = m_OutputPipes.size() > 0 ? (isInputPipe ? m_OutputPipes[0] : m_OutputPipes[pipeIndex]) : nullptr;
1183
1184 // Input surface/pipe may be empty for some feature.
1185 if (isInputPipe)
1186 {
1187 MT_LOG7(MT_VP_FEATURE_GRAPH_INPUT_SURFACE_INFO, MT_NORMAL, MT_VP_FEATURE_GRAPH_SURFACE_WIDTH, m_InputSurfaces[pipeIndex]->osSurface->dwWidth, MT_VP_FEATURE_GRAPH_SURFACE_HEIGHT, m_InputSurfaces[pipeIndex]->osSurface->dwHeight, MT_VP_FEATURE_GRAPH_SURFACE_PITCH, m_InputSurfaces[pipeIndex]->osSurface->dwPitch, MT_VP_FEATURE_GRAPH_SURFACE_RCSRC_LEFT, m_InputSurfaces[pipeIndex]->rcSrc.left, MT_VP_FEATURE_GRAPH_SURFACE_RCSRC_TOP, m_InputSurfaces[pipeIndex]->rcSrc.top, MT_VP_FEATURE_GRAPH_SURFACE_RCSRC_RIGHT, m_InputSurfaces[pipeIndex]->rcSrc.right, MT_VP_FEATURE_GRAPH_SURFACE_RCSRC_BOTTOM, m_InputSurfaces[pipeIndex]->rcSrc.bottom);
1188 MT_LOG7(MT_VP_FEATURE_GRAPH_INPUT_SURFACE_INFO, MT_NORMAL, MT_VP_FEATURE_GRAPH_SURFACE_COLORSPACE, m_InputSurfaces[pipeIndex]->ColorSpace, MT_VP_FEATURE_GRAPH_SURFACE_FORMAT, m_InputSurfaces[pipeIndex]->osSurface->Format, MT_VP_FEATURE_GRAPH_SURFACE_RCDST_LEFT, m_InputSurfaces[pipeIndex]->rcDst.left, MT_VP_FEATURE_GRAPH_SURFACE_RCDST_TOP, m_InputSurfaces[pipeIndex]->rcDst.top, MT_VP_FEATURE_GRAPH_SURFACE_RCDST_RIGHT, m_InputSurfaces[pipeIndex]->rcDst.right, MT_VP_FEATURE_GRAPH_SURFACE_RCDST_BOTTOM, m_InputSurfaces[pipeIndex]->rcDst.bottom, MT_VP_FEATURE_GRAPH_SURFACE_ALLOCATIONHANDLE, static_cast<int64_t>(m_InputSurfaces[pipeIndex]->GetAllocationHandle(m_vpInterface.GetHwInterface()->m_osInterface)));
1189 VP_PUBLIC_NORMALMESSAGE(
1190 "Feature Graph: Input Surface: dwWidth %d, dwHeight %d, dwPitch %d, ColorSpace %d, Format %d, \
1191 rcSrc.left %d, rcSrc.top %d, rcSrc.right %d, rcSrc.bottom %d, \
1192 rcDst.left %d, rcDst.top %d, rcDst.right %d, rcDst.bottom %d, surface allocationhandle %d",
1193 m_InputSurfaces[pipeIndex]->osSurface->dwWidth,
1194 m_InputSurfaces[pipeIndex]->osSurface->dwHeight,
1195 m_InputSurfaces[pipeIndex]->osSurface->dwPitch,
1196 m_InputSurfaces[pipeIndex]->ColorSpace,
1197 m_InputSurfaces[pipeIndex]->osSurface->Format,
1198 m_InputSurfaces[pipeIndex]->rcSrc.left,
1199 m_InputSurfaces[pipeIndex]->rcSrc.top,
1200 m_InputSurfaces[pipeIndex]->rcSrc.right,
1201 m_InputSurfaces[pipeIndex]->rcSrc.bottom,
1202 m_InputSurfaces[pipeIndex]->rcDst.left,
1203 m_InputSurfaces[pipeIndex]->rcDst.top,
1204 m_InputSurfaces[pipeIndex]->rcDst.right,
1205 m_InputSurfaces[pipeIndex]->rcDst.bottom,
1206 m_InputSurfaces[pipeIndex]->GetAllocationHandle(m_vpInterface.GetHwInterface()->m_osInterface));
1207 VP_PUBLIC_CHK_STATUS_RETURN(inputPipe->AddFeatureGraphRTLog());
1208 }
1209 else
1210 {
1211 MT_LOG7(MT_VP_FEATURE_GRAPH_OUTPUT_SURFACE_INFO, MT_NORMAL, MT_VP_FEATURE_GRAPH_SURFACE_WIDTH, m_OutputSurfaces[pipeIndex]->osSurface->dwWidth, MT_VP_FEATURE_GRAPH_SURFACE_HEIGHT, m_OutputSurfaces[pipeIndex]->osSurface->dwHeight, MT_VP_FEATURE_GRAPH_SURFACE_PITCH, m_OutputSurfaces[pipeIndex]->osSurface->dwPitch, MT_VP_FEATURE_GRAPH_SURFACE_RCSRC_LEFT, m_OutputSurfaces[pipeIndex]->rcSrc.left, MT_VP_FEATURE_GRAPH_SURFACE_RCSRC_TOP, m_OutputSurfaces[pipeIndex]->rcSrc.top, MT_VP_FEATURE_GRAPH_SURFACE_RCSRC_RIGHT, m_OutputSurfaces[pipeIndex]->rcSrc.right, MT_VP_FEATURE_GRAPH_SURFACE_RCSRC_BOTTOM, m_OutputSurfaces[pipeIndex]->rcSrc.bottom);
1212 MT_LOG7(MT_VP_FEATURE_GRAPH_OUTPUT_SURFACE_INFO, MT_NORMAL, MT_VP_FEATURE_GRAPH_SURFACE_COLORSPACE, m_OutputSurfaces[pipeIndex]->ColorSpace, MT_VP_FEATURE_GRAPH_SURFACE_FORMAT, m_OutputSurfaces[pipeIndex]->osSurface->Format, MT_VP_FEATURE_GRAPH_SURFACE_RCDST_LEFT, m_OutputSurfaces[pipeIndex]->rcDst.left, MT_VP_FEATURE_GRAPH_SURFACE_RCDST_TOP, m_OutputSurfaces[pipeIndex]->rcDst.top, MT_VP_FEATURE_GRAPH_SURFACE_RCDST_RIGHT, m_OutputSurfaces[pipeIndex]->rcDst.right, MT_VP_FEATURE_GRAPH_SURFACE_RCDST_BOTTOM, m_OutputSurfaces[pipeIndex]->rcDst.bottom, MT_VP_FEATURE_GRAPH_SURFACE_ALLOCATIONHANDLE, static_cast<int64_t>(m_OutputSurfaces[pipeIndex]->GetAllocationHandle(m_vpInterface.GetHwInterface()->m_osInterface)));
1213 VP_PUBLIC_NORMALMESSAGE(
1214 "Feature Graph: Output Surface: dwWidth %d, dwHeight %d, dwPitch %d, ColorSpace %d, Format %d, \
1215 rcSrc.left %d, rcSrc.top %d, rcSrc.right %d, rcSrc.bottom %d, \
1216 rcDst.left %d, rcDst.top %d, rcDst.right %d, rcDst.bottom %d, surface allocationhandle %d",
1217 m_OutputSurfaces[pipeIndex]->osSurface->dwWidth,
1218 m_OutputSurfaces[pipeIndex]->osSurface->dwHeight,
1219 m_OutputSurfaces[pipeIndex]->osSurface->dwPitch,
1220 m_OutputSurfaces[pipeIndex]->ColorSpace,
1221 m_OutputSurfaces[pipeIndex]->osSurface->Format,
1222 m_OutputSurfaces[pipeIndex]->rcSrc.left,
1223 m_OutputSurfaces[pipeIndex]->rcSrc.top,
1224 m_OutputSurfaces[pipeIndex]->rcSrc.right,
1225 m_OutputSurfaces[pipeIndex]->rcSrc.bottom,
1226 m_OutputSurfaces[pipeIndex]->rcDst.left,
1227 m_OutputSurfaces[pipeIndex]->rcDst.top,
1228 m_OutputSurfaces[pipeIndex]->rcDst.right,
1229 m_OutputSurfaces[pipeIndex]->rcDst.bottom,
1230 m_OutputSurfaces[pipeIndex]->GetAllocationHandle(m_vpInterface.GetHwInterface()->m_osInterface));
1231 VP_PUBLIC_CHK_STATUS_RETURN(outputPipe->AddFeatureGraphRTLog());
1232 }
1233
1234 return MOS_STATUS_SUCCESS;
1235 }
1236