PVR Radio - Help with Timeshifting and GetStreamTimes
#1
Hello I am trying work on code dealing with timeshifting PVR radio using code that works for TV.  Basically seeking backwards is fine but when I seek forward the seek code is executed, the read is ok and things seem to be working in the code but then I see the OSD start time stalling and no audio until the time clock catches up with what was read.

Logs with heavy debugging here http://paste.kodi.tv/refinogexu

The problem starts at this time

2019-02-16 16:48:34.467 T:22956 WARNING: ActiveAE - large audio sync error: 32651.719033
2019-02-16 16:48:34.467 T:22956 DEBUG: ActiveAE - start sync of audio stream
until reading starts again
2019-02-16 16:49:07.330 T:15432 DEBUG: ffmpeg[3C48]: [mpegts] pid=100 pes_code=0x1c0

No reads to the stream took place over that time it was just Kodi waiting.  Could someone review the GetStreamTimes() in the logs to see what is going wrong?

Martin
Reply
#2
I have gone over this and it seems to be working if the radio content is mp3.  It PVR radio timeshifting limited to certain codecs?

Martin
Reply
#3
It looks like your results from GetStreamTimes() are wonky.  I've had my problems with implementing this function as well.  I think I'm on my third implementation, but it looks good to the users now.

For LIVE streams, set startTime to the time_t value of the start of the stream.  I use the time_t from when the user opened the stream.
For RECORDED streams, startTime must be zero as indicated in the header file.

I leave ptsBegin and ptsStart as zero at all times, 

ptsEnd needs to be the delta, in microseconds, from startTime (or perhaps startTime + ptsStart, but that's the same for me) to the current end of the stream.  In your log, I see most of the time this is zero, and sometimes it's set but looks to be too small of a number.  Unless ptsEnd sets a positive delta, Kodi won't seek (in my experience).

So let's say you have a stream that started at time_t 1550513393.  It's live, so there is no known end point.  In this case I set startTime to 1550513393, and ptsEnd to ((now - 1550513393) * DVD_TIME_BASE).  This tells Kodi what it needs, and each time GetStreamTimes() is called, the ptsEnd moves along with the wall clock. For a recorded stream, you know the duration, so set startTime to zero, and ptsEnd to ((length in seconds) * DVD_TIME_BASE).

One other thing to watch out for is that ptsEnd is int64_t.  I ran into a problem with GCC here (not MSVC), I suggest static_cast<>ing the seconds to int64_t before multiplying with DVD_TIME_BASE, otherwise the compiler may treat it as 32-bit and overflow on you, causing ptsEnd to go negative.

Code snippet.  I think the variables are explanatory enough, but g_dvrstream->realtime() is my "live" flag, g_stream_starttime is either the initial wall clock time_t for live streams or the known recording start time time_t value.  g_stream_endtime is either MAX_INT64 for live streams or the known recording end time time_t value.

 
cpp:
// Set the start time to the actual start time (UTC) for realtime streams, otherwise zero
 // Using zero here is required to enable calls to SetRecordingLastPlayedPosition()
 times->startTime = (g_dvrstream->realtime()) ? g_stream_starttime : 0;

 times->ptsStart = 0;       // Starting PTS gets set to zero
 times->ptsBegin = 0;       // Timeshift buffer start PTS also gets set to zero

 // Set the timeshift duration to the delta between the start time and the lesser of the
 // current wall clock time or the known stream end time
 time_t now = time(nullptr);
 times->ptsEnd = static_cast<int64_t>(((now < g_stream_endtime) ? now : g_stream_endtime) - g_stream_starttime) * DVD_TIME_BASE;

I hope this helps!!

edit: I always set ptsStart and ptsBegin to zero since I have no back-buffer available.  I can only go back to the point where the user opened the stream.  If you have back-buffer available, I assume you would want to set up all three pts values appropriately.
Reply
#4
My ptsEnd seems to me moving along with the wall clock.  I do leave it at zero at the beginning so the cursor isn't bouncing all over the screen but after that it jumps DVD_TIME_BASE at a time 4, 5, 6 etc which does match what you wrote now - startTime


Martin
Reply
#5
I didn't scroll far enough Smile  Hence why I rarely post - useless info - LOL.
Reply
#6
Thanks for looking.

Martin
Reply
#7
FWIW, I have a set of unresolved complaints from users with audio-only MPEG-TS streams as well, but I don't have access to any myself so I pretty much tweak and wait for feedback.  They've sent me recordings and I've verified the MPEG-TS and have no problems playing them on their behalf.  Do you have any change in behavior when the stream is of a finite length / recorded and can be seeked all the way to the end when asked?  The last change I made solved the problems for raw audio streams like MP3, but no feedback yet regarding audio-only MPEG-TS.

If there are any publicly accessible audio-only MPEG-TS streams you are aware of I would love to be able to try pumping them through what I have to see if there is any correlation that can be made.  I would like to help if possible, especially after restating the obvious on you above and wasting your time like that.
Reply
#8
Recordings from the same source played and seek worked very well.   I can't duplicate in-progress recording since I have changed my source, but I can do that later I believe it worked.

Martin
Reply
#9
I was actually able to partially replicate a problem with an audio-only MPEG-TS stream.  It doesn't quite match your exact symptoms, but maybe this will help to guide you in the right direction or spark an idea.

I hacked my PVR to access a recorded audio-only stream I got from my users as if it was live/real-time.  Seeking forward or backward on the stream always led to Kodi requesting the exact same positions: 0, then 13160, then done.  No attempt to get to a specific time seemed to occur like it usually does with seek.  End result was that no matter where I seeked Kodi ended up at the exact same place.

For comparison, I changed the hacked URL to a regular Video MPEG-TS recorded stream and Kodi was able to seek both backward and forward without issue and requested reasonably accurate positions each time.  The typical 'narrow down' occurred on the position, where it seeked multiple times to get to exactly where it wanted to be, unlike on the audio-only stream.

This isn't a definitive test or proof of a defect by any means, but on the surface seems to be something in Kodi/ffmpeg.  I'm going to try to dig in deeper on my own, but thought you might be able to use this information to help guide your research.  If I find anything of potential actual interest I'll let you know  Nerd
Reply
#10
That is not quite what I see since I can live seek on mp3 file.  In the aac file example I pasted above the wait which seems just like a clock wait is the problem.  I will try an mp2 audio stream for comparison.

I agree with you that with video there is no issue with the same GetStreamTimes().

Out of curiosity do you have any UK users trying DVB radio with EPG?  I have two testers reporting that the player info does not match the EPG info.

Martin
Reply
#11
I tested mp2 audio and it skips fine maybe better than mp3.  The problem is aac.

Martin
Reply
#12
(2019-02-19, 03:32)emveepee Wrote: Out of curiosity do you have any UK users trying DVB radio with EPG?  I have two testers reporting that the player info does not match the EPG info.

Martin
 I do, but they have been reporting the PVR as generally unusable under Leia for audio only streams.  The basic complaint is that the stream will start and then stop after about 5 seconds for no discernable reason.  I don't think we ever got far enough to verify if the EPG was accurate for them or not.  I haven't heard of any similar complaints under Krypton or Jarvis, either from here in the US or abroad. But I really have no way to know how many, if any at all, UK users I had prior to Leia.

The sample audio file I've been using today is actually via UK DVB, from BBC 5 to be specific.  But it's a recording as opposed to a live stream, the indications I've been given is that it plays fine via OpenRecordedStream().  The main difference for me is that I am able to report the length of the stream and won't flag it as "realtime".  I'm having seek problems with it if I fudge those factors.

Thanks for the AAC tip! I haven't really dug into the stream format itself, been considering it as merely generic MPEG-TS stream and perhaps analyzing at too high of a level here.
Reply
#13
I don't have DVB radio myself but I have faked the NextPVR server into returning the live internet radio stream transcoded to the audio format I want by ffmpeg.  The default was aac which is where the problem started.  I still need to test ac3 because that is what North American cable audio format is.

Martin
Reply
#14
Not sure if this will help, but I'm about out of time for today and have to call it quits. 

What I've found so far is that in DVDDemuxFFmpeg.cpp if there is no AVMEDIA_TYPE_VIDEO elementary stream detected/processed, the m_startTime member variable is not being set and will remain at zero. Not sure why yet, but it seems to be getting close to the root cause for my problem.  MPEG-TS with elementary streams of type AVMEDIA_TYPE_VIDEO in them will get m_startTime set on line 2075 (DVDDemuxFFmpeg.cpp, ref 8cfdc895f3, tag "18.1-Leia"), and that seems to be why I don't have the same issues with those.

More if I learn more.
Reply
#15
I think it might be the audio engine.  The wait time is always equal to the current endPts seconds.  If it related to the start being zero that would seem too much difference

Martin
Reply

Logout Mark Read Team Forum Stats Members Help
PVR Radio - Help with Timeshifting and GetStreamTimes0