Win ISO Buffering Help!
#1
All,

I've tried everything I can think of and Kodi refuses to buffer anything that is in ISO format.

This is the latest settings I have, but I've tried many other configurations.

<advancedsettings>
<network>
<buffermode>1</buffermode>
<cachemembuffersize>0</cachemembuffersize>
<readbufferfactor>100</readbufferfactor>
</network>
</advancedsettings>

I recently upgraded to the latest beta 16.0.

I press "o" during playback and forward is always zero for ISOs.

How have I force Kodi to buffer my ISOs?
Reply
#2
I have been looking into this a bit. I dont think the code will load up ISO files with caching enabled.

I hacked it a bit to force it to happen. But it is not a very clean fix and does not seem to be right.

In udf25.cpp in the Open(cosnt char *isofile) method there is a call to CFile Open

The line
if(!m_fp->Open(isofile))

It passes in the default caching status (default parameter). Which is 0 which is the same as no caching. I forced it to READ_CACHED but then that would totally ignore the buffermode setings.

It looks like the original intent of the code was to have CFile decide the caching or the caching code to do it (not really clear). But it seems to not do it for ISO files at all. It looks like it will for pretty much anything that streams off the internet. But nothing else. I have tested that it does not even spin up the caching code with ISOs.
Reply
#3
(2015-11-21, 23:00)lharms Wrote: I have been looking into this a bit. I dont think the code will load up ISO files with caching enabled.

I hacked it a bit to force it to happen. But it is not a very clean fix and does not seem to be right.

In udf25.cpp in the Open(cosnt char *isofile) method there is a call to CFile Open

The line
if(!m_fp->Open(isofile))

It passes in the default caching status (default parameter). Which is 0 which is the same as no caching. I forced it to READ_CACHED but then that would totally ignore the buffermode setings.

It looks like the original intent of the code was to have CFile decide the caching or the caching code to do it (not really clear). But it seems to not do it for ISO files at all. It looks like it will for pretty much anything that streams off the internet. But nothing else. I have tested that it does not even spin up the caching code with ISOs.

Thanks for the feedback.

I hadn't setup the build environment yet, so not sure if how much time I wanted to try debugging this. The part I wasn't sure from your reply is if the hack you did actually got it to start buffering? The last sentence makes it sound like your quick fix did not work and the solution isn't a simple tweak but a decent rewrite?
Reply
#4
Quick update.

Looks like this may be the key here.
I haven't done much testing yet, but when I pause the video, it looks like it's still buffering the video based on network traffic.
The downside is that the buffering doesn't seem to show up in the stats so I can't truly confirm it's working.

Quote:bool CDVDInputStreamFile::Open(const char* strFile, const std:Confusedtring& content, bool contentLookup)
{
if (!CDVDInputStream::Open(strFile, content, contentLookup))
return false;

m_pFile = new CFile();
if (!m_pFile)
return false;

unsigned int flags = READ_TRUNCATED | READ_BITRATE | READ_CHUNKED;

// If this file is audio and/or video (= not a subtitle) flag to caller
if (!CFileItem(strFile).IsSubtitle())
flags |= READ_AUDIO_VIDEO;

/*
* There are 4 buffer modes available (configurable in as.xml)
* 0) Buffer all internet filesystems (like 2 but additionally also ftp, webdav, etc.) (default)
* 1) Buffer all filesystems (including local)
* 2) Only buffer true internet filesystems (streams) (http, etc.)
* 3) No buffer
*/
// if (!URIUtils::IsOnDVD(strFile) && !URIUtils::IsBluray(strFile)) // Never cache these
{
if (g_advancedSettings.m_networkBufferMode == 0 || g_advancedSettings.m_networkBufferMode == 2)
{
if (URIUtils::IsInternetStream(CURL(strFile), (g_advancedSettings.m_networkBufferMode == 0) ) )
flags |= READ_CACHED;
}
else if (g_advancedSettings.m_networkBufferMode == 1)
{
flags |= READ_CACHED; // In buffer mode 1 force cache for (almost) all files
}

Quote:BD_FILE_H * DllLibbluray::file_open(const char* filename, const char *mode)
{
BD_FILE_H *file = new BD_FILE_H;

file->close = file_close;
file->seek = file_seek;
file->read = file_read;
file->write = file_write;
file->tell = file_tell;
file->eof = file_eof;

CFile* fp = new CFile();

unsigned int flags = 0;
if (g_advancedSettings.m_networkBufferMode == 0 || g_advancedSettings.m_networkBufferMode == 2)
{
if (URIUtils::IsInternetStream(CURL(strFile), (g_advancedSettings.m_networkBufferMode == 0) ) )
flags |= READ_CACHED;
}
else if (g_advancedSettings.m_networkBufferMode == 1)
{
flags |= READ_CACHED; // In buffer mode 1 force cache for (almost) all files
}

if(fp->Open(filename, flags))
{
file->internal = (void*)fp;
return file;
}
Reply
#5
Yeah I saw that code too (CDVDInputStreamFile::Open). However, it does not even go down that path when I run it with a bluray or dvd ISO (breakpoint never hit). I have not tried it but I think that path is only for physical DVDs.

Sorry my comment was not clear. But my hack did work. But it also makes it *always* cache. Which is not the intent. My feeling is CFile:Open needs to change to make a better decision. Sort of like you did. Or at a minimum the udf25:Open should make that decision (that way you hit both the DVD and bluray case).

I was tempted to do what you are saying. But that seems too high up the call stack. It is making the upper API calls make the decision when it really should not be up to them at all?

The problem is if you put it too low level then you basically end up double caching things. The way you have would work for the individual files inside the ISO but not the whole ISO? That may be the right way. Just seems like an interface is wrong somehow. If it was the way you said it should be on the DVD stream as well? Maybe a good medium would be inside the udf25 open?

It would be 'better' if the system could decide 'oh you are a virtual file system dont cache individual files because I got it handled at the lower level if needed''. At least that is what I am thinking. Do not think it needs a re-write Smile
Reply
#6
(2015-11-22, 18:30)lharms Wrote: Yeah I saw that code too (CDVDInputStreamFile::Open). However, it does not even go down that path when I run it with a bluray or dvd ISO (breakpoint never hit). I have not tried it but I think that path is only for physical DVDs.

Sorry my comment was not clear. But my hack did work. But it also makes it *always* cache. Which is not the intent. My feeling is CFile:Open needs to change to make a better decision. Sort of like you did. Or at a minimum the udf25:Open should make that decision (that way you hit both the DVD and bluray case).

I was tempted to do what you are saying. But that seems too high up the call stack. It is making the upper API calls make the decision when it really should not be up to them at all?

The problem is if you put it too low level then you basically end up double caching things. The way you have would work for the individual files inside the ISO but not the whole ISO? That may be the right way. Just seems like an interface is wrong somehow. If it was the way you said it should be on the DVD stream as well? Maybe a good medium would be inside the udf25 open?

It would be 'better' if the system could decide 'oh you are a virtual file system dont cache individual files because I got it handled at the lower level if needed''. At least that is what I am thinking. Do not think it needs a re-write Smile

Again, thanks for the feedback.

When I do a Bluray ISO, my second code quote hits for sure.
I could have sworn I was hitting on the my first code quote for a DVD ISO, now I don't see it. Sad

DVDs play fine for me, it's the Bluray that glitches, so I've been focusing on that.

I know I have plenty of bandwidth, so I figured it was a latency issues that buffering could resolve.
Although the buffering is for sure working for Bluray, I still seem to still be having the same problem.

Note, I'm using 0 buffer size meaning it should continue to download the entire video until it reaches the end.

I noticed that it would buffer up the video much faster then stop for a really long time.
It seems to glitch when it starts buffering again.

I started watching the cache files and noticed that during this time, it was deleting the current buffer file and creating a new one.

My theory:
It seems Blurays are broken into much smaller files than DVDs and Kodi won't start buffering the next file until the player starts to play.
It seems that It's this time when the stream glitches.
I may be back to square one on this as it's really not a basic buffering issue, but the basic function of Blurays not letting us buffer the next file ahead of time.
Reply
#7
Oh if it is a stutter at chapter boundaries I may have a fix for that. Though I think it causes a glitchout on some DVDs. I see it as a hesitation right at the beginning of a movie (2-3 second audio dropout). It may not be causing a glitch I need a good way to test for it. But give this thread a try.

http://forum.kodi.tv/showthread.php?tid=241763

I am waiting on a couple of the devs to chime in for it.

You can see it if you turn up the debug level for video. But you will see something like this if it is the chapter stutter
22:37:31 T:139953187059456 DEBUG: CDVDPlayer::CheckContinuity - wrapback :2, prev:111291866.666667, curr:11608955.555556, diff:-99682911.111111

I just need to get off my lazy bum and make a pull request Wink. I have a repo fork and the code staged to check in but need to figure out how to make git make the pull request. But if you can compile and run the code it is a one liner as noted in that other thread.

I stopped digging but I suspect the ffmpeg/libbluray lib is causing the timestamp of the movie to move around. Which causes the code to do a reset of the data stream.

There is another thread on the buffering thing. But like you found it is not doing it. You would see this if your network is borderline. But if you can stream at least 10MB+ per sec you are probably fine. I normally do a file copy and watch the network to see it.

Also setting it to 0 I think it tries to read it out to a local file. At least that is what the docs say. Not sure it would cache anything in memory other than the normal windows file cache. If you look at the settings they are doing on the win32 file read you can see they have it set to cache into memory backwards in the stream but no read ahead.

Yeah your second code hits for 'each' file in the ISO. Your way may make more sense for people who have the thing just split out on disk and not in an ISO. It just makes me think more that the ISO should cache and then just tell it not to cache the files inside. Then when it is not an virtual filestream (which ISO is) it should cache normally. But it does not look like it is.
Reply
#8
Ohh Wow..

The number of hours I've wasted over the last year or so assuming all the glitches in the video was bandwidth and buffering issues.. Sad

I still have the buffering code noted above for Bluray, but I just did the modification below based on your suggestion and suddenly all my issues seem to have disappeared.

Quote: else if(pPacket->dts < current.dts)
{
CLog::Log(LOGDEBUG, "CDVDPlayer::CheckContinuity - wrapback :%d, prev:%f, curr:%f, diff:%f"
, current.type, current.dts, pPacket->dts, pPacket->dts - current.dts);
correction = pPacket->dts - current.dts;
}

I haven't researched what this is specifically doing, but since it's working, I don't mind being ignorant.

Thanks..

Edit: I understand what your saying about the above code buffering everything in the ISO instead of just the video. I was just trying make it just function as most of my Blurays were unwatchable as it is now.. With this now functional, I may look into a better fix..
Reply
#9
I made a pull request for it. https://github.com/xbmc/xbmc/pull/8426

I suspect this fix will also fix that little annoying pop that would sometimes happen on DVD ISOs at chapter change that would happen once and awhile. I have not heard one in a month. At the moment I am a bit ignorant too as to why it is doing this. This bandaids something else that is going wrong lower down. I am also not clear why the bisection I did caused it in the first place.

I found a movie that was doing that startup thing I was describing where the first 2-3 seconds were dropping out. This code does not make any difference in that case. So this fix is safe to do.
Reply
#10
I know this isn't what you were wanting for the buffer part, but this is what I'm sticking to as now Kodi works much better for me.

I can now go back to the default buffer mode 0 in my advanced settings and it will not buffer the file if something above it sets "READ_NO_CACHE".

Quote:xbmc/filesystem/File.cpp | 20 ++++++++++++++++++--
1 file changed, 18 insertions(+), 2 deletions(-)

diff --git a/xbmc/filesystem/File.cpp b/xbmc/filesystem/File.cpp
index 0679606..7f85f50 100644
--- a/xbmc/filesystem/File.cpp
+++ b/xbmc/filesystem/File.cpp
@@ -33,6 +33,7 @@
#include "Util.h"
#include "URL.h"
#include "utils/StringUtils.h"
+#include "settings/AdvancedSettings.h"

#include "commons/Exception.h"

@@ -237,8 +238,23 @@ bool CFile::Open(const CURL& file, const unsigned int flags)
if (!(m_flags & READ_NO_CACHE))
{
const std:Confusedtring pathToUrl(url.Get());
- if (URIUtils::IsInternetStream(url, true) && !CUtil::IsPicture(pathToUrl) )
- m_flags |= READ_CACHED;
+
+ /*
+ * There are 4 buffer modes available (configurable in as.xml)
+ * 0) Buffer all internet filesystems (like 2 but additionally also ftp, webdav, etc.) (default)
+ * 1) Buffer all filesystems (including local)
+ * 2) Only buffer true internet filesystems (streams) (http, etc.)
+ * 3) No buffer
+ */
+ if (g_advancedSettings.m_networkBufferMode == 0 || g_advancedSettings.m_networkBufferMode == 2)
+ {
+ if ((URIUtils::IsInternetStream(url, true) || URIUtils::IsOnLAN(pathToUrl)) && !CUtil::IsPicture(pathToUrl))
+ m_flags |= READ_CACHED;
+ }
+ else if (g_advancedSettings.m_networkBufferMode == 1)
+ {
+ m_flags |= READ_CACHED; // In buffer mode 1 force cache for (almost) all files
+ }

if (m_flags & READ_CACHED)
{

Quote:xbmc/cores/dvdplayer/DVDPlayer.cpp | 1 +
1 file changed, 1 insertion(+)

diff --git a/xbmc/cores/dvdplayer/DVDPlayer.cpp b/xbmc/cores/dvdplayer/DVDPlayer.cpp
index 2e7ad75..51cce98 100644
--- a/xbmc/cores/dvdplayer/DVDPlayer.cpp
+++ b/xbmc/cores/dvdplayer/DVDPlayer.cpp
@@ -2139,6 +2139,7 @@ void CDVDPlayer::CheckContinuity(CCurrentStream& current, DemuxPacket* pPacket)
{
CLog::Log(LOGDEBUG, "CDVDPlayer::CheckContinuity - wrapback :%d, prev:%f, curr:%f, diff:%f"
, current.type, current.dts, pPacket->dts, pPacket->dts - current.dts);
+ correction = pPacket->dts - current.dts;
}

double lastdts = pPacket->dts;

Quote: .../DVDInputStreams/DVDInputStreamFile.cpp | 22 ++--------------------
1 file changed, 2 insertions(+), 20 deletions(-)

diff --git a/xbmc/cores/dvdplayer/DVDInputStreams/DVDInputStreamFile.cpp b/xbmc/cores/dvdplayer/DVDInputStreams/DVDInputStreamFile.cpp
index be07423..94611c0 100644
--- a/xbmc/cores/dvdplayer/DVDInputStreams/DVDInputStreamFile.cpp
+++ b/xbmc/cores/dvdplayer/DVDInputStreams/DVDInputStreamFile.cpp
@@ -58,28 +58,10 @@ bool CDVDInputStreamFile::Open(const char* strFile, const std:Confusedtring& content,
if (!CFileItem(strFile).IsSubtitle())
flags |= READ_AUDIO_VIDEO;

- /*
- * There are 4 buffer modes available (configurable in as.xml)
- * 0) Buffer all internet filesystems (like 2 but additionally also ftp, webdav, etc.) (default)
- * 1) Buffer all filesystems (including local)
- * 2) Only buffer true internet filesystems (streams) (http, etc.)
- * 3) No buffer
- */
- if (!URIUtils::IsOnDVD(strFile) && !URIUtils::IsBluray(strFile)) // Never cache these
+ if (URIUtils::IsOnDVD(strFile) || URIUtils::IsBluray(strFile)) // Never cache these
{
- if (g_advancedSettings.m_networkBufferMode == 0 || g_advancedSettings.m_networkBufferMode == 2)
- {
- if (URIUtils::IsInternetStream(CURL(strFile), (g_advancedSettings.m_networkBufferMode == 0) ) )
- flags |= READ_CACHED;
- }
- else if (g_advancedSettings.m_networkBufferMode == 1)
- {
- flags |= READ_CACHED; // In buffer mode 1 force cache for (almost) all files
- }
- }
-
- if (!(flags & READ_CACHED))
flags |= READ_NO_CACHE; // Make sure CFile honors our no-cache hint
+ }

if (content == "video/mp4" ||
content == "video/x-msvideo" ||

Again, thanks for the help.
Reply

Logout Mark Read Team Forum Stats Members Help
ISO Buffering Help!0