Notices


Reply
Thread Tools
pycage's Avatar
Posts: 3,404 | Thanked: 4,474 times | Joined on Oct 2005 @ Germany
#31
Originally Posted by VulcanRidr View Post
  • A bookmark function. As I said in an earlier post, much of what I listen to is podcasts. The Linux Link Tech Show is 2 - 2 1/2 hrs. Linux Outlaws is at least an hour, etc. It would be nice if, when I arrive a work, I can store a bookmark within the file and go back to that point when I am ready to leave, instead of searching through the entire file to figure out where I was. Barring that, how about a way to punch in how far into the track to jump to?
You can set bookmarks in (seekable) media files by pressing the [Star] button. This will place a bookmark star on the progress bar. Later, you can click that star on the progress bar to jump directly to the bookmarked position.

Last edited by pycage; 2009-08-21 at 06:31.
 

The Following User Says Thank You to pycage For This Useful Post:
Posts: 2 | Thanked: 0 times | Joined on Jul 2009
#32
Is there a media player that can play video in slow motion? Or is any way to add this feature to one of the player easily. I need it badly.
 
Posts: 473 | Thanked: 141 times | Joined on Jan 2009 @ Virginia, USA
#33
Originally Posted by Chun View Post
Is there a media player that can play video in slow motion? Or is any way to add this feature to one of the player easily. I need it badly.
Read the mplayer man page or manual online. There may be a way of doing it from the command line in mplayer. In fact, I would be surprised if there wasn't.
 
Posts: 2 | Thanked: 0 times | Joined on Jul 2009
#34
It is not easy to use command line in mplayer to view just a part of the video, ( eg: type in slow motion, start time, stop time etc). But if there is no other way, I may try it. Thank you VulcanRidr.
 
Posts: 1,101 | Thanked: 1,184 times | Joined on Aug 2008 @ Spain
#35
I love mediabox and it is the only media player I use, but mplayer directly for video. And the last update to the UI is awesome.
Thank you very much, pycage.
I have just one suggestion: a very low cpu usage mode (because battery life). I'll explain, with 0.9.3 (or was it 4?), before the last UI update, playing music from collection view and then switching the to playlist-player view, would left the python process using just 0.3% cpu. Now it is impossible to get it under 5% (which has some battery consecuences). My user scenario is listening music at work with earbuds, device closed in lowest comsumption mode to get the most battery life, no UI to look at or fiddle with unless opening a new album.
And a bug report: since last update, shoutcast radio is played using whatever backend is set for mp3 files (not obvious at all). osso-media-player backend, the default for mp3, doesn't work for internet radio in mediabox (starts "buffering..." and remains there forever). That means shoutcast radio doen't work unless the user changes the mp3 backend to mplayer
Another bug/improvement report: when playing internet media, because of connection problems, mplayer may become "stuck", making it impossible to simply change to another channel. Since there is only a "pause" button in the UI, pressing it will send a "pause" signal to the stuck mplayer process (which ignores it), and the only way to "unstuck" mediabox is to swich to a xterm and issue a killall mplayer. It also happened to me that the mplayer process kept there running in the background "paused", and draining all battery over the night. Providing a "stop" button which kills the mplayer/osso-media-player child process would solve this issue.
 
pycage's Avatar
Posts: 3,404 | Thanked: 4,474 times | Joined on Oct 2005 @ Germany
#36
Originally Posted by maacruz View Post
I have just one suggestion: a very low cpu usage mode (because battery life). I'll explain, with 0.9.3 (or was it 4?), before the last UI update, playing music from collection view and then switching the to playlist-player view, would left the python process using just 0.3% cpu.
This sounds very much like a bug. MediaBox doesn't consume CPU when idle (scrolling of long title labels stops after some time, too).

Originally Posted by maacruz View Post
And a bug report: since last update, shoutcast radio is played using whatever backend is set for mp3 files (not obvious at all). osso-media-player backend, the default for mp3, doesn't work for internet radio in mediabox (starts "buffering..." and remains there forever). That means shoutcast radio doen't work unless the user changes the mp3 backend to mplayer
Thanks, I'll look at this.

Originally Posted by maacruz View Post
Another bug/improvement report: when playing internet media, because of connection problems, mplayer may become "stuck", making it impossible to simply change to another channel. Since there is only a "pause" button in the UI, pressing it will send a "pause" signal to the stuck mplayer process (which ignores it), and the only way to "unstuck" mediabox is to swich to a xterm and issue a killall mplayer.
Does playing another file or switching to a video kill the stuck mplayer process? It ought to.

Originally Posted by maacruz View Post
It also happened to me that the mplayer process kept there running in the background "paused", and draining all battery over the night. Providing a "stop" button which kills the mplayer/osso-media-player child process would solve this issue.
Normally MediaBox kills mplayer when idle. In this case mplayer doesn't seem to react to killing. osso-media-server is a different thing because this is a service of the Maemo OS. The osso-media-server should take care itself of going idle.
 
Posts: 1,101 | Thanked: 1,184 times | Joined on Aug 2008 @ Spain
#37
Originally Posted by pycage View Post
This sounds very much like a bug. MediaBox doesn't consume CPU when idle (scrolling of long title labels stops after some time, too).
To help, I have been having a look at it.

All this data has been gathered using mediabox to play a "internet radio" stream (currently soma fm http://steady.somafm.com:8032 stream). The audio/unknown mime type handler is set to mplayer, so the stream is played with mplayer.

The python cpu process usage is about 20% while playing this stream.
I ran a profile on mediabox; it shows most of the time is spent in the send_event method of MessageBus.py
The mediabox debug output shows __on_observe_player sends about 5 MEDIA_EV_POSITION + CORE_ACT_SET_INFO events per second.

The code is complex and I don't understand it, so I can't propose a patch, but commenting out lines 269 and 273 from AudioWidget.py fix the cpu issue, making python use about 0.1% CPU if in "browser" screen (so there is no title label scrolling).
[EDIT: After some head banging to understand a bit of the code, I'm making a patch to increase efficiency in MessageBus. I think I have had success to some degree. Need to profile a little more]

Profiling data
Code:
>>> p.sort_stats("time").print_stats(15)
Fri Aug 28 20:41:19 2009    profile1

         4282440 function calls (4180566 primitive calls) in 1931.109 CPU seconds

   Ordered by: internal time
   List reduced from 847 to 15 due to restriction <15>

   ncalls  tottime  percall  cumtime  percall filename:lineno(function)
        1 1455.583 1455.583 1931.109 1931.109 {gtk._gtk.main}
14060/14040  209.791    0.015  422.673    0.030 MessageBus.py:27(send_event)
   773384   48.583    0.000   48.583    0.000 {hasattr}
   506095   30.357    0.000   52.529    0.000 Mediator.py:62(handle_message)
   773260   23.138    0.000   23.138    0.000 Mediator.py:52(set_pass_type)
   506095   22.172    0.000   22.172    0.000 Mediator.py:82(pass_on_event)
   773260   20.840    0.000   20.840    0.000 Mediator.py:57(get_pass_type)
86781/17404    6.824    0.000    6.824    0.000 Widget.py:463(_can_be_visible)
     7020    6.296    0.001  431.800    0.062 AudioWidget.py:254(__on_observe_player)
     7003    5.602    0.001  443.811    0.063 AbstractBackend.py:214(__update_position)
      617    5.292    0.009    5.292    0.009 {method 'draw_pixbuf' of 'gtk.gdk.Drawable' objects}
       17    4.702    0.277    4.702    0.277 {gc.collect}
32450/7993    4.544    0.000    5.411    0.001 Widget.py:645(get_screen_pos)
 6104/515    3.760    0.001   13.765    0.027 {gtk._gtk.main_iteration}
     3896    3.756    0.001    3.756    0.001 {method 'get_extents' of 'pango.Layout' objects}


>>> p.sort_stats("cumulative").print_stats(15)
Fri Aug 28 20:41:19 2009    profile1

         4282440 function calls (4180566 primitive calls) in 1931.109 CPU seconds

   Ordered by: cumulative time
   List reduced from 847 to 15 due to restriction <15>

   ncalls  tottime  percall  cumtime  percall filename:lineno(function)
        1    0.000    0.000 1931.109 1931.109 <string>:1(<module>)
        1 1455.583 1455.583 1931.109 1931.109 {gtk._gtk.main}
7042/7029    1.807    0.000  446.328    0.063 Observable.py:71(update_observer)
     7003    5.602    0.001  443.811    0.063 AbstractBackend.py:214(__update_position)
     7020    6.296    0.001  431.800    0.062 AudioWidget.py:254(__on_observe_player)
14060/14040    1.655    0.000  424.325    0.030 Mediator.py:102(emit_message)
14060/14040  209.791    0.015  422.673    0.030 MessageBus.py:27(send_event)
7092/7051    2.549    0.000  250.957    0.036 Widget.py:157(send_event)
     7002    0.713    0.000  229.866    0.033 MediaViewer.py:297(__on_media_position)
     7003    1.060    0.000  229.173    0.033 Viewer.py:87(set_info)
   506095   30.357    0.000   52.529    0.000 Mediator.py:62(handle_message)
   773384   48.583    0.000   48.583    0.000 {hasattr}
    14024    1.033    0.000   38.009    0.003 Label.py:137(set_text)
     7003    0.590    0.000   38.003    0.005 AppWindow.py:652(handle_CORE_ACT_SET_INFO)
     7003    0.607    0.000   37.413    0.005 TitlePanel.py:110(set_info)
Debug output while playing
Code:
2009-08-28 20:54:37.198 - DEBUG   --- *** CORE_ACT_SET_INFO('5:49',) ***
2009-08-28 20:54:37.438 - DEBUG   --- *** MEDIA_EV_POSITION(349418.04809570312, 0) ***
2009-08-28 20:54:37.459 - DEBUG   --- *** CORE_ACT_SET_INFO('5:49',) ***
2009-08-28 20:54:37.686 - DEBUG   --- *** MEDIA_EV_POSITION(349665.4541015625, 0) ***
2009-08-28 20:54:37.706 - DEBUG   --- *** CORE_ACT_SET_INFO('5:49',) ***
2009-08-28 20:54:37.938 - DEBUG   --- *** MEDIA_EV_POSITION(349917.80395507812, 0) ***
2009-08-28 20:54:37.961 - DEBUG   --- *** CORE_ACT_SET_INFO('5:49',) ***
2009-08-28 20:54:38.185 - DEBUG   --- *** MEDIA_EV_POSITION(350165.11793136597, 0) ***
2009-08-28 20:54:38.205 - DEBUG   --- *** CORE_ACT_SET_INFO('5:50',) ***
2009-08-28 20:54:38.445 - DEBUG   --- *** MEDIA_EV_POSITION(350425.52394866943, 0) ***
2009-08-28 20:54:38.466 - DEBUG   --- *** CORE_ACT_SET_INFO('5:50',) ***
2009-08-28 20:54:38.693 - DEBUG   --- *** MEDIA_EV_POSITION(350673.20508956909, 0) ***
2009-08-28 20:54:38.720 - DEBUG   --- *** CORE_ACT_SET_INFO('5:50',) ***
2009-08-28 20:54:38.943 - DEBUG   --- *** MEDIA_EV_POSITION(350923.20508956909, 0) ***
2009-08-28 20:54:38.964 - DEBUG   --- *** CORE_ACT_SET_INFO('5:50',) ***
By the way, how long it should take to stop scrolling the label? (it seems to take forever)

Originally Posted by pycage View Post
Does playing another file or switching to a video kill the stuck mplayer process? It ought to.
mmm, I think I reproduced it today again with some southcast stream.... but is a complex issue, since it happens intermitently. I'll dive more into this. A new thing I have noticed today is that, when it seems to happen, the python CPU usage goes through the roof. I also observed this high cpu usage when trying to connect to a WorldTV stream and it can't reach the "buffering" stage.

Originally Posted by pycage View Post
Normally MediaBox kills mplayer when idle. In this case mplayer doesn't seem to react to killing.
Well, the all-night issue happened a long while ago, pre 0.96 release. I have read the MPlayerBackend.py code and it really kills mplayer for good

Last edited by maacruz; 2009-08-29 at 03:07.
 
Posts: 1,101 | Thanked: 1,184 times | Joined on Aug 2008 @ Spain
#38
Now, I have got it. Hope you like it.

This is my third version of the MessageBus system, and it is 2,6 times faster than the original version.

In the first version, I used python instrospection to get the handler_X methods and store them in a dictionary, getting rid of the expensive hasattr() calls in the process. This got about 15% efficiency increase. It shows in the profiling, but the %cpu seems unaffected.
In the second version, I switched from dicts to lists, this got an additional 10-15%. %cpu went from 20% to 17% in the test case. Good, but clearly not enough.
The main problem I saw with MessageBus.send_event() is the big number of calls for each message, most of them just to do nothing because inherited Mediator.handle_message() in all mediators. So, why not get rid of those calls?
In the third version, I implemented a handler list for each message, getting rid of the mediators which just happen to have the inherited handle_message(). This reduced the number of calls for each message from 53 to 16-22 (there are still too many handle_message() methods). This increased efficiency a lot more, and %cpu went all the way down from 20% to 8%
Now, the more remaining mediator.handle_message() converted to handle_X methods, the better.

Some profiling data:

Original MessageBus
Code:
>>> porig.sort_stats('time').print_stats(10)
Sun Aug 30 17:52:14 2009    profile.orig

         4150278 function calls (4053758 primitive calls) in 1839.819 CPU seconds

   Ordered by: internal time
   List reduced from 871 to 10 due to restriction <10>

   ncalls  tottime  percall  cumtime  percall filename:lineno(function)
        1 1386.551 1386.551 1839.819 1839.819 {gtk._gtk.main}
13640/13607  199.023    0.015  405.449    0.030 MessageBus.py:27(send_event)
   750285   48.447    0.000   48.447    0.000 {hasattr}
   490973   26.384    0.000   45.948    0.000 Mediator.py:62(handle_message)
   750161   23.316    0.000   23.316    0.000 Mediator.py:52(set_pass_type)
   750161   19.588    0.000   19.588    0.000 Mediator.py:57(get_pass_type)
   490973   19.563    0.000   19.563    0.000 Mediator.py:82(pass_on_event)
84225/16923    7.497    0.000    7.497    0.000 Widget.py:463(_can_be_visible)
     6782    5.616    0.001  421.761    0.062 AbstractBackend.py:214(__update_position)
      606    5.604    0.009    5.604    0.009 {method 'draw_pixbuf' of 'gtk.gdk.Drawable' objects}

>>> porig.sort_stats('cumulative').print_stats(10)
Sun Aug 30 17:52:14 2009    profile.orig

         4150278 function calls (4053758 primitive calls) in 1839.819 CPU seconds

   Ordered by: cumulative time
   List reduced from 871 to 10 due to restriction <10>

   ncalls  tottime  percall  cumtime  percall filename:lineno(function)
        1    0.000    0.000 1839.819 1839.819 <string>:1(<module>)
        1 1386.551 1386.551 1839.819 1839.819 {gtk._gtk.main}
6818/6795    1.898    0.000  426.713    0.063 Observable.py:71(update_observer)
     6782    5.616    0.001  421.761    0.062 AbstractBackend.py:214(__update_position)
     6799    4.638    0.001  409.858    0.060 AudioWidget.py:254(__on_observe_player)
13640/13607    1.650    0.000  407.095    0.030 Mediator.py:102(emit_message)
13640/13607  199.023    0.015  405.449    0.030 MessageBus.py:27(send_event)
6924/6863    2.780    0.000  244.397    0.036 Widget.py:157(send_event)
     6782    0.654    0.000  223.142    0.033 MediaViewer.py:297(__on_media_position)
     6783    1.231    0.000  222.509    0.033 Viewer.py:87(set_info)
Optimized MessageBus
Code:
>>> plist1.sort_stats('time').print_stats(10)
Sun Aug 30 17:52:14 2009    profile.list1

         1812850 function calls (1615642 primitive calls) in 1836.003 CPU seconds

   Ordered by: internal time
   List reduced from 878 to 10 due to restriction <10>

   ncalls  tottime  percall  cumtime  percall filename:lineno(function)
        1 1614.027 1614.027 1836.003 1836.003 {gtk._gtk.main}
16072/16041   65.377    0.004  153.521    0.010 MessageBus.py:89(send_event)
174833/28544   14.326    0.000   14.326    0.001 Widget.py:463(_can_be_visible)
   305407    8.357    0.000    8.357    0.000 Mediator.py:52(set_pass_type)
55962/11280    8.313    0.000    9.976    0.001 Widget.py:645(get_screen_pos)
   305407    7.208    0.000    7.208    0.000 Mediator.py:57(get_pass_type)
     7994    6.175    0.001  174.637    0.022 AbstractBackend.py:214(__update_position)
     8010    5.325    0.001  160.753    0.020 AudioWidget.py:254(__on_observe_player)
      596    5.149    0.009    5.149    0.009 {method 'draw_pixbuf' of 'gtk.gdk.Drawable' objects}
       17    5.003    0.294    5.003    0.294 {gc.collect}

>>> plist1.sort_stats('cumulative').print_stats(10)
Sun Aug 30 17:52:14 2009    profile.list1

         1812850 function calls (1615642 primitive calls) in 1836.003 CPU seconds

   Ordered by: cumulative time
   List reduced from 878 to 10 due to restriction <10>

   ncalls  tottime  percall  cumtime  percall filename:lineno(function)
        1    0.000    0.000 1836.003 1836.003 <string>:1(<module>)
        1 1614.027 1614.027 1836.003 1836.003 {gtk._gtk.main}
8029/8007    1.945    0.000  176.955    0.022 Observable.py:71(update_observer)
     7994    6.175    0.001  174.637    0.022 AbstractBackend.py:214(__update_position)
     8010    5.325    0.001  160.753    0.020 AudioWidget.py:254(__on_observe_player)
16072/16041    1.773    0.000  155.291    0.010 Mediator.py:102(emit_message)
16072/16041   65.377    0.004  153.521    0.010 MessageBus.py:89(send_event)
8146/8067    2.538    0.000  116.980    0.015 Widget.py:157(send_event)
     7993    0.719    0.000   96.491    0.012 MediaViewer.py:297(__on_media_position)
     7994    1.394    0.000   95.778    0.012 Viewer.py:87(set_info)
Next stop: reducing the number of messages sent while playing. 10 msgs/second is too many.

EDIT:
Found and fixed little bug in lines 231 and 236 of AbstractBackend.py that caused delay=200 forever. Also changed the "long" delay to 0,5 s to make the time label update regular. With this, the number of messages/second goes to 4.
Improved AudioWidget.__on_observe_player to send messages only when there are visible changes. With this, we are down to 1-2 msgs/s
Now we are in 1.5-4% cpu usage
Attached Files
File Type: gz com.MessageBus.tar.gz (2.6 KB, 78 views)
File Type: gz MessageBus.diff.gz (2.2 KB, 77 views)
File Type: gz AbstractBackend.diff.gz (325 Bytes, 72 views)
File Type: gz AudioWidget.diff.gz (749 Bytes, 68 views)

Last edited by maacruz; 2009-08-30 at 22:20. Reason: More patches
 
pycage's Avatar
Posts: 3,404 | Thanked: 4,474 times | Joined on Oct 2005 @ Germany
#39
Great work on this, maacruz!

Your optimization on MessageBus look very interesting. This is central piece of MediaBox' component plugin system, so it's a good start for optimizations. handle_message() will eventually be removed as it has been replaced by direct handle_<MESSAGE> calls and introspection. It's still in use in some places, but I want to get rid of those.

Keep up the good work!

I'm currently working on getting rid of the ImageStrip class, replacing it with a faster, cleaner, and more versatile implementation.
 
Posts: 1,101 | Thanked: 1,184 times | Joined on Aug 2008 @ Spain
#40
Thanks
So, now an easy task for me for today: replace as many handle_message with handle_<MESSAGE> as I can.
In doing so, I have found a number of components that have handle_message method but do not register as mediators in MessageBus:
components/media_widgets/VideoWidget.py
components/media_widgets/AudioWidget.py
components/core/IdleDetector.py
components/system/DisplayLight.py
components/system/Headset.py
components/side_strip/SideStrip.py
components_extra/upnphouse_viewer/MyViewer.py
components_htpc/osd_info/OSDVolume.py
components_htpc/osd_info/OSDControls.py
components_htpc/dvd/DVDDetector.py
components_htpc/fullscreen/Fullscreen.py
Is this intentional or there is a bug somewhere?
 
Reply


 
Forum Jump


All times are GMT. The time now is 10:52.