OtherCrashOverride / c2play

Command line video player for Odroid C2
GNU General Public License v2.0
42 stars 72 forks source link

[S805] Video and audio are out of sync when playing http stream #26

Open rgerganov opened 7 years ago

rgerganov commented 7 years ago

First of all, great work!

I have an MXQ box with S805 and I have managed to successfully build and run the player on it. It plays video files without any problems. However, when I try to play an http stream, I get a lot of these messages:

AmlVideoSink: Adjust PTS - pts=12475.939744 vpts=12476.829989 drift=0.890244 (44.512222 frames)

and no video is played. I have tried to comment line 84 (codecPTR->SetCurrentPts) in AmlVideoSink.h but then audio and video are out of sync (~1sec.). Could you give me any pointers how to fix this? This is the full log:

https://pastebin.com/9SJCu1AL

Thanks!

OtherCrashOverride commented 7 years ago

Check the system log (dmesg) for hardware codec errors.

rgerganov commented 7 years ago

OK, here are some updates from today:

  1. Some http streams play fine and some not. The player is doing some PTS adjustment in the beginning and if the video comes up, the stream is being played with audio and video in sync.
  2. Sometimes when I try to play again an http stream which was working an hour ago, the player is stuck in the initial adjusting PTS phase. This is very strange because nothing is changed on the server side.
  3. Sometimes (but not always) I get these messages in dmesg when player fails to sync:

[12508.409345@0] discontinue, system=0x17d977 vpts=0x97adf5d0 next_vf->pts = 0x97adeec8

The full dmesg log is available here: http://do.xakcop.com/c2play/dmesg.log

I also recorded two samples from http streams for which the sync fails: http://do.xakcop.com/c2play/sample1 http://do.xakcop.com/c2play/sample2

So now the problem can be reproduced by simply running c2play sample1 or c2play sample2. I am using LibreElec v7.0.0.3c with kernel 3.10:

LibreELEC:~ # lsb_release -ir LibreELEC (community) - Version: 7.0.3.3c LibreELEC:~ # uname -a Linux LibreELEC 3.10.99 #1 SMP PREEMPT Sun Feb 19 12:18:57 CET 2017 armv7l GNU/Linux

I can also provide root access to the box if that would be helpful. Thanks!

OtherCrashOverride commented 7 years ago

I tested the streams provided and the issue originates in the container: MPEG-TS. This container format is currently unsupported by c2play since its payload is allowed to be damaged. The handling of damaged streams is highly dependent on the patch level of the kernel and codec firmware in use. For example, the media plays without issue on S905 with kernel 3.14 but not on S805 with kernel 3.10.

A possible workaround is to "sanitize" the TS stream before its sent to c2play. I tested this with ffmpeg: $ ffmpeg -i sample1.ts -acodec copy -vcodec copy sample1a.ts

This corrects the container errors and allows playback on S805.

OtherCrashOverride commented 7 years ago

I could not find a method to detect/drop bad info. The AV_PKT_FLAG_CORRUPT flag is never set.

Ffmpeg itself is able to filter out the bad data (-logoption verbose on above command):

Input file #0 (sample1.ts):
  Input stream #0:0 (video): 603 packets read (16472498 bytes);
  Input stream #0:1 (audio): 1004 packets read (578304 bytes);
  Total: 1607 packets (17050802 bytes) demuxed
Output file #0 (sample1a.ts):
  Output stream #0:0 (video): 593 packets muxed (16199090 bytes);
  Output stream #0:1 (audio): 1004 packets muxed (578304 bytes);
  Total: 1597 packets (16777394 bytes) muxed

Its possible that future S805 kernel updates (vendor/mainstream) could correct the issue. In the interim, the solution is likely to pipe the TS through ffmpeg and have it output to a FIFO that c2play then reads from.

rgerganov commented 7 years ago

Thanks for looking into this. I wonder how Kodi works because it plays these streams on the same hardware and the same kernel.

OtherCrashOverride commented 7 years ago

I spent several hours investigating that same question. The only difference I found was this: https://github.com/LibreELEC/xbmc/blob/master/xbmc/cores/VideoPlayer/DVDCodecs/Video/AMLCodec.cpp#L970-L1006

I added the same header feeding to c2play and it made no difference. This leads me to conclude one of two things. Either software decoding of MPEG2 is being used or there is some method they use to detect bad TS frames just as FFMPEG does. I encourage others to fork c2play and experiment.

rgerganov commented 7 years ago

Could you please reopen the bug so it become visible to other people? I am also still working on this.

OtherCrashOverride commented 7 years ago

See also here for all the special processing xbmc does: https://github.com/LibreELEC/xbmc/blob/master/xbmc/cores/VideoPlayer/DVDDemuxers/DVDDemuxFFmpeg.cpp