@@ -2311,8 +2311,7 @@ const std::map<int, std::string> AVOutputTV::pqModeMap = {
2311
2311
{PQ_MODE_STANDARD, " Standard" },
2312
2312
{PQ_MODE_VIVID, " Vivid" },
2313
2313
{PQ_MODE_ENERGY_SAVING, " EnergySaving" },
2314
- {PQ_MODE_CUSTOM, " Custom" },
2315
- {PQ_MODE_THEATER, " Movie" }
2314
+ {PQ_MODE_CUSTOM, " Custom" }
2316
2315
};
2317
2316
2318
2317
const std::map<int , std::string> AVOutputTV::videoFormatMap = {
@@ -2333,6 +2332,246 @@ const std::map<int, std::string> AVOutputTV::videoSrcMap = {
2333
2332
{VIDEO_SOURCE_TUNER, " Tuner" }
2334
2333
};
2335
2334
2335
+ template <typename T>
2336
+ std::vector<T> AVOutputTV::collectFieldFromCaps (std::function<T (const tvConfigContext_t&)> accessor) const {
2337
+ std::set<T> uniqueValues;
2338
+ if (!m_backlightCaps || m_backlightCaps->num_contexts <= 0 ) {
2339
+ LOGERR (" collectFieldFromCaps: Backlight capabilities are null or empty" );
2340
+ return {};
2341
+ }
2342
+
2343
+ for (size_t i = 0 ; i < m_backlightCaps->num_contexts ; ++i) {
2344
+ uniqueValues.insert (accessor (m_backlightCaps->contexts [i]));
2345
+ }
2346
+
2347
+ return std::vector<T>(uniqueValues.begin (), uniqueValues.end ());
2348
+ }
2349
+
2350
+ bool AVOutputTV::isGlobalParam (const JsonArray& arr) {
2351
+ return (arr.Length () == 0 ) ||
2352
+ (arr.Length () == 1 && (
2353
+ arr[0 ].String () == " Global" || arr[0 ].String () == " none" ));
2354
+ }
2355
+
2356
+
2357
+ // Modular helper functions
2358
+ std::vector<tvPQModeIndex_t> AVOutputTV::extractPQModes (const JsonObject& parameters, bool & isCurrent) {
2359
+ std::vector<tvPQModeIndex_t> pqModes;
2360
+ isCurrent = false ;
2361
+
2362
+ if (!parameters.HasLabel (" pictureMode" )) return pqModes;
2363
+
2364
+ JsonArray pqmodeArray = parameters[" pictureMode" ].Array ();
2365
+ if (isGlobalParam (pqmodeArray)) {
2366
+ pqModes = collectFieldFromCaps<tvPQModeIndex_t>([](const tvConfigContext_t& ctx) { return ctx.pq_mode ; });
2367
+ } else {
2368
+ for (uint32_t i = 0 ; i < pqmodeArray.Length (); ++i) {
2369
+ std::string modeStr = pqmodeArray[i].String ();
2370
+ if (modeStr == " Current" ) {
2371
+ isCurrent = true ;
2372
+ char picMode[PIC_MODE_NAME_MAX] = {0 };
2373
+ if (getCurrentPictureMode (picMode)) {
2374
+ for (const auto & entry : pqModeMap) {
2375
+ if (entry.second == picMode) {
2376
+ pqModes.push_back (static_cast <tvPQModeIndex_t>(entry.first ));
2377
+ }
2378
+ }
2379
+ }
2380
+ } else {
2381
+ for (const auto & entry : pqModeMap) {
2382
+ if (entry.second == modeStr) {
2383
+ pqModes.push_back (static_cast <tvPQModeIndex_t>(entry.first ));
2384
+ }
2385
+ }
2386
+ }
2387
+ }
2388
+ }
2389
+
2390
+ return pqModes;
2391
+ }
2392
+
2393
+ std::vector<tvVideoSrcType_t> AVOutputTV::extractVideoSources (const JsonObject& parameters, bool & isCurrent) {
2394
+ std::vector<tvVideoSrcType_t> sources;
2395
+ isCurrent = false ;
2396
+
2397
+ if (!parameters.HasLabel (" videoSource" )) return sources;
2398
+
2399
+ JsonArray sourceArray = parameters[" videoSource" ].Array ();
2400
+ if (isGlobalParam (sourceArray)) {
2401
+ sources = collectFieldFromCaps<tvVideoSrcType_t>([](const tvConfigContext_t& ctx) { return ctx.videoSrcType ; });
2402
+ } else {
2403
+ for (uint32_t i = 0 ; i < sourceArray.Length (); ++i) {
2404
+ std::string srcStr = sourceArray[i].String ();
2405
+ if (srcStr == " Current" ) {
2406
+ isCurrent = true ;
2407
+ tvVideoSrcType_t sourceIndex = VIDEO_SOURCE_IP;
2408
+ if (GetCurrentVideoSource (&sourceIndex) == tvERROR_NONE) {
2409
+ sources.push_back (sourceIndex);
2410
+ }
2411
+ } else {
2412
+ for (const auto & entry : videoSrcMap) {
2413
+ if (entry.second == srcStr) {
2414
+ sources.push_back (static_cast <tvVideoSrcType_t>(entry.first ));
2415
+ }
2416
+ }
2417
+ }
2418
+ }
2419
+ }
2420
+
2421
+ return sources;
2422
+ }
2423
+
2424
+ std::vector<tvVideoFormatType_t> AVOutputTV::extractVideoFormats (const JsonObject& parameters, bool & isCurrent) {
2425
+ std::vector<tvVideoFormatType_t> formats;
2426
+ isCurrent = false ;
2427
+
2428
+ if (!parameters.HasLabel (" videoFormat" )) return formats;
2429
+
2430
+ JsonArray formatArray = parameters[" videoFormat" ].Array ();
2431
+ if (isGlobalParam (formatArray)) {
2432
+ formats = collectFieldFromCaps<tvVideoFormatType_t>([](const tvConfigContext_t& ctx) { return ctx.videoFormatType ; });
2433
+ } else {
2434
+ for (uint32_t i = 0 ; i < formatArray.Length (); ++i) {
2435
+ std::string fmtStr = formatArray[i].String ();
2436
+ if (fmtStr == " Current" ) {
2437
+ isCurrent = true ;
2438
+ tvVideoFormatType_t formatIndex = VIDEO_FORMAT_NONE;
2439
+ GetCurrentVideoFormat (&formatIndex);
2440
+ if (formatIndex == VIDEO_FORMAT_NONE) {
2441
+ formatIndex = VIDEO_FORMAT_SDR;
2442
+ }
2443
+ formats.push_back (formatIndex);
2444
+ } else {
2445
+ for (const auto & entry : videoFormatMap) {
2446
+ if (entry.second == fmtStr) {
2447
+ formats.push_back (static_cast <tvVideoFormatType_t>(entry.first ));
2448
+ }
2449
+ }
2450
+ }
2451
+ }
2452
+ }
2453
+
2454
+ return formats;
2455
+ }
2456
+
2457
+
2458
+ std::vector<tvConfigContext_t> AVOutputTV::getValidContextsFromParameters (const JsonObject& parameters)
2459
+ {
2460
+ std::vector<tvConfigContext_t> validContexts;
2461
+
2462
+ if (!m_backlightCaps || m_backlightCaps->num_contexts <= 0 ) {
2463
+ LOGERR (" Backlight capabilities unavailable or empty" );
2464
+ return validContexts;
2465
+ }
2466
+
2467
+ bool pqCurrent = false , srcCurrent = false , fmtCurrent = false ;
2468
+
2469
+ std::vector<tvPQModeIndex_t> pqModes = extractPQModes (parameters, pqCurrent);
2470
+ std::vector<tvVideoSrcType_t> sources = extractVideoSources (parameters, srcCurrent);
2471
+ std::vector<tvVideoFormatType_t> formats = extractVideoFormats (parameters, fmtCurrent);
2472
+
2473
+ if (pqModes.empty () || sources.empty () || formats.empty ()) {
2474
+ LOGWARN (" One or more parameter vectors are empty: PQModes[%zu], Sources[%zu], Formats[%zu]" ,
2475
+ pqModes.size (), sources.size (), formats.size ());
2476
+ return validContexts;
2477
+ }
2478
+
2479
+ std::set<std::tuple<int , int , int >> seenContexts;
2480
+
2481
+ for (const auto & pq : pqModes) {
2482
+ for (const auto & fmt : formats) {
2483
+ for (const auto & src : sources) {
2484
+ tvConfigContext_t testCtx = { pq, fmt, src };
2485
+ for (size_t i = 0 ; i < m_backlightCaps->num_contexts ; ++i) {
2486
+ const tvConfigContext_t& available = m_backlightCaps->contexts [i];
2487
+ if (available.pq_mode == testCtx.pq_mode &&
2488
+ available.videoFormatType == testCtx.videoFormatType &&
2489
+ available.videoSrcType == testCtx.videoSrcType ) {
2490
+ std::tuple<int , int , int > key = std::make_tuple (pq, fmt, src);
2491
+ if (seenContexts.find (key) == seenContexts.end ()) {
2492
+ validContexts.push_back (testCtx);
2493
+ seenContexts.insert (key);
2494
+ }
2495
+ }
2496
+ }
2497
+ }
2498
+ }
2499
+ }
2500
+ // std::tie(...) creates a tuple of values from struct a and b.
2501
+ // The < operator for tuples performs lexicographic comparison, like dictionary order:
2502
+ // It compares the first elements;If they're equal, it compares the second;If still equal, it compares the third.
2503
+ std::sort (validContexts.begin (), validContexts.end (), [](const tvConfigContext_t& a, const tvConfigContext_t& b) {
2504
+ return std::tie (a.pq_mode , a.videoFormatType , a.videoSrcType ) <
2505
+ std::tie (b.pq_mode , b.videoFormatType , b.videoSrcType );
2506
+ });
2507
+
2508
+ #if DEBUG
2509
+ for (const auto & ctx : validContexts) {
2510
+ std::string pqStr = pqModeMap.count (ctx.pq_mode ) ? pqModeMap.at (ctx.pq_mode ) : std::to_string (ctx.pq_mode );
2511
+ std::string fmtStr = videoFormatMap.count (ctx.videoFormatType ) ? videoFormatMap.at (ctx.videoFormatType ) : std::to_string (ctx.videoFormatType );
2512
+ std::string srcStr = videoSrcMap.count (ctx.videoSrcType ) ? videoSrcMap.at (ctx.videoSrcType ) : std::to_string (ctx.videoSrcType );
2513
+ LOGINFO (" Valid Context - PQMode: %s, Format: %s, Source: %s" , pqStr.c_str (), fmtStr.c_str (), srcStr.c_str ());
2514
+ }
2515
+ #endif
2516
+
2517
+ return validContexts;
2518
+ }
2519
+
2520
+ int AVOutputTV::updateAVoutputTVParamV2 (std::string action, std::string tr181ParamName,
2521
+ const JsonObject& parameters,
2522
+ tvPQParameterIndex_t pqParamIndex, int level)
2523
+ {
2524
+ LOGINFO (" Entry: %s" , __FUNCTION__);
2525
+ int ret = 0 ;
2526
+ const bool isSet = (action == " set" );
2527
+
2528
+ std::vector<tvConfigContext_t> validContexts = getValidContextsFromParameters (parameters);
2529
+ LOGINFO (" %s: Action: %s, Param: %s, Level: %d" , __FUNCTION__, action.c_str (), tr181ParamName.c_str (), level);
2530
+
2531
+ if (validContexts.empty ()) {
2532
+ LOGWARN (" %s: No valid contexts found for parameters" , __FUNCTION__);
2533
+ return ret;
2534
+ }
2535
+
2536
+ for (const auto & ctx : validContexts) {
2537
+ paramIndex_t paramIndex {
2538
+ .sourceIndex = static_cast <uint8_t >(ctx.videoSrcType ),
2539
+ .pqmodeIndex = static_cast <uint8_t >(ctx.pq_mode ),
2540
+ .formatIndex = static_cast <uint8_t >(ctx.videoFormatType )
2541
+ };
2542
+
2543
+ if (isSet) {
2544
+ ret |= updateAVoutputTVParamToHAL (tr181ParamName, paramIndex, level, true );
2545
+ ret |= SaveBacklight (static_cast <tvVideoSrcType_t>(paramIndex.sourceIndex ),
2546
+ paramIndex.pqmodeIndex ,
2547
+ static_cast <tvVideoFormatType_t>(paramIndex.formatIndex ),
2548
+ level);
2549
+
2550
+ std::string pqStr = pqModeMap.count (ctx.pq_mode ) ? pqModeMap.at (ctx.pq_mode ) : std::to_string (ctx.pq_mode );
2551
+ std::string fmtStr = videoFormatMap.count (ctx.videoFormatType ) ? videoFormatMap.at (ctx.videoFormatType ) : std::to_string (ctx.videoFormatType );
2552
+ std::string srcStr = videoSrcMap.count (ctx.videoSrcType ) ? videoSrcMap.at (ctx.videoSrcType ) : std::to_string (ctx.videoSrcType );
2553
+
2554
+ LOGINFO (" Checking Context to SetBacklight - PQMode: %s, Format: %s, Source: %s" , pqStr.c_str (), fmtStr.c_str (), srcStr.c_str ());
2555
+
2556
+ if (isSetRequired (pqStr, srcStr, fmtStr)) {
2557
+ LOGINFO (" Proceed with SetBacklight: %d" , level);
2558
+ int setRet = SetBacklight (level);
2559
+ ret |= setRet;
2560
+
2561
+ if (setRet != tvERROR_NONE) {
2562
+ LOGERR (" SetBacklight failed: %d" , setRet);
2563
+ return ret;
2564
+ }
2565
+ } else {
2566
+ LOGINFO (" SetBacklight not required for this context." );
2567
+ }
2568
+ }
2569
+ }
2570
+
2571
+ LOGINFO (" Exit: %s, Return Value: %d" , __FUNCTION__, ret);
2572
+ return ret;
2573
+ }
2574
+
2336
2575
2337
2576
tvError_t AVOutputTV::ReadJsonFile (JsonObject& root) {
2338
2577
std::ifstream file (CAPABLITY_FILE_NAMEV2);
0 commit comments