[Development] The dark side of QtMultimedia - strikes back

Massimo Callegari massimocallegari at yahoo.it
Sat Jul 4 18:36:35 CEST 2015


Hi everyone,
I'm afraid I need to raise this 8-months topic back again, and I have no 
more words to describe the frustration QtMultimedia is giving me.
So this time I come up with a video clip I've taken: 
https://www.youtube.com/watch?v=GE98h_HHuAk

I've built Qt 5.5.0 for the Raspberry Pi 2, with gstreamer-1.0 support, 
and installed the GST OMX plugin, for hardware decoding.
Ran the player example on EGLFS and that's the result: omxplayer works 
like a charm and QtMultimedia doesn't.
Attached the player example log with GST_DEBUG="omx:4" on.
It shows that QtMultimedia is actually using gstreamer + OMX.

I don't understand if things are tested before declaring them "supported".
I quote: " A lot of work has also gone into Qt Multimedia. On Linux, we 
have now added gstreamer 1.0 support and lots of bugs have been fixed 
for the other platforms."

Like this supreme demonstration of how unprofessionally bugs are 
treated: https://bugreports.qt.io/browse/QTBUG-42034 ? (see the history)

I suspect, instead, the Qt Company has received money for a project 
needing the camera input support,
so "the lot of work" is that all the manpower (1 dev ? 2 devs ?) have 
gone into that.

If you're not willing to listen to the Qt community, then don't even 
talk about a community.
Say instead "we do what we need, like it or not"

So the question is, when QtMultimedia can start to be fixed seriously ?

Regards,
Massimo


Il 08/11/2014 16:00, Massimo Callegari ha scritto:
> Dear Qt team,
> I am well aware you guys do your best to provide a quality 
> cross-platform framework and so far you did an excellent job !
> Unfortunately I cannot say such thing for the Qt Multimedia module. If 
> you stick to the provided examples (properly tailored to hide all the 
> bugs) they all almost work. If you try to use the multimedia 
> functionalities in a serious project and try to deploy it, then the 
> pain comes around.
> I found Qt Multimedia buggy, unsupported and moreover not cross-platform.
>
> I am the maintainer of an open source project and so far I provided 
> multimedia audio input/output on Qt4 using ALSA on Linux, 
> WAVEIN/WAVEOUT on Windows and PortAudio on OSX.
> In the last 9 months I tried to switch to Qt5 Multimedia and opened a 
> number of issues on JIRA and none of them has been resolved or taken 
> into account.
>
> It seems the priority goes to things like Camera input, instead of 
> fixing and consolidating the current functionalities.
> As of today, on Gerrit there are only 12 open commits. 5 of them 
> related to Camera input. 9 of them are 4 or more months old.
> https://codereview.qt-project.org/#/q/status:open+project:qt/qtmultimedia,n,z
> On JIRA there 178 open tickets. More than 100 are P1 or P2 but it 
> seems nobody is actively taking care of them:
> https://bugreports.qt-project.org/browse/QTBUG/component/19173#selectedTab=com.atlassian.jira.plugin.system.project%3Acomponent-issues-panel
>
> So the question is, are you guys actually interested in improving Qt 
> Multimedia ?
> Is there any internal problem in maintaining this module that we 
> should be aware of ?
>
> Please let us know something about the future of this module, cause 
> right now it is quite difficult to rely on it and include it on a project.
> I would offer my contribution to fix some of the issues I found, but 
> unfortunately my time is very limited and I'd risk to not being able 
> to follow the activities.
>
> My personal suggestion: to take this seriously you need 2-3 developers 
> working 8 hours a day on this module. At least until it reaches the 
> quality of the other Qt modules.
>
> Thanks in advance and regards.
> Massimo
>
> Here's the issues I opened on JIRA plus a few other considerations
> (apologies if the description is not complete, the issues on JIRA have 
> been locked so I couldn't improve them anymore)
>
> ----
> https://bugreports.qt-project.org/browse/QTBUG-37004
> *February 22nd 2014**: QAudioDeviceInfo should have a displayName() or 
> description() function*
> On OSX devices names are correct.
> On Windows they are truncated to 31 characters
> On Linux it's a mess. I think no user wants something like this: 
> http://pbrd.co/1tpyzuu
>
> ----
> https://bugreports.qt-project.org/browse/QTBUG-37005
> *February 22nd 2014**: QMediaPlayer supported mime types*
> The documentations says we shouldn't use 
> QMediaPlayer::supportedMimeTypes() but:
> - on OSX it returns a list of mime types even though it says it 
> supports AVI video playback and instead it doesn't
> - on Windows and Linux it returns an empty QStringList
> - the alternative is to use the 'hasSupport' method, which is a pure 
> non-sense/blind shooting way to understand the capabilities of the 
> MediaPlayer engine
>
> ----
> https://bugreports.qt-project.org/browse/QTBUG-42034
> *October 18th 2014**: QMediaPlayer metaDataChanged signal not emitted 
> on OSX*
> An example of NOT cross-compatibility. The signal is emitted on 
> Windows and Linux.
>
> ----
> https://bugreports.qt-project.org/browse/QTBUG-37882
> *March 27th 2014**: QAudioDeviceInfo nearestFormat not working on OSX*
> Another example of NOT-cross compatilibity. A code that works on Linux 
> and Windows doesn't work on OSX.
> It took me months to find a non-sense workaround to make my code to work.
> In the meantime, the original code was hanging on OSX, which shouldn't 
> happen anyway.
>
> ----
> *Audio input example doesn't work on Windows 7 and Realtek audio card*
> Unfortunately the OS and card combination is quite popular on the 
> market. RTK cards are most likely integrated in desktop motherboards. 
> On Linux the same example with the same card works as expected.
> Here there are 2 issues:
> - the example gets a QIODevice from the QAudioInput::start() method. 
> The QIODevice is used to read data from the audio card, but if I call 
> the QIODevice::bytesAvailable() method
>   it always returns 0. QAudioInput::bytesReady() must be used instead. 
> I believe that the first approach should work if the subclassing was 
> done properly
> - with the Realtek card, QIODevice::read always reads 3840 bytes, no 
> matter what QAudioInput::bytesReady() returns.
>   For example: the app needs 4096 bytes, bytesReady returns 7680 bytes 
> and QIODevice::read reads 3840 instead of 4096 as requested.
> In my case I need 4096 bytes to perform a FFT. If the device returns 
> less bytes, the FFT fails.
>
> ----
> *GStreamer 1.0 support*
> GStreamer 1.0 has been released more than 2 years ago. An issue on 
> JIRA has been opened on Sep 9th 2013 and it's still ongoing.
> This porting is fundamental for the Raspberry Pi since it cannot 
> afford to software decode videos.
> How can you guys "officially" support (as a paid enterprise service) 
> the Raspberry Pi if you don't have such a basic functionality ?
> http://blog.qt.digia.com/blog/2013/10/24/introducing-qt-enterprise-embedded-aka-boot-to-qt/
> You should say "we support the Pi, except for the multimedia 
> functionalities"
>
>

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.qt-project.org/pipermail/development/attachments/20150704/430dd807/attachment.html>
-------------- next part --------------
pi at raspberrypi ~ $ ./player                   
Unable to query physical screen size, defaulting to 100 dpi.
To override, set QT_QPA_EGLFS_PHYSICAL_WIDTH and QT_QPA_EGLFS_PHYSICAL_HEIGHT (in millimeters).
No m_videoSink available!
0:00:33.631480802  3267  0x1ecee30 INFO                     omx gstomx.c:1864:gst_omx_port_set_enabled_unlocked:<omxh264dec-omxh264dec0> Setting video_decode port 131 to disabled
0:00:33.632935077  3267  0x1ecee30 INFO                     omx gstomx.c:1912:gst_omx_port_set_enabled_unlocked:<omxh264dec-omxh264dec0> Set video_decode port 131 to disabled: None (0x00000000)
0:00:33.633545234  3267  0x1ecee30 INFO                     omx gstomx.c:2153:gst_omx_port_wait_enabled_unlocked:<omxh264dec-omxh264dec0> Waiting for video_decode port 131 to be disabled
0:00:33.634344194  3267  0x1ecee30 INFO                     omx gstomx.c:2228:gst_omx_port_wait_enabled_unlocked:<omxh264dec-omxh264dec0> video_decode port 131 is disabled: None (0x00000000)
0:00:33.634675706  3267  0x1ecee30 INFO                     omx gstomx.c:756:gst_omx_component_set_state:<omxh264dec-omxh264dec0> Setting video_decode state from Loaded to Idle
0:00:33.635576281  3267  0x1ecee30 INFO                     omx gstomx.c:1631:gst_omx_port_allocate_buffers_unlocked:<omxh264dec-omxh264dec0> Allocating 20 buffers of size 81920 for video_decode port 130
0:00:33.639860822  3267  0x1ecee30 INFO                     omx gstomx.c:225:gst_omx_component_handle_messages:<omxh264dec-omxh264dec0> video_decode state change to Idle finished
0:00:33.640540875  3267  0x1ecee30 INFO                     omx gstomx.c:1688:gst_omx_port_allocate_buffers_unlocked:<omxh264dec-omxh264dec0> Allocated buffers for video_decode port 130: None (0x00000000)
0:00:33.641004574  3267  0x1ecee30 INFO                     omx gstomx.c:756:gst_omx_component_set_state:<omxh264dec-omxh264dec0> Setting video_decode state from Idle to Executing
0:00:33.641554575  3267  0x1ecee30 INFO                     omx gstomx.c:225:gst_omx_component_handle_messages:<omxh264dec-omxh264dec0> video_decode state change to Executing finished
Warning: "No volume control found"
0:00:33.784333756  3267 0x7251acf0 INFO                     omx gstomx.c:1864:gst_omx_port_set_enabled_unlocked:<omxh264dec-omxh264dec0> Setting egl_render port 220 to disabled
0:00:33.787895430  3267 0x7251acf0 INFO                     omx gstomx.c:1912:gst_omx_port_set_enabled_unlocked:<omxh264dec-omxh264dec0> Set egl_render port 220 to disabled: None (0x00000000)
0:00:33.789914914  3267 0x7251acf0 INFO                     omx gstomx.c:2153:gst_omx_port_wait_enabled_unlocked:<omxh264dec-omxh264dec0> Waiting for egl_render port 220 to be disabled
0:00:33.792132315  3267 0x7251acf0 INFO                     omx gstomx.c:2228:gst_omx_port_wait_enabled_unlocked:<omxh264dec-omxh264dec0> egl_render port 220 is disabled: None (0x00000000)
0:00:33.792446534  3267 0x7251acf0 INFO                     omx gstomx.c:1864:gst_omx_port_set_enabled_unlocked:<omxh264dec-omxh264dec0> Setting egl_render port 221 to disabled
0:00:33.795417375  3267 0x7251acf0 INFO                     omx gstomx.c:1912:gst_omx_port_set_enabled_unlocked:<omxh264dec-omxh264dec0> Set egl_render port 221 to disabled: None (0x00000000)
0:00:33.796361856  3267 0x7251acf0 INFO                     omx gstomx.c:2153:gst_omx_port_wait_enabled_unlocked:<omxh264dec-omxh264dec0> Waiting for egl_render port 221 to be disabled
0:00:33.796943159  3267 0x7251acf0 INFO                     omx gstomx.c:2228:gst_omx_port_wait_enabled_unlocked:<omxh264dec-omxh264dec0> egl_render port 221 is disabled: None (0x00000000)
0:00:33.797849516  3267 0x7251acf0 INFO                     omx gstomx.c:1864:gst_omx_port_set_enabled_unlocked:<omxh264dec-omxh264dec0> Setting egl_render port 220 to enabled
0:00:33.798684205  3267 0x7251acf0 INFO                     omx gstomx.c:1912:gst_omx_port_set_enabled_unlocked:<omxh264dec-omxh264dec0> Set egl_render port 220 to enabled: None (0x00000000)
0:00:33.798879987  3267 0x7251acf0 INFO                     omx gstomx.c:756:gst_omx_component_set_state:<omxh264dec-omxh264dec0> Setting egl_render state from Loaded to Idle
0:00:33.800507178  3267 0x7251acf0 INFO                     omx gstomx.c:225:gst_omx_component_handle_messages:<omxh264dec-omxh264dec0> egl_render state change to Idle finished
0:00:33.800872856  3267 0x7251acf0 INFO                     omx gstomx.c:2153:gst_omx_port_wait_enabled_unlocked:<omxh264dec-omxh264dec0> Waiting for egl_render port 220 to be enabled
0:00:33.801395774  3267 0x7251acf0 INFO                     omx gstomx.c:2228:gst_omx_port_wait_enabled_unlocked:<omxh264dec-omxh264dec0> egl_render port 220 is enabled: None (0x00000000)
0:00:33.801756972  3267 0x7251acf0 INFO                     omx gstomx.c:1864:gst_omx_port_set_enabled_unlocked:<omxh264dec-omxh264dec0> Setting video_decode port 131 to disabled
0:00:33.802348953  3267 0x7251acf0 INFO                     omx gstomx.c:1912:gst_omx_port_set_enabled_unlocked:<omxh264dec-omxh264dec0> Set video_decode port 131 to disabled: None (0x00000000)
0:00:33.802738641  3267 0x7251acf0 INFO                     omx gstomx.c:2153:gst_omx_port_wait_enabled_unlocked:<omxh264dec-omxh264dec0> Waiting for video_decode port 131 to be disabled
0:00:33.804988907  3267 0x7251acf0 INFO                     omx gstomx.c:2228:gst_omx_port_wait_enabled_unlocked:<omxh264dec-omxh264dec0> video_decode port 131 is disabled: None (0x00000000)
0:00:33.805208959  3267 0x7251acf0 INFO                     omx gstomx.c:756:gst_omx_component_set_state:<omxh264dec-omxh264dec0> Setting egl_render state from Idle to Loaded
0:00:33.805561669  3267 0x7251acf0 INFO                     omx gstomx.c:225:gst_omx_component_handle_messages:<omxh264dec-omxh264dec0> egl_render state change to Loaded finished
0:00:33.805720836  3267 0x7251acf0 INFO                     omx gstomx.c:1755:gst_omx_port_deallocate_buffers_unlocked:<omxh264dec-omxh264dec0> Deallocating buffers of egl_render port 221
0:00:33.859359708  3267 0x7251acf0 INFO                     omx gstomx.c:1864:gst_omx_port_set_enabled_unlocked:<omxh264dec-omxh264dec0> Setting resize port 60 to disabled
0:00:33.862358152  3267 0x7251acf0 INFO                     omx gstomx.c:1912:gst_omx_port_set_enabled_unlocked:<omxh264dec-omxh264dec0> Set resize port 60 to disabled: None (0x00000000)
0:00:33.863576384  3267 0x7251acf0 INFO                     omx gstomx.c:2153:gst_omx_port_wait_enabled_unlocked:<omxh264dec-omxh264dec0> Waiting for resize port 60 to be disabled
0:00:33.865785400  3267 0x7251acf0 INFO                     omx gstomx.c:2228:gst_omx_port_wait_enabled_unlocked:<omxh264dec-omxh264dec0> resize port 60 is disabled: None (0x00000000)
0:00:33.866339932  3267 0x7251acf0 INFO                     omx gstomx.c:1864:gst_omx_port_set_enabled_unlocked:<omxh264dec-omxh264dec0> Setting resize port 61 to disabled
0:00:33.869525148  3267 0x7251acf0 INFO                     omx gstomx.c:1912:gst_omx_port_set_enabled_unlocked:<omxh264dec-omxh264dec0> Set resize port 61 to disabled: None (0x00000000)
0:00:33.871455465  3267 0x7251acf0 INFO                     omx gstomx.c:2153:gst_omx_port_wait_enabled_unlocked:<omxh264dec-omxh264dec0> Waiting for resize port 61 to be disabled
0:00:33.872199425  3267 0x7251acf0 INFO                     omx gstomx.c:2228:gst_omx_port_wait_enabled_unlocked:<omxh264dec-omxh264dec0> resize port 61 is disabled: None (0x00000000)
0:00:33.872853281  3267 0x7251acf0 INFO                     omx gstomx.c:1864:gst_omx_port_set_enabled_unlocked:<omxh264dec-omxh264dec0> Setting resize port 60 to enabled
0:00:33.873662762  3267 0x7251acf0 INFO                     omx gstomx.c:1912:gst_omx_port_set_enabled_unlocked:<omxh264dec-omxh264dec0> Set resize port 60 to enabled: None (0x00000000)
0:00:33.873801147  3267 0x7251acf0 INFO                     omx gstomx.c:756:gst_omx_component_set_state:<omxh264dec-omxh264dec0> Setting resize state from Loaded to Idle
0:00:33.874387815  3267 0x7251acf0 INFO                     omx gstomx.c:225:gst_omx_component_handle_messages:<omxh264dec-omxh264dec0> resize state change to Idle finished
0:00:33.874741097  3267 0x7251acf0 INFO                     omx gstomx.c:2153:gst_omx_port_wait_enabled_unlocked:<omxh264dec-omxh264dec0> Waiting for resize port 60 to be enabled
0:00:33.876438080  3267 0x7251acf0 INFO                     omx gstomx.c:2228:gst_omx_port_wait_enabled_unlocked:<omxh264dec-omxh264dec0> resize port 60 is enabled: None (0x00000000)
0:00:33.878991784  3267 0x7251acf0 INFO                     omx gstomx.c:1864:gst_omx_port_set_enabled_unlocked:<omxh264dec-omxh264dec0> Setting resize port 61 to enabled
0:00:33.881093404  3267 0x7251acf0 INFO                     omx gstomx.c:1912:gst_omx_port_set_enabled_unlocked:<omxh264dec-omxh264dec0> Set resize port 61 to enabled: None (0x00000000)
0:00:33.881508665  3267 0x7251acf0 INFO                     omx gstomx.c:1631:gst_omx_port_allocate_buffers_unlocked:<omxh264dec-omxh264dec0> Allocating 4 buffers of size 3686400 for resize port 61
0:00:33.882866012  3267 0x7251acf0 INFO                     omx gstomx.c:1688:gst_omx_port_allocate_buffers_unlocked:<omxh264dec-omxh264dec0> Allocated buffers for resize port 61: None (0x00000000)
0:00:33.883388096  3267 0x7251acf0 INFO                     omx gstomx.c:2153:gst_omx_port_wait_enabled_unlocked:<omxh264dec-omxh264dec0> Waiting for resize port 61 to be enabled
0:00:33.884132108  3267 0x7251acf0 INFO                     omx gstomx.c:2228:gst_omx_port_wait_enabled_unlocked:<omxh264dec-omxh264dec0> resize port 61 is enabled: None (0x00000000)
0:00:33.884641380  3267 0x7251acf0 INFO                     omx gstomx.c:756:gst_omx_component_set_state:<omxh264dec-omxh264dec0> Setting resize state from Idle to Executing
0:00:33.885981852  3267 0x7251acf0 INFO                     omx gstomx.c:225:gst_omx_component_handle_messages:<omxh264dec-omxh264dec0> resize state change to Executing finished
0:00:33.888384879  3267 0x7251acf0 INFO                     omx gstomx.c:1864:gst_omx_port_set_enabled_unlocked:<omxh264dec-omxh264dec0> Setting video_decode port 131 to enabled
0:00:33.890767749  3267 0x7251acf0 INFO                     omx gstomx.c:1912:gst_omx_port_set_enabled_unlocked:<omxh264dec-omxh264dec0> Set video_decode port 131 to enabled: None (0x00000000)
0:00:33.891297437  3267 0x7251acf0 INFO                     omx gstomx.c:2153:gst_omx_port_wait_enabled_unlocked:<omxh264dec-omxh264dec0> Waiting for video_decode port 131 to be enabled
0:00:33.891872386  3267 0x7251acf0 INFO                     omx gstomx.c:2228:gst_omx_port_wait_enabled_unlocked:<omxh264dec-omxh264dec0> video_decode port 131 is enabled: None (0x00000000)
0:00:33.892013897  3267 0x7251acf0 INFO                     omx gstomx.c:2277:gst_omx_port_mark_reconfigured:<omxh264dec-omxh264dec0> Marking video_decode port 131 is reconfigured
0:00:33.892395929  3267 0x7251acf0 INFO                     omx gstomx.c:2304:gst_omx_port_mark_reconfigured:<omxh264dec-omxh264dec0> Marked video_decode port 131 as reconfigured: None (0x00000000)
0:00:33.892774159  3267 0x7251acf0 INFO                     omx gstomx.c:2277:gst_omx_port_mark_reconfigured:<omxh264dec-omxh264dec0> Marking resize port 61 is reconfigured
0:00:33.927247624  3267 0x7251acf0 INFO                     omx gstomx.c:2304:gst_omx_port_mark_reconfigured:<omxh264dec-omxh264dec0> Marked resize port 61 as reconfigured: None (0x00000000)
0:00:47.374042603  3267  0x1c1aa00 INFO                     omx gstomx.c:756:gst_omx_component_set_state:<omxh264dec-omxh264dec0> Setting video_decode state from Executing to Idle
0:00:47.374558073  3267  0x1c1aa00 INFO                     omx gstomx.c:225:gst_omx_component_handle_messages:<omxh264dec-omxh264dec0> video_decode state change to Idle finished
0:00:47.374724011  3267  0x1c1aa00 INFO                     omx gstomx.c:756:gst_omx_component_set_state:<omxh264dec-omxh264dec0> Setting resize state from Executing to Idle
0:00:47.375073491  3267  0x1c1aa00 INFO                     omx gstomx.c:225:gst_omx_component_handle_messages:<omxh264dec-omxh264dec0> resize state change to Idle finished
0:00:47.375230262  3267  0x1c1aa00 INFO                     omx gstomx.c:756:gst_omx_component_set_state:<omxh264dec-omxh264dec0> Setting resize state from Idle to Loaded
0:00:47.375550159  3267  0x1c1aa00 INFO                     omx gstomx.c:756:gst_omx_component_set_state:<omxh264dec-omxh264dec0> Setting video_decode state from Idle to Loaded
0:00:47.375897660  3267  0x1c1aa00 INFO                     omx gstomx.c:1755:gst_omx_port_deallocate_buffers_unlocked:<omxh264dec-omxh264dec0> Deallocating buffers of video_decode port 130
0:00:47.379903190  3267  0x1c1aa00 INFO                     omx gstomx.c:225:gst_omx_component_handle_messages:<omxh264dec-omxh264dec0> video_decode state change to Loaded finished
0:00:47.387307321  3267  0x1c1aa00 INFO                     omx gstomx.c:1755:gst_omx_port_deallocate_buffers_unlocked:<omxh264dec-omxh264dec0> Deallocating buffers of resize port 61
0:00:47.388474876  3267  0x1c1aa00 INFO                     omx gstomx.c:225:gst_omx_component_handle_messages:<omxh264dec-omxh264dec0> resize state change to Loaded finished
0:00:47.394478431  3267  0x1c1aa00 INFO                     omx gstomx.c:707:gst_omx_component_free:<omxh264dec-omxh264dec0> Unloading component 0x72547060 video_decode
0:00:47.394702442  3267  0x1c1aa00 INFO                     omx gstomx.c:1755:gst_omx_port_deallocate_buffers_unlocked:<omxh264dec-omxh264dec0> Deallocating buffers of video_decode port 130
0:00:47.395121506  3267  0x1c1aa00 INFO                     omx gstomx.c:1755:gst_omx_port_deallocate_buffers_unlocked:<omxh264dec-omxh264dec0> Deallocating buffers of video_decode port 131
0:00:47.395798486  3267  0x1c1aa00 INFO                     omx gstomx.c:707:gst_omx_component_free:<omxh264dec-omxh264dec0> Unloading component 0x72547000 egl_render
0:00:47.395995518  3267  0x1c1aa00 INFO                     omx gstomx.c:1755:gst_omx_port_deallocate_buffers_unlocked:<omxh264dec-omxh264dec0> Deallocating buffers of egl_render port 220
0:00:47.396345467  3267  0x1c1aa00 INFO                     omx gstomx.c:1755:gst_omx_port_deallocate_buffers_unlocked:<omxh264dec-omxh264dec0> Deallocating buffers of egl_render port 221
0:00:47.396909687  3267  0x1c1aa00 INFO                     omx gstomx.c:707:gst_omx_component_free:<omxh264dec-omxh264dec0> Unloading component 0x7250e780 resize
0:00:47.397048541  3267  0x1c1aa00 INFO                     omx gstomx.c:1755:gst_omx_port_deallocate_buffers_unlocked:<omxh264dec-omxh264dec0> Deallocating buffers of resize port 60
0:00:47.397366928  3267  0x1c1aa00 INFO                     omx gstomx.c:1755:gst_omx_port_deallocate_buffers_unlocked:<omxh264dec-omxh264dec0> Deallocating buffers of resize port 61
Error: "Internal data stream error."



More information about the Development mailing list