@@ -68,6 +68,8 @@ namespace adaptive
68
68
69
69
void AdaptiveTree::PostOpen (const UTILS::PROPERTIES::KodiProperties& kodiProps)
70
70
{
71
+ FixStreamsFlags (kodiProps);
72
+
71
73
// A manifest can provide live delay value, if not so we use our default
72
74
// value of 16 secs, this is needed to ensure an appropriate playback,
73
75
// an add-on can override the delay to try fix edge use cases
@@ -374,4 +376,148 @@ namespace adaptive
374
376
m_cvWait.notify_all ();
375
377
}
376
378
379
+ void AdaptiveTree::FixStreamsFlags (const UTILS::PROPERTIES::KodiProperties& kodiProps)
380
+ {
381
+ // Add-ons can override subtitles "default" flag to streams
382
+ if (!kodiProps.m_subtitleLangDefault .empty ())
383
+ {
384
+ for (auto & period : m_periods)
385
+ {
386
+ for (auto & adpSet : period->GetAdaptationSets ())
387
+ {
388
+ if (adpSet->GetStreamType () == StreamType::SUBTITLE)
389
+ {
390
+ adpSet->SetIsDefault (
391
+ STRING::CompareNoCase (adpSet->GetLanguage (), kodiProps.m_subtitleLangDefault ));
392
+ }
393
+ }
394
+ }
395
+ }
396
+
397
+ // Add-ons can override audio "original" flag to streams
398
+ if (!kodiProps.m_audioLangOriginal .empty ())
399
+ {
400
+ for (auto & period : m_periods)
401
+ {
402
+ for (auto & adpSet : period->GetAdaptationSets ())
403
+ {
404
+ if (adpSet->GetStreamType () == StreamType::AUDIO)
405
+ {
406
+ adpSet->SetIsOriginal (
407
+ STRING::CompareNoCase (adpSet->GetLanguage (), kodiProps.m_audioLangOriginal ));
408
+ }
409
+ }
410
+ }
411
+ }
412
+
413
+ // Audio streams "default" flag customization / workaround
414
+
415
+ // Manifest of video services dont always set appropriately the default stream flag and also
416
+ // the manifest "default" stream flag dont have always the same meaning of Kodi track "default" flag,
417
+ // this can lead to wrong audio track selected when playback start.
418
+ // A good example is when "Media default" Kodi audio setting is set, where kodi expects just
419
+ // a single track with the default flag.
420
+ // Another problem is when video services provide multiple audio streams with same language code
421
+ // but differents channels, most of the times we can have 1 stereo and 1 multichannels
422
+ // stream with same language code, rarely there are multi-codecs with same channels,
423
+ // but we simplify by ignoring codec types.
424
+
425
+ // To allow Kodi VP to do a better track auto-selection we need:
426
+ // - Set default flag to a single track only
427
+ // - Set default flag to stereo or multichannels track, not both
428
+ // to do this its needed that an addon specify what to do because C++ interface dont provide
429
+ // access to kodi language settings where python can do it, then we cant automatize it.
430
+ const std::string langCodeDef = kodiProps.m_audioLangDefault ;
431
+ const std::string langCodeOrig = kodiProps.m_audioLangOriginal ;
432
+
433
+ if (!langCodeDef.empty () || !langCodeOrig.empty ())
434
+ {
435
+ bool isDefaultStereo = kodiProps.m_audioPrefStereo ; // add-on based setting
436
+
437
+ for (auto & period : m_periods)
438
+ {
439
+ auto & adpSets = period->GetAdaptationSets ();
440
+ auto itAudioStream = adpSets.cend ();
441
+
442
+ // Try give priority to "impaired" streams
443
+ if (kodiProps.m_audioPrefType == " impaired" )
444
+ {
445
+ if (isDefaultStereo)
446
+ {
447
+ itAudioStream = CAdaptationSet::FindAudioAdpSet (adpSets, langCodeDef, true , true );
448
+ if (itAudioStream == adpSets.cend ()) // No stereo stream, find multichannels
449
+ itAudioStream = CAdaptationSet::FindAudioAdpSet (adpSets, langCodeDef, false , true );
450
+ }
451
+ else
452
+ {
453
+ itAudioStream = CAdaptationSet::FindAudioAdpSet (adpSets, langCodeDef, false , true );
454
+ if (itAudioStream == adpSets.cend ()) // No multichannels stream, find stereo
455
+ itAudioStream = CAdaptationSet::FindAudioAdpSet (adpSets, langCodeDef, true , true );
456
+ }
457
+
458
+ // No stream found, try find a "impaired" stream with the "original" language code
459
+ if (itAudioStream == adpSets.cend () && !langCodeOrig.empty ())
460
+ {
461
+ if (isDefaultStereo)
462
+ {
463
+ itAudioStream = CAdaptationSet::FindAudioAdpSet (adpSets, langCodeOrig, true , true );
464
+ if (itAudioStream == adpSets.cend ()) // No stereo stream, find multichannels
465
+ itAudioStream = CAdaptationSet::FindAudioAdpSet (adpSets, langCodeOrig, false , true );
466
+ }
467
+ else
468
+ {
469
+ itAudioStream = CAdaptationSet::FindAudioAdpSet (adpSets, langCodeOrig, false , true );
470
+ if (itAudioStream == adpSets.cend ()) // No multichannels stream, find stereo
471
+ itAudioStream = CAdaptationSet::FindAudioAdpSet (adpSets, langCodeOrig, true , true );
472
+ }
473
+ }
474
+ }
475
+
476
+ // Try find a stream with specified lang code
477
+ if (kodiProps.m_audioPrefType != " original" && itAudioStream == adpSets.cend () &&
478
+ !langCodeDef.empty ())
479
+ {
480
+ if (isDefaultStereo)
481
+ {
482
+ itAudioStream = CAdaptationSet::FindAudioAdpSet (adpSets, langCodeDef, true );
483
+ if (itAudioStream == adpSets.cend ()) // No stereo stream, find multichannels
484
+ itAudioStream = CAdaptationSet::FindAudioAdpSet (adpSets, langCodeDef, false );
485
+ }
486
+ else
487
+ {
488
+ itAudioStream = CAdaptationSet::FindAudioAdpSet (adpSets, langCodeDef, false );
489
+ if (itAudioStream == adpSets.cend ()) // No multichannels stream, find stereo
490
+ itAudioStream = CAdaptationSet::FindAudioAdpSet (adpSets, langCodeDef, true );
491
+ }
492
+ }
493
+
494
+ // No stream found, try find a stream with the "original" language code
495
+ if (itAudioStream == adpSets.cend () && !langCodeOrig.empty ())
496
+ {
497
+ if (isDefaultStereo)
498
+ {
499
+ itAudioStream = CAdaptationSet::FindAudioAdpSet (adpSets, langCodeOrig, true );
500
+ if (itAudioStream == adpSets.cend ()) // No stereo stream, find multichannels
501
+ itAudioStream = CAdaptationSet::FindAudioAdpSet (adpSets, langCodeOrig, false );
502
+ }
503
+ else
504
+ {
505
+ itAudioStream = CAdaptationSet::FindAudioAdpSet (adpSets, langCodeOrig, false );
506
+ if (itAudioStream == adpSets.cend ()) // No multichannels stream, find stereo
507
+ itAudioStream = CAdaptationSet::FindAudioAdpSet (adpSets, langCodeOrig, true );
508
+ }
509
+ }
510
+
511
+ // Update "default" flags
512
+ if (itAudioStream != adpSets.cend ())
513
+ {
514
+ for (auto & adpSet : adpSets)
515
+ {
516
+ adpSet->SetIsDefault (adpSet.get () == itAudioStream->get ());
517
+ }
518
+ }
519
+ }
520
+ }
521
+ }
522
+
377
523
} // namespace adaptive
0 commit comments