Command line video player

crashoverride
Posts: 4938
Joined: Tue Dec 30, 2014 8:42 pm
languages_spoken: english
ODROIDs: C1
Has thanked: 0
Been thanked: 284 times
Contact:

Re: Command line video player

Post by crashoverride » Mon Dec 05, 2016 5:39 am

The player is highly threaded. The threads spend the majority of their time "sleeping". They do not wake until something has happened.

When video gets "stuck" it is typically because the hardware codec is "busy". In this case, the rest of the threads continue operation. C2play will continue to receive key events and queues them internally up to a set maximum. When the hardware becomes responsive again, the player "catches up" with the key events that it has queued.
https://github.com/OtherCrashOverride/c ... e.cpp#L137

Currently, the player can not tell if the hardware is "busy" due to its buffers being full or if its due to some other condition. Because of this, it will continue to retry up to a defined maximum number of attempts. This is what causes the player to appear stalled. The number of attempts was selected after testing with various media. Lower values caused problems with 4K video playback where the hardware is constantly "busy".
https://github.com/OtherCrashOverride/c ... k.cpp#L399

Since the behavior of the hardware codec is highly dependent on the type of media being played, it is best to supply a sample file that demonstrates the issue.

elmerfudd
Posts: 21
Joined: Sun May 15, 2016 10:00 pm
languages_spoken: english
Has thanked: 0
Been thanked: 0
Contact:

Re: Command line video player

Post by elmerfudd » Mon Dec 05, 2016 6:59 am

I'm able to cause the problem simply by tapping the space bar quickly. The playback stops and the screen shows no "progress bar" at bottom and gives no indication of what state it's in (paused vs playing). I've tried a number of different videos and they all exhibited the same behavior,so I don't think it's media dependant. It would be nice if the GUI part of the player gave a better indication of its current state, without blocking internally.

crashoverride
Posts: 4938
Joined: Tue Dec 30, 2014 8:42 pm
languages_spoken: english
ODROIDs: C1
Has thanked: 0
Been thanked: 284 times
Contact:

Re: Command line video player

Post by crashoverride » Mon Dec 05, 2016 7:06 am

I did perform a quick test using a CEC remote control. I was able to rapidly play/pause the video without issue. I will perform more tests with a keyboard to see if I can reproduce the issue.
elmerfudd wrote:the screen shows no "progress bar" at bottom and gives no indication of what state it's in (paused vs playing).
This was a know issue with the X11 Mali DDX. It should no longer be present with the fbturbo DDX currently used by the Ubuntu image. Ensure your system is updated.

elmerfudd
Posts: 21
Joined: Sun May 15, 2016 10:00 pm
languages_spoken: english
Has thanked: 0
Been thanked: 0
Contact:

Re: Command line video player

Post by elmerfudd » Tue Dec 06, 2016 9:12 am

I've tried both of the following combinations:
c2play-x11 with mali-x11 package installed
c2play with mali-fbdev package installed

Both show the same symptoms: the first few presses of the space bar work as expected. Ie. the player stops and shows the green progress bar, then resumes when the space bar is pressed again. But eventually, if you press the space bar enough times, and especially if pressed quickly, the player stops and never starts playing again. And, at this point, there is no green progress bar displayed.

Considering you mentioned that your code is heavily threaded, I wonder if there is a race condition or deadlock somewhere that gets triggered by rapid delivery of keyboard events?

crashoverride
Posts: 4938
Joined: Tue Dec 30, 2014 8:42 pm
languages_spoken: english
ODROIDs: C1
Has thanked: 0
Been thanked: 284 times
Contact:

Re: Command line video player

Post by crashoverride » Tue Dec 06, 2016 9:47 am

I was able to reproduce the issue using a keyboard. The log output shows that when the playback is stuck, the player is transitioning from pause to play. This explains why there is no progress bar and is correct operation. The log output also indicates the problem is in the video sink.

[edit]
The debugger tells a different story. The player is stuck transitioning the audio sink from pause to play.

[edit2]
The issue appears to originate from ALSA:

Code: Select all

(gdb) thread 17
[Switching to thread 17 (Thread 0x7f68a08120 (LWP 24507))]
#0  0x0000007f78df31c0 in ?? () from /usr/lib/aarch64-linux-gnu/libasound.so.2
(gdb) bt
#0  0x0000007f78df31c0 in ?? () from /usr/lib/aarch64-linux-gnu/libasound.so.2
#1  0x0000007f4c01d8f0 in ?? ()
#2  0x0000007f78deaf50 in ?? () from /usr/lib/aarch64-linux-gnu/libasound.so.2
Backtrace stopped: previous frame inner to this frame (corrupt stack?)

crashoverride
Posts: 4938
Joined: Tue Dec 30, 2014 8:42 pm
languages_spoken: english
ODROIDs: C1
Has thanked: 0
Been thanked: 284 times
Contact:

Re: Command line video player

Post by crashoverride » Tue Dec 06, 2016 11:52 am

The issue should be corrected in the S805 branch (this branch will be merged into beta1 branch and supports both S805 and S905):
https://github.com/OtherCrashOverride/c ... c03949684b

elmerfudd
Posts: 21
Joined: Sun May 15, 2016 10:00 pm
languages_spoken: english
Has thanked: 0
Been thanked: 0
Contact:

Re: Command line video player

Post by elmerfudd » Sat Dec 10, 2016 7:01 am

Thanks very much for looking into this. Any ETA on when the fix will be available in the beta1 branch?

crashoverride
Posts: 4938
Joined: Tue Dec 30, 2014 8:42 pm
languages_spoken: english
ODROIDs: C1
Has thanked: 0
Been thanked: 284 times
Contact:

Re: Command line video player

Post by crashoverride » Sat Dec 10, 2016 7:26 am

The S805 branch is the work in progress for beta1. It contains everything beta1 does with support for C1 added. After the merge, S805 will become the new beta1. So if you use the S805 branch, you are using the next beta1. The only reason that it is not currently beta1 is because I was trying to isolate an issue. The issue turned out to be unrelated so all that is left to do now is the merge. After the merge beta1 will be the exact same code as S805 is today.

elmerfudd
Posts: 21
Joined: Sun May 15, 2016 10:00 pm
languages_spoken: english
Has thanked: 0
Been thanked: 0
Contact:

Re: Command line video player

Post by elmerfudd » Sat Dec 10, 2016 11:04 pm

Ok, I'll try the S805 branch. I was confused by the nomenclature, thinking that S805 implied that the code was only for C1.

elmerfudd
Posts: 21
Joined: Sun May 15, 2016 10:00 pm
languages_spoken: english
Has thanked: 0
Been thanked: 0
Contact:

Re: Command line video player

Post by elmerfudd » Sun Dec 11, 2016 12:14 am

Ok I tried the new version but see the same symptoms. Tap space bar slowly - pause/resume works as expected. Tap half a dozen times quickly - player freezes, no progress bar, doesn't respond to any more keystrokes, have to kill it manually with pkill.

crashoverride
Posts: 4938
Joined: Tue Dec 30, 2014 8:42 pm
languages_spoken: english
ODROIDs: C1
Has thanked: 0
Been thanked: 284 times
Contact:

Re: Command line video player

Post by crashoverride » Sun Dec 11, 2016 4:35 am

On the command line, type "git log" to show the history. You should see the following:

Code: Select all

commit 14a4b10666bc15a74f928cf3e91b0ac03949684b
Author: OtherCrashOverride <OtherCrashOverride@users.noreply.github.com>
Date:   Mon Dec 5 21:47:58 2016 -0500

    Handle the case where ALSA reports zero (0) frames written to avoid an
    infinite loop.

commit 505f37db7c4ede6a43c61e71903e7f22ed269c06
Author: OtherCrashOverride <OtherCrashOverride@users.noreply.github.com>
Date:   Sun Nov 13 16:54:31 2016 -0500

    Support mono audio for PcmFormat::Float32Planes.

commit 3a8633da17f33d916bf2b14506bf7cacefd51ae9
Author: OtherCrashOverride <OtherCrashOverride@users.noreply.github.com>
Date:   Sun Oct 30 22:04:29 2016 +0000

    32bit compatibility fixes.

commit c046c6dbb96f6662e4f468764deb24f702bf3ddc
Author: OtherCrashOverride <OtherCrashOverride@users.noreply.github.com>
Date:   Sun Oct 30 21:42:11 2016 +0000
Note the first commit listed is the one that corrects the issue. If you do not see the commit, then ensure you are on the correct (S805) branch.

Code: Select all

git pull
git checkout S805

elmerfudd
Posts: 21
Joined: Sun May 15, 2016 10:00 pm
languages_spoken: english
Has thanked: 0
Been thanked: 0
Contact:

Re: Command line video player

Post by elmerfudd » Sun Dec 11, 2016 7:25 am

I used the zip file option to download. The top level directory create by unzipping was: 2016-12-05 21:47:58 c2play-S805/
which matches your date exactly. By the way, it might be useful to print a compiled-in version number or date stamp at startup, to avoid any possibility of user confusion about what they're running when reporting bugs.

crashoverride
Posts: 4938
Joined: Tue Dec 30, 2014 8:42 pm
languages_spoken: english
ODROIDs: C1
Has thanked: 0
Been thanked: 284 times
Contact:

Re: Command line video player

Post by crashoverride » Sun Dec 11, 2016 7:36 am

I have merged the S805 branch into the beta1 branch. While testing the Odroid remote, I noticed that LIRC reports key repeats. I disabled processing of those events.
https://github.com/OtherCrashOverride/c ... mits/beta1

The beta1 branch is now the most current, and it is used for both Odroid C0/C1 (S805) and C2 (S905).

elmerfudd
Posts: 21
Joined: Sun May 15, 2016 10:00 pm
languages_spoken: english
Has thanked: 0
Been thanked: 0
Contact:

Re: Command line video player

Post by elmerfudd » Mon Dec 12, 2016 5:30 am

Your latest code didn't fix my problem, however it gave me a clue where to look.

I made the following changes to "c2play-beta1/src/UI/InputDevice.cpp" (marked by NEW and OLD) and no longer have the multiple keypress / lockup problem:

Code: Select all

void InputDevice::WorkThread()
{
   .
   .
   .
   
   while (isRunning)
   {
      int count = read(fd, &ev, sizeof(ev));
#if 1 // NEW
      if (count == -1 && errno == EINTR)
         continue;
      if (count != sizeof(ev))
         break;
#else // OLD
      if (count != sizeof(ev))
      {
         // EINTR will happen when threaded
         if (count != -(EINTR))
            break;
      }
#endif
      else
      {
         //int value = ev.value;

         switch (ev.type)
         {
            case EV_SYN:
            {
               //unsigned short sync = ev.code;
            }
            break;


            case EV_KEY:
            {
               unsigned short keycode = ev.code;

               switch (ev.value)
               {
                  case 0:
                  {
                  //RaiseKeyReleased(keyType);
                  printf("%s: KeyReleased %d (0x%x)\n", name.c_str(), keycode, keycode);
               #if 1 // NEW
                  EnqueKey(keycode);
               #endif
                  }
                  break;

                  case 1:
                  {
                  //RaiseKeyPressed(keyType);
                  printf("%s: KeyPressed %d (0x%x)\n", name.c_str(), keycode, keycode);
               #if 0 // OLD
                  EnqueKey(keycode);
               #endif
                  }
                  break;

   .
   .
   .
The first change was to fix the EINTR test. You need to check the value of errno, not the value returned by read().

The second change was to enque the keycode when the key is *released* not when it is *pressed*.


With these changes, c2play seems to work reliably for me, both from the keyboard and using my IR remote.

gseaman
Posts: 87
Joined: Fri Jan 01, 2016 2:42 pm
languages_spoken: english
ODROIDs: c1+
Location: WA, USA
Has thanked: 0
Been thanked: 0
Contact:

Re: Command line video player

Post by gseaman » Mon Dec 12, 2016 6:36 am

Good find!

crashoverride
Posts: 4938
Joined: Tue Dec 30, 2014 8:42 pm
languages_spoken: english
ODROIDs: C1
Has thanked: 0
Been thanked: 284 times
Contact:

Re: Command line video player

Post by crashoverride » Mon Dec 12, 2016 7:31 am

elmerfudd wrote:I made the following changes to "c2play-beta1/src/UI/InputDevice.cpp" (marked by NEW and OLD) and no longer have the multiple keypress / lockup problem:l
I will look into this. It is not a condition I have ever encountered or have been able to reproduce. Does this occur using the Ubuntu 16.04 image? Or is it a different distro or build-root?
elmerfudd wrote:The second change was to enque the keycode when the key is *released* not when it is *pressed*.
This is by design. When using a keyboard with applications, it is customary to event on key up. When controlling a device, it is more appropriate to event on key-down for better user feedback.

The combination of these two observations suggests there may be an issue in the LIRC subsystem and/or a configuration difference. However, this should not affect keyboard response or cause c2play to become unresponsive. I will need to investigate further.

[edit]
It would also be helpful to see the log output from a session where the issue occurs. Also include the output of "uname -a".

[edit2]
I added the following debugging code to the InputDevice.cpp file:

Code: Select all

			// EINTR will happen when threaded     
			if (count == -(EINTR))
			{
				printf("InputDevice: '%s' EINTR\n", name.c_str());
			}
			else
			{
				printf("InputDevice: '%s' unexpected read count (%d).\n", name.c_str(), count);
				break;
			}
Neither of the code paths ever appears in the output log.

I was able to 'glitch' the playback by mashing the keyboard spacebar at unrealistic rates; however, I was never able to freeze or lockup c2play. It always recovered operation after a period of time.

elmerfudd
Posts: 21
Joined: Sun May 15, 2016 10:00 pm
languages_spoken: english
Has thanked: 0
Been thanked: 0
Contact:

Re: Command line video player

Post by elmerfudd » Mon Dec 12, 2016 11:43 am

I'm using Ubuntu 16.04 (v2.1) - with all updates/upgrades applied as of 31 Oct 2016.

The correction I made involving EINTR probably is unrelated to the bug, but rather a correction to your code.
The read() function never returns a negative value other than -1. The error code EINTR is obtained by consulting the system errno variable, not the return code from read().

I don't know why changing the enque from 'press' to 'release' made a difference, but it did. Perhaps this is not a solution per se, but rather a manifestation of a timing issue somewhere else. One thing I did notice in the old code: when typing the escape key to terminate the player, the 'release' event is never captured because the program exits on the 'press' event. This leaves an unread 'key release' event in the system event queue. I don't know if that confuses other programs or not, but didn't seem like a good idea.

crashoverride
Posts: 4938
Joined: Tue Dec 30, 2014 8:42 pm
languages_spoken: english
ODROIDs: C1
Has thanked: 0
Been thanked: 284 times
Contact:

Re: Command line video player

Post by crashoverride » Mon Dec 12, 2016 12:55 pm

I pushed some more updates to github. With the current commits, I can no longer 'glitch' the player by rapid play/pause requests.

Testing was done similar to this:
Image
elmerfudd wrote:The correction I made involving EINTR probably is unrelated to the bug, but rather a correction to your code.
Since it appears to be "dead code" now, I will likely replace it with a simpler error check. With the thread aborts, it should no longer be necessary to check specifically for -EINTR.
elmerfudd wrote:This leaves an unread 'key release' event in the system event queue.
The program uses input devices directly. It does not use the X11 event queue. It should be no different than holding down a key and exiting any other program. X11 should not generate a key press event unless it saw the "key down" first. If it does present a problem, please let me know.

elmerfudd
Posts: 21
Joined: Sun May 15, 2016 10:00 pm
languages_spoken: english
Has thanked: 0
Been thanked: 0
Contact:

Re: Command line video player

Post by elmerfudd » Tue Dec 13, 2016 12:47 am

Your latest changes work perfectly for me. Thanks for persevering and for enlisting the cat to do final testing.

crashoverride
Posts: 4938
Joined: Tue Dec 30, 2014 8:42 pm
languages_spoken: english
ODROIDs: C1
Has thanked: 0
Been thanked: 284 times
Contact:

Re: Command line video player

Post by crashoverride » Tue Dec 20, 2016 10:02 am

The beta1 branch has been merged with master and tagged v1.0.0. This is designated as the first release. There are no additional code changes. The release has received months of testing on my side.

Omniflux
Posts: 2
Joined: Fri Dec 09, 2016 5:02 pm
languages_spoken: english
ODROIDs: C2
Has thanked: 0
Been thanked: 0
Contact:

Re: Command line video player

Post by Omniflux » Tue Dec 20, 2016 1:55 pm

I would like windowed display from the console, like omxplayer's --win argument, so I can display multiple video streams at once. Is this blocked by the same issue as X11 windowed displays?

User avatar
mad_ady
Posts: 7892
Joined: Wed Jul 15, 2015 5:00 pm
languages_spoken: english
ODROIDs: XU4, C1+, C2, C4, N1, N2, H2, Go, Go Advance
Location: Bucharest, Romania
Has thanked: 494 times
Been thanked: 348 times
Contact:

Re: Command line video player

Post by mad_ady » Tue Dec 20, 2016 2:29 pm

Yes

crashoverride
Posts: 4938
Joined: Tue Dec 30, 2014 8:42 pm
languages_spoken: english
ODROIDs: C1
Has thanked: 0
Been thanked: 284 times
Contact:

Re: Command line video player

Post by crashoverride » Tue Dec 20, 2016 2:46 pm

Omniflux wrote:I would like windowed display from the console
Its dependent on the number of simultaneous hardware codec sessions that can be open. I currently do not know the answer to that.

Additionally, it would require breaking out the current internal compositor into its own stand-alone program. The omxplayer leverages the VC4 compositor to allow different programs access to display "layers". We would need a similar service running on top of FBDEV. An open specification for such an item exists as OpenWF (https://www.khronos.org/openwf/). However, this would not be a trivial endeavor.

User avatar
mad_ady
Posts: 7892
Joined: Wed Jul 15, 2015 5:00 pm
languages_spoken: english
ODROIDs: XU4, C1+, C2, C4, N1, N2, H2, Go, Go Advance
Location: Bucharest, Romania
Has thanked: 494 times
Been thanked: 348 times
Contact:

Re: Command line video player

Post by mad_ady » Tue Dec 20, 2016 3:58 pm

So, in laymen terms you can't preserve "zero-copy" decoding and rendering without going fullscreen, right? I understand you can't decode 4k in real time without it, but what about copying the decoded image to a regular "window" surface that can be displayed onscreen? Would it not work for low resolution (e.g. <720p) video without loss of framerate? It would be an un-optimal solution, but it would allow you to move the window around for low quality content (e.g. web video). Also, displaying 4k in a window on a 4k desktop without allowing for resizing is pointless because of the constraints of space...

crashoverride
Posts: 4938
Joined: Tue Dec 30, 2014 8:42 pm
languages_spoken: english
ODROIDs: C1
Has thanked: 0
Been thanked: 284 times
Contact:

Re: Command line video player

Post by crashoverride » Tue Dec 20, 2016 5:14 pm

For clarification, there are two different questions being asked:
1) Multiple video display without X11. This requires a compositor or some other method to share /dev/fb0 aka FBDEV among different command line programs.
2) Single video display in a X11 window.
mad_ady wrote:So, in laymen terms you can't preserve "zero-copy" decoding and rendering without going fullscreen, right?
Under X11, this can be done zero-copy by using a transparent window and resizing the video layer to give the appearance of video in a window.
mad_ady wrote:I understand you can't decode 4k in real time without it
Resizing the video layer allows 4K in real time since no additional copy is done.
mad_ady wrote:but what about copying the decoded image to a regular "window" surface that can be displayed onscreen?
This is the scenario that can not be done in 4K@60. The maximum that has been achieved is 4K@40 using this method.
mad_ady wrote:Would it not work for low resolution (e.g. <720p) video without loss of framerate?
It depends on both video size as well as the display resolution. The current X11 DDX performs software blits. So even a 720p@60 video would bottleneck when X11 attempts to scale it up to a 4K desktop.

The issue with question #1 (fbdev) requires a compositor to be written. The issue with question #2 (X11) requires a hardware accelerated X11 DDX or a software X11 DDX that properly understands transparency.

Both question #1 and question #2 with "regular window surfaces" require a kernel driver such as vfm_grabber to provide userspace access to the video frames.

Both questions require work that is outside of c2play.

crashoverride
Posts: 4938
Joined: Tue Dec 30, 2014 8:42 pm
languages_spoken: english
ODROIDs: C1
Has thanked: 0
Been thanked: 284 times
Contact:

Re: Command line video player

Post by crashoverride » Wed Jan 04, 2017 2:02 pm

Posting this info here so it does not get lost:

To enable a 1080p framebuffer with 4K video output (for fbdev remove the "sudo service lightdm" lines):

Code: Select all

sudo service lightdm stop
fbset -fb /dev/fb0 -g 1920 1080 1920 2160 32
echo "0 0 1919 1079" | sudo tee /sys/class/graphics/fb0/scale_axis
echo 65537 | sudo tee /sys/class/graphics/fb0/scale
echo "0 0 3819 2159" | sudo tee /sys/class/video/axis
sudo service lightdm start
[edit]
This appears to be a work-around for the issue described here:
http://forum.odroid.com/viewtopic.php?f ... 50#p159881

When using 4K display resolutions, the video may occasionally "glitch". Using a 1080p framebuffer seems to remedy this.

[edit 2]
After further testing, the issue is still present.
:(

Cobrand
Posts: 4
Joined: Wed Jan 18, 2017 3:19 am
languages_spoken: english
ODROIDs: C2
Has thanked: 0
Been thanked: 0
Contact:

Re: Command line video player

Post by Cobrand » Wed Jan 18, 2017 4:18 am

Hi crashoverride,

First of all thank you for your amazing job, that's quite a big software you wrote by yourself, props to you!

I'm currently trying to recreate a library similar to your application, which would be used as a shared library by other software. I've deeply analyzed your source code to see how you manage to make all of this work, however while I've got the hang of it, there is still something that I don't fully understand, and I had hoped that you could give me some hindsight as of what I don't understand.

I am only trying to display video, and I am not caring about audio and subtitles for now.

For your software and amllibs, I am making these assumptions (please correct me if I'm wrong):

* For the video to play, you need to input libav packets (roughly) via /dev/amstream_hevc (for HEVC video)
* For the output of the video to be controlled, you need to tweak /sys/class/video/... such as axis, am I right ?
* For your overlay, you used the EGL API to draw things over the player, is that correct ?
* The video is always outputted to /dev/fb0, and never to a software surface or whatever

Now if all of these are correct, I have some questions:

* How can it tell when exactly to draw a frame ? Does it print a frame by itself right after the end of a Vertical Sync ? I'm very confused by that, because a quick test with c2play-x11 in windowed mode showed that the window was properly displayed after every other window, and the video inside rendered fine. If it was renderer right after a VSync, Xorg would override it and the video wouldn't show, so I guess that's not it. With that, you can draw an overlay on top of it with EGL, meaning that EGL knows when to render the overlay. At this point I'm not even sure that the video is directly outputted to /dev/fb0, and I wouldn't be surprised if it was outputted to some hidden EGLSurface instead.
* Does the VPU has an internal avpacket buffer that you fill as much as possible, or do you send a packet at a time to the VPU, so that you can decide when to pause/accelerate/... ? I'd go for the first option, but I don't see a function call or ioctl call or whatever saying "stop playback", it looks like you just stop sending avpackets, is that right ?

I have some more questions but if you can answer these two it would be a huge help already, and maybe it will help me understand things that I don't understand that are related.

crashoverride
Posts: 4938
Joined: Tue Dec 30, 2014 8:42 pm
languages_spoken: english
ODROIDs: C1
Has thanked: 0
Been thanked: 284 times
Contact:

Re: Command line video player

Post by crashoverride » Wed Jan 18, 2017 11:39 am

Cobrand wrote:* For the video to play, you need to input libav packets (roughly) via /dev/amstream_hevc (for HEVC video)
After the hardware is setup, the packets are written to the codec device:
https://github.com/OtherCrashOverride/c ... c.cpp#L874
Sometimes, minimal processing of the libav packets is required:
https://github.com/OtherCrashOverride/c ... #L256-L382
Cobrand wrote:* For the output of the video to be controlled, you need to tweak /sys/class/video/... such as axis, am I right ?
/sys/class/video has various parameters, such as scaling, that can be used to manipulate the presentation of the video.
Cobrand wrote:* For your overlay, you used the EGL API to draw things over the player, is that correct ?
Yes, EGL/GLES2 is used to compose the overlay scene (UI, subtitles) that is rendered to /dev/fb0.
Cobrand wrote:* The video is always outputted to /dev/fb0, and never to a software surface or whatever
Only the overlay is output to /dev/fb0 when needed. The video is its own hardware layer that is logically beneath /dev/fb0. This layer is managed by its own kernel device (amvideo):
https://github.com/hardkernel/linux/blo ... ts/video.c

Cobrand wrote:* How can it tell when exactly to draw a frame ?
amvideo handles the video frame presentation (see above) and the UI frame presentation is performed by a compositor in C2 play:
https://github.com/OtherCrashOverride/c ... p#L87-L149
The compositor only output a new frame when one is required (such as subtitle has changed), it does not continually render a new frame each vsync. The compositor has no information about the video frame, that is handled entirely by amvideo. The video is never output or copied to /dev/fb0. Instead, it is on its own dedicated hardware layer managed by amvideo.
Cobrand wrote:* Does the VPU has an internal avpacket buffer that you fill as much as possible, or do you send a packet at a time to the VPU, so that you can decide when to pause/accelerate/... ?
The VPU has its own internal buffers for video packets. I have not yet found a good strategy for pausing. The current sequence is that when a pause is requested it is queued. During buffer feeding, the pause status is checked between each packet. If a pause is requested, it is done instead of feeding more packets. When unpaused, packet feeding resumes. The issue lies in that the hardware codec will block until it has room for more packets. This can lead to a condition where a pause is requested, but the hardware has not fully accepted its current packet. In this case, a maximum number of attempts is made before aborting.
https://github.com/OtherCrashOverride/c ... #L179-L393
https://github.com/OtherCrashOverride/c ... #L395-L439
https://github.com/OtherCrashOverride/c ... #L527-L569

[edit]
I should note that the hardware video layer is used since its the only way to get 4K UHD @ 60 fps. It uses a hardware compressed framebuffer to achieve this. The Mali-450 does not understand this format. Using Mali (GLES2) to display video frames significantly increases the memory bandwidth. This should not be an issue for S912 that has an AFBC enabled GPU. In the future (when newer Odroids are released), it may be possible to use a traditional (PC) GPU rendering approach instead. The current hardware is capable of 4K UHD @ 30 fps using Mali, however.

Cobrand
Posts: 4
Joined: Wed Jan 18, 2017 3:19 am
languages_spoken: english
ODROIDs: C2
Has thanked: 0
Been thanked: 0
Contact:

Re: Command line video player

Post by Cobrand » Wed Jan 18, 2017 8:54 pm

Thank you for your answers, definitely very useful, thanks a bunch !

If I understood that well, the Compositor is only useful for the overlay, not for the video itself. If I were the delete the code from Compositor from your code, the video would still play but there would be not overlay or subtitles, correct ?

I have one last question :
Only the overlay is output to /dev/fb0 when needed. The video is its own hardware layer that is logically beneath /dev/fb0. This layer is managed by its own kernel device (amvideo)
If the video layer (amvideo) is beneath fb0, that means that fb0 has to be transparent for the video layer is be displayed, right ? (otherwise the DPU will have none of that and onyl display say your X environment). Is that why you are turning fb0 into a RGBA display before the rendering, and taking is back to a RGBX display after the playback is done ?

crashoverride
Posts: 4938
Joined: Tue Dec 30, 2014 8:42 pm
languages_spoken: english
ODROIDs: C1
Has thanked: 0
Been thanked: 284 times
Contact:

Re: Command line video player

Post by crashoverride » Wed Jan 18, 2017 9:08 pm

Cobrand wrote:If I were the delete the code from Compositor from your code, the video would still play but there would be not overlay or subtitles, correct ?
Yes, only the subtitles and progress bar are rendered through the compositor using EGL/GLES2.
Cobrand wrote:If the video layer (amvideo) is beneath fb0, that means that fb0 has to be transparent for the video layer is be displayed, right ?
/dev/fb0 transparency must be enabled (RGBA). The alpha value is then used to determine how much of the background video shows through. Alternatively, the framebuffer may be disabled entirely to allow the video to show through:
https://github.com/OtherCrashOverride/m ... c#L71-L111
Cobrand wrote:Is that why you are turning fb0 into a RGBA display before the rendering, and taking is back to a RGBX display after the playback is done ?
The display mode is switched to a RGBA since alpha (A) is the only way to express transparency. It is switched back to RGBX because the X11 driver does not properly understand alpha resulting in incorrect visuals being shown.

Cobrand
Posts: 4
Joined: Wed Jan 18, 2017 3:19 am
languages_spoken: english
ODROIDs: C2
Has thanked: 0
Been thanked: 0
Contact:

Re: Command line video player

Post by Cobrand » Thu Jan 19, 2017 1:21 am

crashoverride wrote:
Cobrand wrote:Is that why you are turning fb0 into a RGBA display before the rendering, and taking is back to a RGBX display after the playback is done ?
The display mode is switched to a RGBA since alpha (A) is the only way to express transparency. It is switched back to RGBX because the X11 driver does not properly understand alpha resulting in incorrect visuals being shown.
My guess is that X11 uses RGBX, hence must output garbage instead of the X value, resulting in weird phenomenons happening with enabling the alpha bit. It's strange though, since by default X11 uses 32bpp instead of 24, so this issue shouldn't happen at all ... There might be a way to force X11 to use RGBA, do you have a clue how to do it ?

Thanks again for your answers, it will definitely help a lot !

crashoverride
Posts: 4938
Joined: Tue Dec 30, 2014 8:42 pm
languages_spoken: english
ODROIDs: C1
Has thanked: 0
Been thanked: 284 times
Contact:

Re: Command line video player

Post by crashoverride » Thu Jan 19, 2017 1:34 am

Cobrand wrote:There might be a way to force X11 to use RGBA, do you have a clue how to do it ?
My theory is that it would take a patch to Pixman or an EXA customization to the X11 driver. As noted earlier in this thread, this is outside the scope of c2play.

sney
Posts: 4
Joined: Thu Jan 26, 2017 3:28 am
languages_spoken: english
ODROIDs: C2
Has thanked: 0
Been thanked: 0
Contact:

Re: Command line video player

Post by sney » Thu Jan 26, 2017 3:44 am

Hi, I'm deploying a few C2s playing video slideshows on 4k displays, and I'd like to use c2play for the video since it's similar to what I was previously doing on raspberry pi devices, just at a lower resolution.

The one thing I need that's missing is the ability to play the video in a seamless loop. On the pi I used the example 'hello_video' program, with the change as described here: http://w.xuv.be/projects/raspi_video_lo ... _scripting

I'm going to try and patch a similar thing into c2play with a --loop or similar but my programming skills are pretty slim. It looks like I could test for the end of the video stream with

Code: Select all

if (mediaPlayer->IsEndOfStream())
and then seek back to the beginning with

Code: Select all

newTime = 0.0
goto seek;
maybe? That's just after skimming the source though so maybe a better coder than me can tell me how dumb my idea is and a way better way to accomplish this. ;)

crashoverride
Posts: 4938
Joined: Tue Dec 30, 2014 8:42 pm
languages_spoken: english
ODROIDs: C1
Has thanked: 0
Been thanked: 284 times
Contact:

Re: Command line video player

Post by crashoverride » Thu Jan 26, 2017 4:41 am

I have not tested, but the basic strategy would be to seek to start:
replace the exit condition here:
https://github.com/OtherCrashOverride/c ... n.cpp#L529
with:

Code: Select all

mediaPlayer->Seek(0);

sney
Posts: 4
Joined: Thu Jan 26, 2017 3:28 am
languages_spoken: english
ODROIDs: C2
Has thanked: 0
Been thanked: 0
Contact:

Re: Command line video player

Post by sney » Thu Jan 26, 2017 5:41 am

Thanks, that essentially works. There's one little issue that I can work around, but it'd be better solved -the loop isn't completely seamless, it blinks black for about half a second between the end and the beginning.

crashoverride
Posts: 4938
Joined: Tue Dec 30, 2014 8:42 pm
languages_spoken: english
ODROIDs: C1
Has thanked: 0
Been thanked: 284 times
Contact:

Re: Command line video player

Post by crashoverride » Thu Jan 26, 2017 5:58 am

Again, I have not tested it, but the goal in that case would be to keep a continuous feed of data.

Replace the code here:
https://github.com/OtherCrashOverride/c ... #L550-L560
with

Code: Select all

Seek(0);

sney
Posts: 4
Joined: Thu Jan 26, 2017 3:28 am
languages_spoken: english
ODROIDs: C2
Has thanked: 0
Been thanked: 0
Contact:

Re: Command line video player

Post by sney » Thu Jan 26, 2017 6:33 am

crashoverride wrote:Again, I have not tested it, but the goal in that case would be to keep a continuous feed of data.

Replace the code here:
https://github.com/OtherCrashOverride/c ... #L550-L560
with

Code: Select all

Seek(0);
I don't expect extensive testing. I know mine is a bit of an edge case so thanks for obliging me. I'm happy to do the testing myself.

This change results in no video output, and the following if I check tty1: http://paste.debian.net/plain/910620

I can just use the version with the black blip, if I fade to black at the loop point then it looks seamless anyway. But if you have any other ideas and it's not too much of a pain I'll continue to try stuff.

crashoverride
Posts: 4938
Joined: Tue Dec 30, 2014 8:42 pm
languages_spoken: english
ODROIDs: C1
Has thanked: 0
Been thanked: 284 times
Contact:

Re: Command line video player

Post by crashoverride » Thu Jan 26, 2017 7:33 am

Looping is a feature I have considered before so I added it to the issue list:
https://github.com/OtherCrashOverride/c2play/issues/22

LeRoms77
Posts: 7
Joined: Sat Dec 17, 2016 12:26 am
languages_spoken: english, french
ODROIDs: C2
Has thanked: 0
Been thanked: 0
Contact:

Re: Command line video player

Post by LeRoms77 » Fri Jan 27, 2017 5:35 am

Hello there i've got compile errors:

Code: Select all

root@a19de1f9acc1:~/c2play# make c2play -j2
==== Building c2play (debug) ====
Creating obj/Debug/c2play
main.cpp
Image.cpp
In file included from ../../src/UI/Compositor.h:27:0,
                 from ../../src/Media/SubtitleCodecElement.h:33,
                 from ../../src/Media/MediaPlayer.h:23,
                 from ../../src/main.cpp:39:
../../src/UI/Egl.h:22:21: fatal error: EGL/egl.h: No such file or directory
compilation terminated.
c2play.make:163: recipe for target 'obj/Debug/c2play/main.o' failed
make[1]: *** [obj/Debug/c2play/main.o] Error 1
make[1]: *** Waiting for unfinished jobs....
Makefile:16: recipe for target 'c2play' failed
make: *** [c2play] Error 2
Can you help please
Thanks in advance

crashoverride
Posts: 4938
Joined: Tue Dec 30, 2014 8:42 pm
languages_spoken: english
ODROIDs: C1
Has thanked: 0
Been thanked: 284 times
Contact:

Re: Command line video player

Post by crashoverride » Fri Jan 27, 2017 5:46 am

LeRoms77 wrote:../../src/UI/Egl.h:22:21: fatal error: EGL/egl.h: No such file or directory
The error indicates your distro does not have development resources for EGL installed. The default Ubuntu image includes these. If you are using the official Ubuntu image, ensure you have the mali-fbdev or mali-x11 package installed. If you are using a different image, you will need to contact your distribution maintainer for the relevant package.

You can also consult this thread for compiling tips:
http://forum.odroid.com/viewtopic.php?f=112&t=24350

crashoverride
Posts: 4938
Joined: Tue Dec 30, 2014 8:42 pm
languages_spoken: english
ODROIDs: C1
Has thanked: 0
Been thanked: 284 times
Contact:

Re: Command line video player

Post by crashoverride » Fri Jan 27, 2017 10:52 am

crashoverride wrote:Looping is a feature I have considered before so I added it to the issue list:
https://github.com/OtherCrashOverride/c2play/issues/22
Looping is added in the 'next' branch
https://github.com/OtherCrashOverride/c ... 9998ebb2c4

LeRoms77
Posts: 7
Joined: Sat Dec 17, 2016 12:26 am
languages_spoken: english, french
ODROIDs: C2
Has thanked: 0
Been thanked: 0
Contact:

Re: Command line video player

Post by LeRoms77 » Sat Jan 28, 2017 2:25 am

I am compiling from docker with image michaelcoll/odroid-c2-arm64-base. I will try to install the deb packages inside
Thanks

sney
Posts: 4
Joined: Thu Jan 26, 2017 3:28 am
languages_spoken: english
ODROIDs: C2
Has thanked: 0
Been thanked: 0
Contact:

Re: Command line video player

Post by sney » Sat Jan 28, 2017 2:32 am

crashoverride wrote:
crashoverride wrote:Looping is a feature I have considered before so I added it to the issue list:
https://github.com/OtherCrashOverride/c2play/issues/22
Looping is added in the 'next' branch
https://github.com/OtherCrashOverride/c ... 9998ebb2c4

Awesome! Thanks!

Cobrand
Posts: 4
Joined: Wed Jan 18, 2017 3:19 am
languages_spoken: english
ODROIDs: C2
Has thanked: 0
Been thanked: 0
Contact:

Re: Command line video player

Post by Cobrand » Mon Mar 20, 2017 11:18 pm

Hey! I've "finished" the project that I've talked about few posts above, and there it is : https://github.com/Cobrand/c2player

That was the name of the library day one but it has not been changed since, if this is trouble I can change it anytime.

Huge thanks to OtherCrashOverride for both his advices and his source code from which obscure parts have been heavily inspired (especially the undocumented parts of the VPU ioctl calls). I'm just sharing this because some people might be interested, but please notice that I will not maintain this anymore for various reasons. The license is permissive though, so you are free to use this code however you'd like.

Unlike c2play, this has been created to only be used as a library, and thus only C calls are used as input.

Examples of what you can do with this library :
  • Play multiple videos successively in a loop
  • Play a long video in a small part of the screen (for instance with a news board, displaying a video in a part of the screen and HTML in the other part)
  • Play the first 10 seconds of a video, pause the video and hide it, then 10 seconds later show it back in fullscreen and resume the playback.
What you can't do with this library:
  • Keyboard / mouse input
  • Audio playback
  • Subtitles display
  • Play anything else than HEVC/H265 (lack of time for AVC/H264)
So the usage is quite limited but I'm sure at least somebody will find a way to use it nicely. The source code is here mostly for others to understand what's going on and someday someone wants to program something similar.

mcomp.sp
Posts: 1
Joined: Tue Mar 21, 2017 7:07 pm
languages_spoken: English, Danish
ODROIDs: C2
Has thanked: 0
Been thanked: 0
Contact:

Re: Command line video player

Post by mcomp.sp » Tue Mar 21, 2017 7:17 pm

Amazing job! Runs smoothly.
Would it be possible to add geometry options, so player limits to a portion of the screen, like mpv and mplayer supports?

crashoverride
Posts: 4938
Joined: Tue Dec 30, 2014 8:42 pm
languages_spoken: english
ODROIDs: C1
Has thanked: 0
Been thanked: 284 times
Contact:

Re: Command line video player

Post by crashoverride » Wed Mar 22, 2017 4:51 am

mcomp.sp wrote:Would it be possible to add geometry options, so player limits to a portion of the screen, like mpv and mplayer supports?
The method to do that remains in the c2play codebase, but it is commented out (disabled) due to issues. I am pointing it out for anyone wishing to implement the feature in their own work:
https://github.com/OtherCrashOverride/c ... #L101-L120

Code: Select all

void AmlWindow::SetVideoAxis(int x, int y, int width, int height)
{
	// IMPORTANT: this causes video to be drained instead of flushed
	// when codec_close is called.  The cause needs to be investigated.

	//int video_fd = OpenDevice();

	//int params[4]{ x, y, x + width, y + height };

	//int ret = ioctl(video_fd, AMSTREAM_IOC_SET_VIDEO_AXIS, &params);
	//
	//CloseDevice(video_fd);

	//if (ret < 0)
	//{
	//	throw Exception("ioctl AMSTREAM_IOC_SET_VIDEO_AXIS failed.");
	//}


}

alabama
Posts: 17
Joined: Wed Mar 22, 2017 12:27 am
languages_spoken: english
ODROIDs: 2x Odroid C1+
2x Odroid C2
Has thanked: 0
Been thanked: 0
Contact:

Re: Command line video player

Post by alabama » Thu Apr 13, 2017 5:41 pm

Hi crashoverride.
I've seen that c2play uses PTS in an incremental way to keep A/V sync, apart from guessing the end of the file.
I was wondering how could I feed sequentially several TS files thru a pipe to c2play, if they all restart the PTS value from file to file.
I did it on my own just remuxing thru ffmpeg, and works seemlessly, but it would be easier if c2play could play restarted PTS segments seemlessly. Not just incrementally.
It is just a suggestion.
Nice tool.
Last edited by alabama on Fri Apr 14, 2017 12:06 am, edited 1 time in total.

crashoverride
Posts: 4938
Joined: Tue Dec 30, 2014 8:42 pm
languages_spoken: english
ODROIDs: C1
Has thanked: 0
Been thanked: 284 times
Contact:

Re: Command line video player

Post by crashoverride » Thu Apr 13, 2017 7:10 pm

alabama wrote:I've seen that c2play uses PTS in an incremental way to keep A/V sync, apart from guessing the end of the file.
Due to the way the Amlogic codec interface is architected, the kernel drivers themselves track PTS information. c2play simply passes that information along to the driver. To maintain synchronization, it also "asks" the video codec what time it thinks it is and then tells it the correct time if its too far off what time the audio codec thinks it is.

Time can only be adjusted on packet boundaries. An audio packet may be be longer in time than a video packet. For example, one packet of audio may be five packets of video in length. This means that to adjust time, c2play stops audio/video playback, flushes any pending packets, and starts sending new packets with the changed PTS. This happens every time a request is made to jump forward or backward in a stream.
https://github.com/OtherCrashOverride/c ... #L256-L350
alabama wrote:I was wondering how could I feed sequentially several TS files thru a pipe to c2play, if they all restart the PTS value from file to file.
c2play expects a stream to be homogeneous. For avi, mkv, and mp4, the container guarantees this. The stream will not change audio/video codecs or add/remove sub-streams:
https://github.com/OtherCrashOverride/c ... ME#L37-L38

Code: Select all

Supported containers:
MKV, AVI, MP4 have been tested.
MPEG-TS does not offer this guarantee. It is possible for the TS to "redefine" its contents at any time. This is effectively the same as playing different .mkv, .mp4, .avi. The streams of different files may be homogeneous, but there is no guarantee or expectation that they will be.

To handle a change of codec or sub-stream (non-homogeneous), the media graph has to be stopped, torn down, and rebuilt. This is why c2play can not offer generic seamless playback across multiple files regardless of container format.

Since everything is open source, it is possible to make your own customizations to meet your needs. c2play is object oriented and graph based so arbitrary new components can be added as needed.
https://github.com/OtherCrashOverride/c ... lement.cpp
https://github.com/OtherCrashOverride/c ... Player.cpp

In the future, its is likely that the kernel codec architecture will change (V4L based codec). At that time it may be possible for c2play to "freeze" the last video frame being displayed to better offer the illusion of seamless playback while the media graph is torn down and rebuilt.

User avatar
HeinrichG
Posts: 46
Joined: Wed Jul 05, 2017 11:19 pm
languages_spoken: english, german
ODROIDs: C2
Location: Germany
Has thanked: 0
Been thanked: 0
Contact:

Re: Command line video player

Post by HeinrichG » Thu Jul 06, 2017 5:57 pm

Hello crashoverride,

really nice work!

I've got a question: does c2play support streams too?

I mean this constellation:
-> an video device, for example DVB-C or DVB-T2 usb stick, which is supported by linux
-> channel list created by w_scan

Or alternatively; tvheadend as a data source.

Thanks you.
Regards,
Heinrich

crashoverride
Posts: 4938
Joined: Tue Dec 30, 2014 8:42 pm
languages_spoken: english
ODROIDs: C1
Has thanked: 0
Been thanked: 284 times
Contact:

Re: Command line video player

Post by crashoverride » Fri Jul 07, 2017 3:06 am

HeinrichG wrote:Or alternatively; tvheadend as a data source.
It does work with tvheadend in tests that I did. I used the tvheadend web interface to select the stream, then i copied the URL from the browser and used it as the input parameter to c2play:

Code: Select all

c2play http://TheVideoUrlProvidedByTvheaded

Post Reply

Return to “Ubuntu”

Who is online

Users browsing this forum: No registered users and 2 guests