maemo.org - Talk

maemo.org - Talk (https://talk.maemo.org/index.php)
-   Multimedia (https://talk.maemo.org/forumdisplay.php?f=32)
-   -   A couple of Mediabox questions (https://talk.maemo.org/showthread.php?t=30593)

pycage 2009-08-21 06:23

Re: A couple of Mediabox questions
 
Quote:

Originally Posted by VulcanRidr (Post 313596)
  • 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.

Chun 2009-08-21 13:42

Re: A couple of Mediabox questions
 
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.

VulcanRidr 2009-08-21 14:03

Re: A couple of Mediabox questions
 
Quote:

Originally Posted by Chun (Post 314002)
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.

Chun 2009-08-21 14:22

Re: A couple of Mediabox questions
 
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.

maacruz 2009-08-23 13:19

Re: A couple of Mediabox questions
 
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 2009-08-27 06:16

Re: A couple of Mediabox questions
 
Quote:

Originally Posted by maacruz (Post 314543)
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).

Quote:

Originally Posted by maacruz (Post 314543)
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.

Quote:

Originally Posted by maacruz (Post 314543)
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.

Quote:

Originally Posted by maacruz (Post 314543)
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.

maacruz 2009-08-28 21:44

Re: A couple of Mediabox questions
 
Quote:

Originally Posted by pycage (Post 316022)
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)

Quote:

Originally Posted by pycage (Post 316022)
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.

Quote:

Originally Posted by pycage (Post 316022)
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 :D

maacruz 2009-08-30 16:36

Re: A couple of Mediabox questions - PATCH/FILES INCLUDED
 
4 Attachment(s)
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

pycage 2009-08-31 06:09

Re: A couple of Mediabox questions
 
Great work on this, maacruz! :D

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.

maacruz 2009-08-31 22:44

Re: A couple of Mediabox questions
 
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?


All times are GMT. The time now is 00:12.

vBulletin® Version 3.8.8