Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

1080p video not recognized (played at 720p) #9

Closed
axlt2002 opened this issue Jan 4, 2017 · 19 comments
Closed

1080p video not recognized (played at 720p) #9

axlt2002 opened this issue Jan 4, 2017 · 19 comments

Comments

@axlt2002
Copy link

axlt2002 commented Jan 4, 2017

Hi peak3d,

I Am actually using the new version of YouTube add-on (5.3.6) that works with MPEG-DASH thanks to your inputstream.adaptive. I have already posted the following issue in the YouTube add-on thread and the author suggested me to contact you since it seems the issue is related to inputstream. Hope you can give at least a look to it (I didn't find any thread on the Kodi forum, that is why I'm writing here).

The point is simple: even if on YouTube the interested video is available in 1080p resolution, Kodi plays it at 720p. So I'm wondering where I'm making a mistake. These are the relevant settings I'm using:

YouTube addo-on
Video Quality -> 720p (this one does not have any impact; is an old parameter that is not used in case of MPEG-DASH)
Always ask for the video quality -> Disabled
Use MPEG-DASH -> Enabled

InputStream Adaptive
Min. Bandwidth -> 11000000
Max. Bandwidth -> 20000000
Max. Resolution -> 1080p
Stream Selection -> Manual (I have tried also "Auto")
Media -> All

The "guilty" video is this one and under Firefox it plays without any issue at 1080p resolution.

In order to help, you can find the log at this link. Please let me know if you need further information.

A more generic question: is there any way to "force" the use of 1080p instead of having the adaptive approach calculation based on the minimum bandwidth (4 Mbit/s as default; 11 Mbit/s in my case)? It would be like in YouTube, where you can choice manually the format.

Thanks for your attention and big effort.

@peak3d
Copy link
Contributor

peak3d commented Jan 24, 2017

Hi, from log this video is not played using mpeg/dash.
inputstream.adaptive is quite talkative, but there is nothing (except loading on kodi start)

@axlt2002
Copy link
Author

Hi peak3d,
Thanks a lot for your answer. I'm going to report back to the YouTube add-on developer. In fact it was sounding strange to me that some other videos are played at 4K.
One question on this last point...is there a way to limit the resolution to 1080p? I have set maximum resolution to 1080p, but videos that have 4K available are played at 4K.
Thanks again for your effort in this work!

@peak3d
Copy link
Contributor

peak3d commented Jan 24, 2017

Seems to be the same issue - if imputstream.adaptive / dash is used for playing the content, the limitation should work (assuming stream selection is "auto" and NOT manual).
Without inputstream.adaptive as player everything could happen (out of my scope)

(Just read above: its manual. if manual is selected, I'll ever pass all streams to kodi and kodi decides which of the streams is played. For sure I can add the limitation as well for manual (will do it in one of the next commits)

manual is more for debugging purpose, in general everythin should work well with "auto"

@axlt2002
Copy link
Author

axlt2002 commented Jan 24, 2017

Thanks for the clarification; it seems the problem is in my settings. I will try the stream selection on "auto" while playing a 4K video to check if it will be limited to 1080p.
For the "720p issue", please take a look to this thread; may be you can give some hints on that.
Keep in touch!

@axlt2002
Copy link
Author

Hello,
I had finally some time to make a trial. Well, actually I'm not able to watch this YouTube video zikMbQZe8_k at 1080p. I have tried different settings but in case of "manual" the video is played even at 4K, in case of "auto" it does not go more than 720p. Can you make a try please?
For the "720p issue" reported in the previous posts, is a question of DRM for the 1080p stream option of the same video. See the thread mentioned above.

@peak3d
Copy link
Contributor

peak3d commented Feb 8, 2017

Have you downloaded the manifest file and looked into it that it supports the 1080p?
The URL of the manifest/mpd file can be found in kodi.log after trying to play.
Can you pls attach this mpd here?

I'm currently very busy in other kodi issues and need your support for this one.

@axlt2002
Copy link
Author

Hi peak3d!
No worries...thanks for your great work you are doing for Kodi and its users!
I think that I understood why the video is played at 720p maximum. I have just noticed that my PC monitor is not Full HD, therefore inputstream.adaptive does take it into account while "deciding" the stream to be played. Trying on my tablet, that has a 1920x1200 resolution, the video finally played at 1080p.
I think that this implementation choice is for optimize the data flow; does it make sense to download a 1080p video if the screen is only 720p? Well, I think that sometimes this could be the case...A suggestion would be to add an option to inputstream such as "limit the resolution according to the screen one" or something like that.
Thanks for your great effort!

@peak3d
Copy link
Contributor

peak3d commented Feb 16, 2017

Hi @axlt2002
I'll do something like how much % screen vs media can differ.
If you type 150% then the movie can be 150% of the screen resolution.

I have currently many open issues, but have noted the requirement.
Means, this will take some time to get it in.

@pckbls
Copy link

pckbls commented Feb 16, 2017

I'm wondering if it would make sense to implement a format filter string similar to the way youtube-dl handles the format selection problem:
https://github.com/rg3/youtube-dl/blob/master/README.md#format-selection

@peak3d
Copy link
Contributor

peak3d commented Feb 16, 2017

Not really, the example you posted is for streams wich don't support adaptive bitrate switching.

inputstream.adaptive is designed for mpd / ism files wich are thought to do those things best possible automagically.

Edit: If you select Stream Selection "manual" in inputstream.adaptive settings, you can choose from all resolutions. Pls. don't post any "my video buffers" issues here if you use this option.

@pckbls
Copy link

pckbls commented Feb 16, 2017

Ah, I should have been more clear: My thought was to use such a format string to pre-filter the available representations that shall be taken into account by the actual adaptation logic. That way we could for instance:

  • limit the maximum video resolution to 1080p while the adaptation logic can still choose between 144p, 240p, 360p, 720p, whatever...
  • prefer a specific video codec such as h.264 over vp9 (might be useful for YouTube videos)

@peak3d
Copy link
Contributor

peak3d commented Feb 16, 2017

  • For detailed selection you can use manual stream selection (should only be use for debugging)
  • For limiting stream resolution I don't think fixed absolute values ("1080p") is the solution because only a few % of kodi users know what they are doing. A relative value (video can be X % bigger than screen) would fulfill most needs.
  • Prio List for codecs would make sense, good idea.

My current implementation sight is to make technical things hidden wherether it is possible.
It is not thought as a kind of mpd analyzer, inputstream.adaptive should run with the best possible result without any manual setting needed (still some work to do for this)

@koenkooi
Copy link

My use case for 4k video when using 1080p gui is s905* based systems. Running the gui at 4k seems to be too much for the GPU, but 4k decode is fine.
So I would love to have inputstream.adaptive pick a 4k stream and have kodi switch resolution to 4k, just like it does for local media.

@peak3d
Copy link
Contributor

peak3d commented Apr 3, 2017

@koenkooi Ok, I'll will add an option to ignore display res on start.
Didn't expect that kodi can switch display-res on stream start.

@vaguerant
Copy link

Apologies if this is unrelated, but I've got a Raspberry Pi 3 running Kodi on a 1080p TV. I wasn't able to get 1080p videos from YouTube with inputstream.adaptive set to "Max resolution general decoder: 1080p". With that setting, the YouTube addon would exclusively get me 720p videos. Setting stream selection to manual, I was able to choose 1080p without issue.

I was able to solve this issue by changing "Max resolution general decoder} to "Max" instead of "1080p". I now get 1080p video without fail (including on videos with 4K support; which is fine, I don't want 4K, but that's why I initially set my max to "1080p" rather than "Max"). Is this an issue with the way 1080p is determined vs. Max? It seems like I should get the 1080p streams if my maximum is set to 1080p, but I don't.

@Fludizz
Copy link

Fludizz commented Jan 5, 2019

Can confirm what @vaguerant just said. After updating to LibreELEC 8.95.2, having Inputstream configured with a resolution set to "1080p" causes all streams to play at 720p. Changing it back to "max" seems to resolve this and streams run at 1080p just fine.

Debug log with setting at "1080p" using Youtube/MPEG-DASH for playback:
https://paste.ubuntu.com/p/HW4yzF82MP/

@dagwieers
Copy link
Contributor

There was a bug in inputstream.adaptive where if you selected 720p, you would get a lower quality stream. And if you selected 1080p you would get the 720p stream. It is fixed in #259

@dagwieers
Copy link
Contributor

@axlt2002 I think we fixed this as part of #259, can you please verify? Or if no longer relevant to you, please close this issue.

@axlt2002
Copy link
Author

axlt2002 commented Jul 8, 2019

Everything is working as expected now. Thanks a lot!

@axlt2002 axlt2002 closed this as completed Jul 8, 2019
Maven85 pushed a commit to Maven85/inputstream.adaptive that referenced this issue Aug 20, 2020
Maven85 pushed a commit to Maven85/inputstream.adaptive that referenced this issue Aug 28, 2020
Maven85 pushed a commit to Maven85/inputstream.adaptive that referenced this issue Aug 31, 2020
Maven85 pushed a commit to Maven85/inputstream.adaptive that referenced this issue Sep 7, 2020
Maven85 pushed a commit to Maven85/inputstream.adaptive that referenced this issue Oct 14, 2020
Maven85 pushed a commit to Maven85/inputstream.adaptive that referenced this issue Oct 16, 2020
dobo90 added a commit to dobo90/inputstream.adaptive that referenced this issue Feb 8, 2023
* Add sleep inside AdaptiveTree.cpp to trigger the issue

From Kodi logs:

2023-02-08 18:02:11.679 T:22020    info <general>: Creating InputStream
2023-02-08 18:02:11.691 T:22020    info <general>: AddOnLog: inputstream.adaptive: [Repr. chooser] Resolution set: 4096x2304, max allowed: 8152x4436, Adjust refresh rate: 0
2023-02-08 18:02:11.989 T:22020    info <general>: AddOnLog: inputstream.adaptive: Successfully parsed manifest file (Periods: 1, Streams in first period: 2, Type: live)
2023-02-08 18:02:12.989 T:22024   error <general>: AddOnLog: inputstream.adaptive: SegmentUpdateWorker: DEBUG before RefreshLiveSegments()
2023-02-08 18:02:13.028 T:22020    info <general>: Creating Demuxer
2023-02-08 18:02:13.029 T:22020    info <general>: Opening stream: 1006 source: 256
2023-02-08 18:02:13.114 T:22024   error <general>: AddOnLog: inputstream.adaptive: SegmentUpdateWorker: DEBUG after RefreshLiveSegments()
2023-02-08 18:02:13.160 T:22020   error <general>: AddOnLog: inputstream.adaptive: DEBUG before sleep()
2023-02-08 18:02:14.114 T:22024   error <general>: AddOnLog: inputstream.adaptive: SegmentUpdateWorker: DEBUG before RefreshLiveSegments()
2023-02-08 18:02:14.135 T:22024   error <general>: AddOnLog: inputstream.adaptive: SegmentUpdateWorker: DEBUG after RefreshLiveSegments()
2023-02-08 18:02:15.135 T:22024   error <general>: AddOnLog: inputstream.adaptive: SegmentUpdateWorker: DEBUG before RefreshLiveSegments()
2023-02-08 18:02:15.155 T:22024   error <general>: AddOnLog: inputstream.adaptive: SegmentUpdateWorker: DEBUG after RefreshLiveSegments()
2023-02-08 18:02:16.155 T:22024   error <general>: AddOnLog: inputstream.adaptive: SegmentUpdateWorker: DEBUG before RefreshLiveSegments()
2023-02-08 18:02:16.161 T:22020   error <general>: AddOnLog: inputstream.adaptive: DEBUG after sleep()

Address sanitizer report:

==21945==ERROR: AddressSanitizer: heap-use-after-free on address 0x7f402596e960 at pc 0x7f40131c4944 bp 0x7f402616de50 sp 0x7f402616de40
READ of size 8 at 0x7f402596e960 thread T53
    #0 0x7f40131c4943 in adaptive::AdaptiveStream::start_stream() /home/dobo/kodi/inputstream.adaptive/src/common/AdaptiveStream.cpp:610
    xbmc#1 0x7f4013178317 in CInputStreamAdaptive::OpenStream(int) /home/dobo/kodi/inputstream.adaptive/src/main.cpp:309
    xbmc#2 0x7f4013187f07 in kodi::addon::CInstanceInputStream::ADDON_OpenStream(AddonInstance_InputStream const*, int) (/usr/lib/kodi/addons/inputstream.adaptive/inputstream.adaptive.so.20.3.2+0x387f07)
    xbmc#3 0x55abad48474b in CDVDDemuxClient::OpenStream(int) (/usr/lib/kodi/kodi.bin+0xb7c74b)
    xbmc#4 0x55abad508385 in CVideoPlayer::OpenStream(CCurrentStream&, long, int, int, bool) (/usr/lib/kodi/kodi.bin+0xc00385)
    xbmc#5 0x55abad508bba in CVideoPlayer::OpenDefaultStreams(bool) (/usr/lib/kodi/kodi.bin+0xc00bba)
    xbmc#6 0x55abad50a857 in CVideoPlayer::Prepare() (/usr/lib/kodi/kodi.bin+0xc02857)
    xbmc#7 0x55abad510d45 in CVideoPlayer::Process() (/usr/lib/kodi/kodi.bin+0xc08d45)
    xbmc#8 0x55abad758396 in CThread::Action() (/usr/lib/kodi/kodi.bin+0xe50396)
    xbmc#9 0x55abae0f0e24  (/usr/lib/kodi/kodi.bin+0x17e8e24)
    xbmc#10 0x55abad755dba  (/usr/lib/kodi/kodi.bin+0xe4ddba)
    xbmc#11 0x7f403d4d72c2 in execute_native_thread_routine /usr/src/debug/gcc/gcc/libstdc++-v3/src/c++11/thread.cc:82
    xbmc#12 0x7f403dd8cbb4  (/usr/lib/libc.so.6+0x85bb4)
    xbmc#13 0x7f403de0ed8f  (/usr/lib/libc.so.6+0x107d8f)

0x7f402596e960 is located 303456 bytes inside of 303840-byte region [0x7f4025924800,0x7f402596eae0)
freed by thread T57 here:
    #0 0x7f403fac178a in operator delete(void*, unsigned long) /usr/src/debug/gcc/gcc/libsanitizer/asan/asan_new_delete.cpp:164
    xbmc#1 0x7f40131de17d in std::__new_allocator<adaptive::AdaptiveTree::Segment>::deallocate(adaptive::AdaptiveTree::Segment*, unsigned long) /usr/include/c++/12.2.1/bits/new_allocator.h:158
    xbmc#2 0x7f40131d974a in std::allocator_traits<std::allocator<adaptive::AdaptiveTree::Segment> >::deallocate(std::allocator<adaptive::AdaptiveTree::Segment>&, adaptive::AdaptiveTree::Segment*, unsigned long) /usr/include/c++/12.2.1/bits/alloc_traits.h:496
    xbmc#3 0x7f40131d33cb in std::_Vector_base<adaptive::AdaptiveTree::Segment, std::allocator<adaptive::AdaptiveTree::Segment> >::_M_deallocate(adaptive::AdaptiveTree::Segment*, unsigned long) /usr/include/c++/12.2.1/bits/stl_vector.h:387
    xbmc#4 0x7f40131edabd in std::_Vector_base<adaptive::AdaptiveTree::Segment, std::allocator<adaptive::AdaptiveTree::Segment> >::~_Vector_base() /usr/include/c++/12.2.1/bits/stl_vector.h:366
    xbmc#5 0x7f40131edb57 in std::vector<adaptive::AdaptiveTree::Segment, std::allocator<adaptive::AdaptiveTree::Segment> >::~vector() /usr/include/c++/12.2.1/bits/stl_vector.h:733
    xbmc#6 0x7f40131ea67f in adaptive::SPINCACHE<adaptive::AdaptiveTree::Segment>::~SPINCACHE() /home/dobo/kodi/inputstream.adaptive/src/common/AdaptiveTree.h:44
    xbmc#7 0x7f40131eae13 in adaptive::AdaptiveTree::Representation::~Representation() /home/dobo/kodi/inputstream.adaptive/src/common/AdaptiveTree.h:208
    xbmc#8 0x7f40131eb5c2 in adaptive::AdaptiveTree::AdaptationSet::~AdaptationSet() /home/dobo/kodi/inputstream.adaptive/src/parser/../common/AdaptiveTree.h:326
    xbmc#9 0x7f40131ecef6 in adaptive::AdaptiveTree::Period::~Period() /home/dobo/kodi/inputstream.adaptive/src/parser/../common/AdaptiveTree.h:462
    xbmc#10 0x7f40131e19ef in adaptive::AdaptiveTree::~AdaptiveTree() /home/dobo/kodi/inputstream.adaptive/src/common/AdaptiveTree.cpp:92
    xbmc#11 0x7f401323f6a4 in adaptive::DASHTree::~DASHTree() /home/dobo/kodi/inputstream.adaptive/src/parser/DASHTree.h:16
    xbmc#12 0x7f401323f6bf in adaptive::DASHTree::~DASHTree() /home/dobo/kodi/inputstream.adaptive/src/parser/DASHTree.h:16
    xbmc#13 0x7f401323f73c in std::default_delete<adaptive::DASHTree>::operator()(adaptive::DASHTree*) const /usr/include/c++/12.2.1/bits/unique_ptr.h:95
    xbmc#14 0x7f401323c926 in std::unique_ptr<adaptive::DASHTree, std::default_delete<adaptive::DASHTree> >::~unique_ptr() /usr/include/c++/12.2.1/bits/unique_ptr.h:396
    xbmc#15 0x7f4013237aa8 in adaptive::DASHTree::RefreshLiveSegments() /home/dobo/kodi/inputstream.adaptive/src/parser/DASHTree.cpp:1962
    xbmc#16 0x7f40131e7842 in adaptive::AdaptiveTree::SegmentUpdateWorker() /home/dobo/kodi/inputstream.adaptive/src/common/AdaptiveTree.cpp:431
    xbmc#17 0x7f4013208eea in void std::__invoke_impl<void, void (adaptive::AdaptiveTree::*)(), adaptive::AdaptiveTree*>(std::__invoke_memfun_deref, void (adaptive::AdaptiveTree::*&&)(), adaptive::AdaptiveTree*&&) /usr/include/c++/12.2.1/bits/invoke.h:74
    xbmc#18 0x7f4013208d56 in std::__invoke_result<void (adaptive::AdaptiveTree::*)(), adaptive::AdaptiveTree*>::type std::__invoke<void (adaptive::AdaptiveTree::*)(), adaptive::AdaptiveTree*>(void (adaptive::AdaptiveTree::*&&)(), adaptive::AdaptiveTree*&&) /usr/include/c++/12.2.1/bits/invoke.h:96
    xbmc#19 0x7f4013208cc6 in void std::thread::_Invoker<std::tuple<void (adaptive::AdaptiveTree::*)(), adaptive::AdaptiveTree*> >::_M_invoke<0ul, 1ul>(std::_Index_tuple<0ul, 1ul>) /usr/include/c++/12.2.1/bits/std_thread.h:258
    xbmc#20 0x7f4013208c7f in std::thread::_Invoker<std::tuple<void (adaptive::AdaptiveTree::*)(), adaptive::AdaptiveTree*> >::operator()() /usr/include/c++/12.2.1/bits/std_thread.h:265
    xbmc#21 0x7f4013208c63 in std::thread::_State_impl<std::thread::_Invoker<std::tuple<void (adaptive::AdaptiveTree::*)(), adaptive::AdaptiveTree*> > >::_M_run() /usr/include/c++/12.2.1/bits/std_thread.h:210
    xbmc#22 0x7f403d4d72c2 in execute_native_thread_routine /usr/src/debug/gcc/gcc/libstdc++-v3/src/c++11/thread.cc:82

previously allocated by thread T53 here:
    #0 0x7f403fac0672 in operator new(unsigned long) /usr/src/debug/gcc/gcc/libsanitizer/asan/asan_new_delete.cpp:95
    xbmc#1 0x7f40131deab1 in std::__new_allocator<adaptive::AdaptiveTree::Segment>::allocate(unsigned long, void const*) /usr/include/c++/12.2.1/bits/new_allocator.h:137
    xbmc#2 0x7f40131db727 in std::allocator_traits<std::allocator<adaptive::AdaptiveTree::Segment> >::allocate(std::allocator<adaptive::AdaptiveTree::Segment>&, unsigned long) /usr/include/c++/12.2.1/bits/alloc_traits.h:464
    xbmc#3 0x7f40131d5b81 in std::_Vector_base<adaptive::AdaptiveTree::Segment, std::allocator<adaptive::AdaptiveTree::Segment> >::_M_allocate(unsigned long) /usr/include/c++/12.2.1/bits/stl_vector.h:378
    xbmc#4 0x7f40131d1308 in std::vector<adaptive::AdaptiveTree::Segment, std::allocator<adaptive::AdaptiveTree::Segment> >::reserve(unsigned long) /usr/include/c++/12.2.1/bits/vector.tcc:79
    xbmc#5 0x7f401322dd61 in end /home/dobo/kodi/inputstream.adaptive/src/parser/DASHTree.cpp:1253
    xbmc#6 0x7f403c4d8263  (/usr/lib/libexpat.so.1+0xd263)

Thread T53 created by T0 here:
    #0 0x7f403fa64207 in __interceptor_pthread_create /usr/src/debug/gcc/gcc/libsanitizer/asan/asan_interceptors.cpp:207
    xbmc#1 0x7f403d4d73a9 in __gthread_create /usr/src/debug/gcc/gcc-build/x86_64-pc-linux-gnu/libstdc++-v3/include/x86_64-pc-linux-gnu/bits/gthr-default.h:663
    xbmc#2 0x7f403d4d73a9 in std::thread::_M_start_thread(std::unique_ptr<std::thread::_State, std::default_delete<std::thread::_State> >, void (*)()) /usr/src/debug/gcc/gcc/libstdc++-v3/src/c++11/thread.cc:147

Thread T57 created by T53 here:
    #0 0x7f403fa64207 in __interceptor_pthread_create /usr/src/debug/gcc/gcc/libsanitizer/asan/asan_interceptors.cpp:207
    xbmc#1 0x7f403d4d73a9 in __gthread_create /usr/src/debug/gcc/gcc-build/x86_64-pc-linux-gnu/libstdc++-v3/include/x86_64-pc-linux-gnu/bits/gthr-default.h:663
    xbmc#2 0x7f403d4d73a9 in std::thread::_M_start_thread(std::unique_ptr<std::thread::_State, std::default_delete<std::thread::_State> >, void (*)()) /usr/src/debug/gcc/gcc/libstdc++-v3/src/c++11/thread.cc:147
    xbmc#3 0x7f40131e751e in adaptive::AdaptiveTree::StartUpdateThread() /home/dobo/kodi/inputstream.adaptive/src/common/AdaptiveTree.cpp:418
    xbmc#4 0x7f401323398d in adaptive::DASHTree::open(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::map<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::less<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >) /home/dobo/kodi/inputstream.adaptive/src/parser/DASHTree.cpp:1639
    xbmc#5 0x7f401328c8ed in SESSION::CSession::Initialize() /home/dobo/kodi/inputstream.adaptive/src/Session.cpp:248
    xbmc#6 0x7f4013175f30 in CInputStreamAdaptive::Open(kodi::addon::InputstreamProperty const&) /home/dobo/kodi/inputstream.adaptive/src/main.cpp:86
    xbmc#7 0x7f40131871d5 in kodi::addon::CInstanceInputStream::ADDON_Open(AddonInstance_InputStream const*, INPUTSTREAM_PROPERTY*) (/usr/lib/kodi/addons/inputstream.adaptive/inputstream.adaptive.so.20.3.2+0x3871d5)
    xbmc#8 0x55abad46eddc in CInputStreamAddon::Open() (/usr/lib/kodi/kodi.bin+0xb66ddc)

SUMMARY: AddressSanitizer: heap-use-after-free /home/dobo/kodi/inputstream.adaptive/src/common/AdaptiveStream.cpp:610 in adaptive::AdaptiveStream::start_stream()
Shadow bytes around the buggy address:
  0x0fe884b25cd0: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
  0x0fe884b25ce0: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
  0x0fe884b25cf0: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
  0x0fe884b25d00: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
  0x0fe884b25d10: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
=>0x0fe884b25d20: fd fd fd fd fd fd fd fd fd fd fd fd[fd]fd fd fd
  0x0fe884b25d30: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
  0x0fe884b25d40: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
  0x0fe884b25d50: fd fd fd fd fd fd fd fd fd fd fd fd fa fa fa fa
  0x0fe884b25d60: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0fe884b25d70: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
Shadow byte legend (one shadow byte represents 8 application bytes):
  Addressable:           00
  Partially addressable: 01 02 03 04 05 06 07
  Heap left redzone:       fa
  Freed heap region:       fd
  Stack left redzone:      f1
  Stack mid redzone:       f2
  Stack right redzone:     f3
  Stack after return:      f5
  Stack use after scope:   f8
  Global redzone:          f9
  Global init order:       f6
  Poisoned by user:        f7
  Container overflow:      fc
  Array cookie:            ac
  Intra object redzone:    bb
  ASan internal:           fe
  Left alloca redzone:     ca
  Right alloca redzone:    cb
==21945==ABORTING
dobo90 pushed a commit to dobo90/inputstream.adaptive that referenced this issue Feb 14, 2023
…hile CloseSession is active to avoid endless loop.

Sometimes when stopping a playback Kodi crashes with a following backtrace:

    (__m=<optimized out>, this=<optimized out>)
    at /usr/include/c++/12.1.0/bits/atomic_base.h:486
        __b = <optimized out>
    at /usr/include/c++/12.1.0/atomic:87
    (adp=std::shared_ptr<media::CdmAdapter> (use count 1, weak count 1) = {...}, delay=<optimized out>, context=<optimized out>)
    at /usr/src/debug/kodi-addon-inputstream-adaptive/inputstream.adaptive-20.3.3-Nexus/wvdecrypter/cdm/media/cdm/cdm_adapter.cc:81
    at /usr/include/c++/12.1.0/bits/invoke.h:96, unsigned long long, void*), std::shared_ptr<media::CdmAdapter>, long long, void*> >::_M_invoke<0u, 1u, 2u, 3u>(std::_Index_tuple<0u, 1u, 2u, 3u>)
    (this=<optimized out>) at /usr/include/c++/12.1.0/bits/std_thread.h:252
    at /usr/include/c++/12.1.0/bits/std_thread.h:259
    at /usr/include/c++/12.1.0/bits/std_thread.h:210
    at /usr/src/debug/gcc/libstdc++-v3/src/c++11/thread.cc:82
        ret = <optimized out>
        pd = 0x85cf9080
        unwind_buf = {cancel_jmp_buf = {{jmp_buf = {857629366, 66004830, -2049994624, -2008033272, -2008033282, 338, -2008033281, 8387456, -2058383360, -2049995908, 1920, 1080, 3840, 2160, 0, 10000000, -1431355392, 1107558643, 0 <repeats 46 times>}, mask_was_saved = 0}}, priv = {pad = {0x0, 0x0, 0x0, 0x0}, data = {prev = 0x0, cleanup = 0x0, canceltype = 0}}}
        not_first_call = <optimized out>
        robust = <optimized out>

After searching in the github history it came out that there was a
similar issue adressed in xbmc#728.

For some reason that piece of code got removed in
xbmc@8889fe9
(in pull request xbmc#883).

The stack trace is from the Raspberry Pi 4 machine. But I can also reproduce the issue
on my x86_64 Linux machine by adding a 1s sleep in the beginning of CdmAdapter::SetTimer.

In order to reproduce it is necessary to quickly play/stop streams.
Script attached at the end of the commit message can be used to ease the reproduction.
In my environment running the script for 1-3 minutes makes Kodi crash.
Although the root cause described in xbmc#729
was a busy loop. Right now address sanitizer reports:
```
AddressSanitizer:DEADLYSIGNAL
=================================================================
==108079==ERROR: AddressSanitizer: SEGV on unknown address 0x7f6e314f7d4a (pc 0x7f6e314f7d4a bp 0x7f6e263fd830 sp 0x7f6e263fd720 T464)
==108079==The signal is caused by a READ memory access.
==108079==Hint: PC is at a non-executable region. Maybe a wild jump?
    #0 0x7f6e314f7d4a  (<unknown module>)
    xbmc#1 0x7f6e3151c066  (<unknown module>)
    xbmc#2 0x7f6e31526947  (<unknown module>)
    xbmc#3 0x7f6e31526729  (<unknown module>)
    xbmc#4 0x7f6e31526620  (<unknown module>)
    xbmc#5 0x7f6e315265a1  (<unknown module>)
    xbmc#6 0x7f6e31526585  (<unknown module>)
    xbmc#7 0x7f6e46ed72c2 in execute_native_thread_routine /usr/src/debug/gcc/gcc/libstdc++-v3/src/c++11/thread.cc:82

AddressSanitizer can not provide additional info.
SUMMARY: AddressSanitizer: SEGV (<unknown module>)
Thread T464 created by T51 here:
    #0 0x7f6e49464207 in __interceptor_pthread_create /usr/src/debug/gcc/gcc/libsanitizer/asan/asan_interceptors.cpp:207
    xbmc#1 0x7f6e46ed73a9 in __gthread_create /usr/src/debug/gcc/gcc-build/x86_64-pc-linux-gnu/libstdc++-v3/include/x86_64-pc-linux-gnu/bits/gthr-default.h:663
    xbmc#2 0x7f6e46ed73a9 in std::thread::_M_start_thread(std::unique_ptr<std::thread::_State, std::default_delete<std::thread::_State> >, void (*)()) /usr/src/debug/gcc/gcc/libstdc++-v3/src/c++11/thread.cc:147
    xbmc#3 0x7f6e31522028  (<unknown module>)
    xbmc#4 0x7f6e27569d40  (/home/dobo/.kodi/cdm/libwidevinecdm.so+0x969d40)
    xbmc#5 0x7f6e2757e7fc  (/home/dobo/.kodi/cdm/libwidevinecdm.so+0x97e7fc)
    xbmc#6 0x7f6e27569c36  (/home/dobo/.kodi/cdm/libwidevinecdm.so+0x969c36)
    xbmc#7 0x7f6e3151fb28  (<unknown module>)
    xbmc#8 0x7f6e3151c0b1  (<unknown module>)
    xbmc#9 0x7f6e31526947  (<unknown module>)
    xbmc#10 0x7f6e31526729  (<unknown module>)
    xbmc#11 0x7f6e31526620  (<unknown module>)
    xbmc#12 0x7f6e315265a1  (<unknown module>)
    xbmc#13 0x7f6e31526585  (<unknown module>)
    xbmc#14 0x7f6e46ed72c2 in execute_native_thread_routine /usr/src/debug/gcc/gcc/libstdc++-v3/src/c++11/thread.cc:82

Thread T51 created by T45 here:
    #0 0x7f6e49464207 in __interceptor_pthread_create /usr/src/debug/gcc/gcc/libsanitizer/asan/asan_interceptors.cpp:207
    xbmc#1 0x7f6e46ed73a9 in __gthread_create /usr/src/debug/gcc/gcc-build/x86_64-pc-linux-gnu/libstdc++-v3/include/x86_64-pc-linux-gnu/bits/gthr-default.h:663
    xbmc#2 0x7f6e46ed73a9 in std::thread::_M_start_thread(std::unique_ptr<std::thread::_State, std::default_delete<std::thread::_State> >, void (*)()) /usr/src/debug/gcc/gcc/libstdc++-v3/src/c++11/thread.cc:147
    xbmc#3 0x7f6e31522028  (<unknown module>)
    xbmc#4 0x7f6e27569d40  (/home/dobo/.kodi/cdm/libwidevinecdm.so+0x969d40)
    xbmc#5 0x7f6e2757e7fc  (/home/dobo/.kodi/cdm/libwidevinecdm.so+0x97e7fc)
    xbmc#6 0x7f6e2757e70e  (/home/dobo/.kodi/cdm/libwidevinecdm.so+0x97e70e)
    xbmc#7 0x7f6e274e4ecc  (/home/dobo/.kodi/cdm/libwidevinecdm.so+0x8e4ecc)
    xbmc#8 0x7f6e3151f280  (<unknown module>)
    xbmc#9 0x7f6e314e9ea1  (<unknown module>)
    xbmc#10 0x7f6e314e49bb  (<unknown module>)
    xbmc#11 0x7f6e314f45ce  (<unknown module>)
    xbmc#12 0x7f6e2889228f in SESSION::CSession::InitializeDRM(bool) /home/dobo/kodi/inputstream.adaptive/src/Session.cpp:643
    xbmc#13 0x7f6e28893279 in SESSION::CSession::InitializePeriod(bool) /home/dobo/kodi/inputstream.adaptive/src/Session.cpp:723
    xbmc#14 0x7f6e2888e36d in SESSION::CSession::Initialize() /home/dobo/kodi/inputstream.adaptive/src/Session.cpp:266
    xbmc#15 0x7f6e28775f4c in CInputStreamAdaptive::Open(kodi::addon::InputstreamProperty const&) /home/dobo/kodi/inputstream.adaptive/src/main.cpp:101
    xbmc#16 0x7f6e287871a1 in kodi::addon::CInstanceInputStream::ADDON_Open(AddonInstance_InputStream const*, INPUTSTREAM_PROPERTY*) (/usr/lib/kodi/addons/inputstream.adaptive/inputstream.adaptive.so.20.3.2+0x3871a1)
    xbmc#17 0x55c2811f4ddc in CInputStreamAddon::Open() (/usr/lib/kodi/kodi.bin+0xb66ddc)

Thread T45 created by T0 here:
    #0 0x7f6e49464207 in __interceptor_pthread_create /usr/src/debug/gcc/gcc/libsanitizer/asan/asan_interceptors.cpp:207
    xbmc#1 0x7f6e46ed73a9 in __gthread_create /usr/src/debug/gcc/gcc-build/x86_64-pc-linux-gnu/libstdc++-v3/include/x86_64-pc-linux-gnu/bits/gthr-default.h:663
    xbmc#2 0x7f6e46ed73a9 in std::thread::_M_start_thread(std::unique_ptr<std::thread::_State, std::default_delete<std::thread::_State> >, void (*)()) /usr/src/debug/gcc/gcc/libstdc++-v3/src/c++11/thread.cc:147
```

The root cause of the crash is unknown as it comes directly from
libwidevine library. But it crashes when we call cdm->TimerExpired when
the session is closed. After applying mentioned commit I'm not able
to reproduce the crash anymore.

Script to reproduce the issue:
```
set -x

URI='Change it to some uri to play'

while true; do
  curl -s "http://kodi:kodi@127.0.0.1:8080/jsonrpc" -H 'Content-Type: application/json' --data "{\"jsonrpc\":\"2.0\",\"method\":\"Player.Open\",\"params\":{\"item\":{\"file\":\"$URI\"}}}"
  sleep $[ ($RANDOM % 70 + 30) / 10.0 ]

  curl -s "http://kodi:kodi@127.0.0.1:8080/jsonrpc" -H 'Content-Type: application/json' --data '{"jsonrpc":"2.0","method":"Player.Stop","params":{"playerid":1}}'
  sleep 1
done
```
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

7 participants