[haiku-commits] r33678 - in haiku/trunk/src/apps/mediaplayer: . media_node_framework media_node_framework/audio

  • From: superstippi@xxxxxx
  • To: haiku-commits@xxxxxxxxxxxxx
  • Date: Tue, 20 Oct 2009 16:12:13 +0200 (CEST)

Author: stippi
Date: 2009-10-20 16:12:12 +0200 (Tue, 20 Oct 2009)
New Revision: 33678
Changeset: http://dev.haiku-os.org/changeset/33678/haiku

Modified:
   haiku/trunk/src/apps/mediaplayer/Controller.cpp
   haiku/trunk/src/apps/mediaplayer/media_node_framework/NodeManager.cpp
   haiku/trunk/src/apps/mediaplayer/media_node_framework/NodeManager.h
   haiku/trunk/src/apps/mediaplayer/media_node_framework/audio/AudioAdapter.cpp
   
haiku/trunk/src/apps/mediaplayer/media_node_framework/audio/AudioChannelConverter.cpp
   haiku/trunk/src/apps/mediaplayer/media_node_framework/audio/AudioProducer.cpp
   haiku/trunk/src/apps/mediaplayer/media_node_framework/audio/AudioProducer.h
Log:
All sorts of refactoring with regards to the audio node and format setup. At
first I tried adding support for changing the format during running the node
connection, but later found out that this is not implemented in the system
mixer (it has this weird setting to allow input format changes, but if you
do this, the media_server will just crash, since the backend does not support
it yet). Also, the Media Kit documentation is extremely lacking in this regard.
I ended up re-establishing the node connection when the audio format is
supposed to change, just like it is already done for video. This means that
audio files now play with their native channel count and frame rate. But it
isn't so well tested yet, if 48 kHz for example introduce some clicks. The
channel count should not be a problem though, I've also tested that with some
movies and it works fine.


Modified: haiku/trunk/src/apps/mediaplayer/Controller.cpp
===================================================================
--- haiku/trunk/src/apps/mediaplayer/Controller.cpp     2009-10-20 09:59:09 UTC 
(rev 33677)
+++ haiku/trunk/src/apps/mediaplayer/Controller.cpp     2009-10-20 14:12:12 UTC 
(rev 33678)
@@ -295,7 +295,7 @@
        int height;
        GetSize(&width, &height);
        color_space preferredVideoFormat = B_NO_COLOR_SPACE;
-       if (fVideoTrackSupplier) {
+       if (fVideoTrackSupplier != NULL) {
                const media_format& format = fVideoTrackSupplier->Format();
                preferredVideoFormat = format.u.raw_video.display.format;
        }
@@ -308,13 +308,22 @@
        else
                enabledNodes = AUDIO_AND_VIDEO;
 
+       float audioFrameRate = 44100.0f;
+       uint32 audioChannels = 2;
+       if (fAudioTrackSupplier != NULL) {
+               const media_format& audioTrackFormat = 
fAudioTrackSupplier->Format();
+               audioFrameRate = audioTrackFormat.u.raw_audio.frame_rate;
+               audioChannels = audioTrackFormat.u.raw_audio.channel_count;
+       }
+
        if (InitCheck() != B_OK) {
                Init(BRect(0, 0, width - 1, height - 1), fVideoFrameRate,
-                       preferredVideoFormat, LOOPING_ALL, false, 1.0, 
enabledNodes,
-                       useOverlays);
+                       preferredVideoFormat, audioFrameRate, audioChannels, 
LOOPING_ALL,
+                       false, 1.0, enabledNodes, useOverlays);
        } else {
                FormatChanged(BRect(0, 0, width - 1, height - 1), 
fVideoFrameRate,
-                       preferredVideoFormat, enabledNodes, useOverlays);
+                       preferredVideoFormat, audioFrameRate, audioChannels, 
enabledNodes,
+                       useOverlays);
        }
 
        _NotifyFileChanged();

Modified: haiku/trunk/src/apps/mediaplayer/media_node_framework/NodeManager.cpp
===================================================================
--- haiku/trunk/src/apps/mediaplayer/media_node_framework/NodeManager.cpp       
2009-10-20 09:59:09 UTC (rev 33677)
+++ haiku/trunk/src/apps/mediaplayer/media_node_framework/NodeManager.cpp       
2009-10-20 14:12:12 UTC (rev 33678)
@@ -66,8 +66,9 @@
 // Init
 status_t
 NodeManager::Init(BRect videoBounds, float videoFrameRate,
-       color_space preferredVideoFormat, int32 loopingMode,
-       bool loopingEnabled, float speed, uint32 enabledNodes, bool useOverlays)
+       color_space preferredVideoFormat, float audioFrameRate,
+       uint32 audioChannels, int32 loopingMode, bool loopingEnabled,
+       float speed, uint32 enabledNodes, bool useOverlays)
 {
        // init base class
        PlaybackManager::Init(videoFrameRate, loopingMode, loopingEnabled, 
speed);
@@ -83,7 +84,7 @@
                fAudioSupplier = CreateAudioSupplier();
 
        return FormatChanged(videoBounds, videoFrameRate, preferredVideoFormat,
-               enabledNodes, useOverlays, true);
+               audioFrameRate, audioChannels, enabledNodes, useOverlays, true);
 }
 
 // InitCheck
@@ -118,8 +119,8 @@
 // FormatChanged
 status_t
 NodeManager::FormatChanged(BRect videoBounds, float videoFrameRate,
-       color_space preferredVideoFormat, uint32 enabledNodes, bool useOverlays,
-       bool force)
+       color_space preferredVideoFormat, float audioFrameRate,
+       uint32 audioChannels, uint32 enabledNodes, bool useOverlays, bool force)
 {
        TRACE("NodeManager::FormatChanged()\n");
 
@@ -144,7 +145,7 @@
        SetVideoBounds(videoBounds);
 
        status_t ret = _SetUpNodes(preferredVideoFormat, enabledNodes,
-               useOverlays);
+               useOverlays, audioFrameRate, audioChannels);
        if (ret == B_OK)
                _StartNodes();
        else
@@ -253,7 +254,7 @@
 // _SetUpNodes
 status_t
 NodeManager::_SetUpNodes(color_space preferredVideoFormat, uint32 enabledNodes,
-       bool useOverlays)
+       bool useOverlays, float audioFrameRate, uint32 audioChannels)
 {
        TRACE("NodeManager::_SetUpNodes()\n");
 
@@ -289,7 +290,7 @@
        
        // setup the audio nodes
        if (enabledNodes != VIDEO_ONLY) {
-               fStatus = _SetUpAudioNodes();
+               fStatus = _SetUpAudioNodes(audioFrameRate, audioChannels);
                if (fStatus != B_OK) {
                        print_error("Error setting up audio nodes", fStatus);
                        fMediaRoster->Unlock();
@@ -445,7 +446,7 @@
 
 // _SetUpAudioNodes
 status_t
-NodeManager::_SetUpAudioNodes()
+NodeManager::_SetUpAudioNodes(float audioFrameRate, uint32 audioChannels)
 {
        fAudioProducer = new AudioProducer("MediaPlayer Audio Out", 
fAudioSupplier);
        fAudioProducer->SetPeakListener(fPeakListener);
@@ -489,11 +490,13 @@
        }
 
        // got the endpoints; now we connect it!
-       media_format audio_format;
-       audio_format.type = B_MEDIA_RAW_AUDIO;  
-       audio_format.u.raw_audio = media_raw_audio_format::wildcard;
+       media_format audioFormat;
+       audioFormat.type = B_MEDIA_RAW_AUDIO;
+       audioFormat.u.raw_audio = media_raw_audio_format::wildcard;
+       audioFormat.u.raw_audio.frame_rate = audioFrameRate;
+       audioFormat.u.raw_audio.channel_count = audioChannels;
        fStatus = fMediaRoster->Connect(soundOutput.source, 
mixerInput.destination,
-               &audio_format, &soundOutput, &mixerInput);
+               &audioFormat, &soundOutput, &mixerInput);
        if (fStatus != B_OK) {
                print_error("unable to connect audio nodes", fStatus);
                return fStatus;
@@ -502,7 +505,7 @@
        // the inputs and outputs might have been reassigned during the
        // nodes' negotiation of the Connect().  That's why we wait until
        // after Connect() finishes to save their contents.
-       fAudioConnection.format = audio_format;
+       fAudioConnection.format = audioFormat;
        fAudioConnection.source = soundOutput.source;
        fAudioConnection.destination = mixerInput.destination;
        fAudioConnection.connected = true;
@@ -694,7 +697,6 @@
        }
 
        if (fAudioProducer) {
-               fAudioProducer->SetRunning(true);
                status = fMediaRoster->StartNode(fAudioConnection.producer, 
perf);
                if (status != B_OK) {
                        print_error("Can't start the audio producer", status);
@@ -715,27 +717,19 @@
 NodeManager::_StopNodes()
 {
        TRACE("NodeManager::_StopNodes()\n");
-//     if (PlayMode() == MODE_PLAYING_PAUSED_FORWARD
-//             || PlayMode() == MODE_PLAYING_PAUSED_FORWARD)
-//             return;
        fMediaRoster = BMediaRoster::Roster();
-       if (!fMediaRoster) {
-               if (fAudioProducer)
-                       fAudioProducer->SetRunning(false);
-               return;
-       } else if (fMediaRoster->Lock()) {
+       if (fMediaRoster != NULL && fMediaRoster->Lock()) {
                // begin mucking with the media roster
-               if (fVideoProducer) {
+               if (fVideoProducer != NULL) {
                        TRACE("  stopping video producer...\n");
                        fMediaRoster->StopNode(fVideoConnection.producer, 0, 
true);
                }
-               if (fAudioProducer) {
+               if (fAudioProducer != NULL) {
                        TRACE("  stopping audio producer...\n");
-                       fAudioProducer->SetRunning(false);
                        fMediaRoster->StopNode(fAudioConnection.producer, 0, 
true);
                                // synchronous stop
                }
-               if (fVideoConsumer) {
+               if (fVideoConsumer != NULL) {
                        TRACE("  stopping video consumer...\n");
                        fMediaRoster->StopNode(fVideoConnection.consumer, 0, 
true);
                }

Modified: haiku/trunk/src/apps/mediaplayer/media_node_framework/NodeManager.h
===================================================================
--- haiku/trunk/src/apps/mediaplayer/media_node_framework/NodeManager.h 
2009-10-20 09:59:09 UTC (rev 33677)
+++ haiku/trunk/src/apps/mediaplayer/media_node_framework/NodeManager.h 
2009-10-20 14:12:12 UTC (rev 33678)
@@ -40,10 +40,9 @@
 
                        status_t                        Init(BRect videoBounds, 
float videoFrameRate,
                                                                        
color_space preferredVideoFormat,
-                                                                       int32 
loopingMode,
-                                                                       bool 
loopingEnabled,
-                                                                       float 
speed,
-                                                                       uint32 
enabledNodes,
+                                                                       float 
audioFrameRate, uint32 audioChannels,
+                                                                       int32 
loopingMode, bool loopingEnabled,
+                                                                       float 
speed, uint32 enabledNodes,
                                                                        bool 
useOverlays);
                        status_t                        InitCheck();
                                                                // only call 
this if the
@@ -53,9 +52,11 @@
                        status_t                        FormatChanged(BRect 
videoBounds,
                                                                        float 
videoFrameRate,
                                                                        
color_space preferredVideoFormat,
+                                                                       float 
audioFrameRate, uint32 audioChannels,
                                                                        uint32 
enabledNodes,
                                                                        bool 
useOverlays,
                                                                        bool 
force = false);
+
        virtual void                            SetPlayMode(int32 mode,
                                                                        bool 
continuePlaying = true);
                                                                        
@@ -76,11 +77,14 @@
 
  private:
                        status_t                        _SetUpNodes(color_space 
preferredVideoFormat,
-                                                                       uint32 
enabledNodes, bool useOverlays);
+                                                                       uint32 
enabledNodes, bool useOverlays,
+                                                                       float 
audioFrameRate,
+                                                                       uint32 
audioChannels);
                        status_t                        _SetUpVideoNodes(
                                                                        
color_space preferredVideoFormat,
                                                                        bool 
useOverlays);
-                       status_t                        _SetUpAudioNodes();
+                       status_t                        _SetUpAudioNodes(float 
audioFrameRate,
+                                                                       uint32 
audioChannels);
                        status_t                        _TearDownNodes(bool 
disconnect = true);
                        status_t                        _StartNodes();
                        void                            _StopNodes();

Modified: 
haiku/trunk/src/apps/mediaplayer/media_node_framework/audio/AudioAdapter.cpp
===================================================================
--- 
haiku/trunk/src/apps/mediaplayer/media_node_framework/audio/AudioAdapter.cpp    
    2009-10-20 09:59:09 UTC (rev 33677)
+++ 
haiku/trunk/src/apps/mediaplayer/media_node_framework/audio/AudioAdapter.cpp    
    2009-10-20 14:12:12 UTC (rev 33678)
@@ -55,7 +55,9 @@
 
                if (fFormat.u.raw_audio.channel_count
                                != source->Format().u.raw_audio.channel_count) {
-                       TRACE("AudioAdapter() - using channel converter\n");
+                       TRACE("AudioAdapter() - using channel converter (%ld -> 
%ld)\n",
+                               source->Format().u.raw_audio.channel_count,
+                               fFormat.u.raw_audio.channel_count);
                        fChannelConverter = new (nothrow) 
AudioChannelConverter(source,
                                fFormat);
                        source = fChannelConverter;

Modified: 
haiku/trunk/src/apps/mediaplayer/media_node_framework/audio/AudioChannelConverter.cpp
===================================================================
--- 
haiku/trunk/src/apps/mediaplayer/media_node_framework/audio/AudioChannelConverter.cpp
       2009-10-20 09:59:09 UTC (rev 33677)
+++ 
haiku/trunk/src/apps/mediaplayer/media_node_framework/audio/AudioChannelConverter.cpp
       2009-10-20 14:12:12 UTC (rev 33678)
@@ -40,6 +40,8 @@
 {
        // TODO: more conversions!
        switch (inChannels) {
+               case 0:
+                       break;
                case 1:
                        switch (outChannels) {
                                case 2:
@@ -61,13 +63,13 @@
                                        break;
                        }
                        break;
-               case 5:
+               default:
                        switch (outChannels) {
                                case 2:
                                        for (int32 i = 0; i < frames; i++) {
                                                outBuffer[0] = inBuffer[0];
                                                outBuffer[1] = inBuffer[1];
-                                               inBuffer += 5;
+                                               inBuffer += outChannels;
                                                outBuffer += 2;
                                        }
                                        break;

Modified: 
haiku/trunk/src/apps/mediaplayer/media_node_framework/audio/AudioProducer.cpp
===================================================================
--- 
haiku/trunk/src/apps/mediaplayer/media_node_framework/audio/AudioProducer.cpp   
    2009-10-20 09:59:09 UTC (rev 33677)
+++ 
haiku/trunk/src/apps/mediaplayer/media_node_framework/audio/AudioProducer.cpp   
    2009-10-20 14:12:12 UTC (rev 33678)
@@ -1,10 +1,12 @@
-/*     Copyright (c) 1998-99, Be Incorporated, All Rights Reserved.
- *     Distributed under the terms of the Be Sample Code license.
+/*
+ * Copyright (c) 1998-99, Be Incorporated, All Rights Reserved.
+ * Distributed under the terms of the Be Sample Code license.
  *
- *     Copyright (c) 2000-2008, Ingo Weinhold <ingo_weinhold@xxxxxx>,
- *     Copyright (c) 2000-2008, Stephan Aßmus <superstippi@xxxxxx>,
- *     All Rights Reserved. Distributed under the terms of the MIT license.
+ * Copyright (c) 2000-2008, Ingo Weinhold <ingo_weinhold@xxxxxx>,
+ * Copyright (c) 2000-2008, Stephan Aßmus <superstippi@xxxxxx>,
+ * All Rights Reserved. Distributed under the terms of the MIT license.
  */
+
 #include "AudioProducer.h"
 
 #include <math.h>
@@ -32,13 +34,15 @@
 
 
 // debugging
-//#define TRACE_AUDIO_PRODUCER
+#define TRACE_AUDIO_PRODUCER
 #ifdef TRACE_AUDIO_PRODUCER
-# define TRACE(x...)   printf(x)
-# define ERROR(x...)   fprintf(stderr, x)
+# define TRACE(x...)           printf(x)
+# define TRACE_BUFFER(x...)
+# define ERROR(x...)           fprintf(stderr, x)
 #else
 # define TRACE(x...)
-# define ERROR(x...)   fprintf(stderr, x)
+# define TRACE_BUFFER(x...)
+# define ERROR(x...)           fprintf(stderr, x)
 #endif
 
 
@@ -96,7 +100,6 @@
          fFramesSent(0),
          fStartTime(0),
          fSupplier(supplier),
-         fRunning(false),
 
          fPeakListener(NULL)
 {
@@ -175,15 +178,12 @@
        if (!_format)
                return B_BAD_VALUE;
 
-       // this is the format we'll be returning (our preferred format)
+       // This is the format we'll be returning (our preferred format)
        *_format = fPreferredFormat;
 
-       // a wildcard type is okay; we can specialize it
-       if (type == B_MEDIA_UNKNOWN_TYPE)
-               type = B_MEDIA_RAW_AUDIO;
-
-       // we only support raw audio
-       if (type != B_MEDIA_RAW_AUDIO)
+       // A wildcard type is okay; we can specialize it, otherwise only raw 
audio
+       // is supported
+       if (type != B_MEDIA_UNKNOWN_TYPE && type != B_MEDIA_RAW_AUDIO)
                return B_MEDIA_BAD_FORMAT;
 
        return B_OK;
@@ -200,20 +200,28 @@
                return B_MEDIA_BAD_SOURCE;
        }
 
-       // TODO: we might want to support different audio formats
-       // we only support floating-point raw audio, so we always return that, 
but
-       // we supply an error code depending on whether we found the proposal
-       // acceptable.
-       media_type requestedType = format->type;
-       *format = fPreferredFormat;
-
-       // raw audio or wildcard type, either is okay by us
-       if (requestedType != B_MEDIA_UNKNOWN_TYPE
-               && requestedType != B_MEDIA_RAW_AUDIO) {
+       // Raw audio or wildcard type, either is okay by us. If the format is
+       // anything else, overwrite it with our preferred format. Also, we only 
support
+       // floating point audio in the host native byte order at the moment.
+       if ((format->type != B_MEDIA_UNKNOWN_TYPE
+                       && format->type != B_MEDIA_RAW_AUDIO)
+               || (format->u.raw_audio.format
+                               != media_raw_audio_format::wildcard.format
+                       && format->u.raw_audio.format
+                               != fPreferredFormat.u.raw_audio.format)
+               || (format->u.raw_audio.byte_order
+                               != media_raw_audio_format::wildcard.byte_order
+                       && format->u.raw_audio.byte_order
+                               != fPreferredFormat.u.raw_audio.byte_order)) {
                TRACE("  -> B_MEDIA_BAD_FORMAT\n");
+               *format = fPreferredFormat;
                return B_MEDIA_BAD_FORMAT;
        }
 
+       format->type = B_MEDIA_RAW_AUDIO;
+       format->u.raw_audio.format = fPreferredFormat.u.raw_audio.format;
+       format->u.raw_audio.byte_order = 
fPreferredFormat.u.raw_audio.byte_order;
+
        return B_OK;
 }
 
@@ -235,13 +243,10 @@
                return B_MEDIA_BAD_SOURCE;
        }
 
-       fOutput.format = *ioFormat;
-       
-       // notify our audio supplier of the format change
-       if (fSupplier)
-               fSupplier->SetFormat(fOutput.format);
+// TODO: Maybe we are supposed to specialize here only and not actually change 
yet?
+//     status_t ret = _SpecializeFormat(ioFormat);
 
-       return _AllocateBuffers(ioFormat);
+       return ChangeFormat(ioFormat);
 }
 
 
@@ -333,52 +338,19 @@
                return B_MEDIA_ALREADY_CONNECTED;
        }
 
-       // the format may not yet be fully specialized (the consumer might have
-       // passed back some wildcards).  Finish specializing it now, and return 
an
-       // error if we don't support the requested format.
-       if (format->type != B_MEDIA_RAW_AUDIO) {
-               TRACE("  -> B_MEDIA_BAD_FORMAT\n");
-               return B_MEDIA_BAD_FORMAT;
-// TODO: we might want to support different audio formats
-       } else if (format->u.raw_audio.format
-                       != fPreferredFormat.u.raw_audio.format) {
-               TRACE("  -> B_MEDIA_BAD_FORMAT\n");
-               return B_MEDIA_BAD_FORMAT;
+       status_t ret = _SpecializeFormat(format);
+       if (ret != B_OK) {
+               TRACE("  -> format error: %s\n", strerror(ret));
+               return ret;
        }
 
-       if (format->u.raw_audio.channel_count
-               == media_raw_audio_format::wildcard.channel_count) {
-               format->u.raw_audio.channel_count = 2;
-               TRACE("  -> adjusting channel count, it was wildcard\n");
-       }
-       if (format->u.raw_audio.frame_rate
-               == media_raw_audio_format::wildcard.frame_rate) {
-               format->u.raw_audio.frame_rate = 44100.0;
-               TRACE("  -> adjusting frame rate, it was wildcard\n");
-       }
-
-       // check the buffer size, which may still be wildcarded
-       if (format->u.raw_audio.buffer_size
-               == media_raw_audio_format::wildcard.buffer_size) {
-               // pick something comfortable to suggest
-               TRACE("  -> adjusting buffer size, it was wildcard\n");
-
-               // NOTE: the (buffer_size * 1000000) needs to be dividable by
-               // format->u.raw_audio.frame_rate! (We assume frame rate is a 
multiple of
-               // 25, which it usually is.)
-               format->u.raw_audio.buffer_size
-                       = uint32(format->u.raw_audio.frame_rate / 25.0)
-                               * (format->u.raw_audio.format
-                                       & 
media_raw_audio_format::B_AUDIO_SIZE_MASK);
-       
-               if (!fLowLatency)
-                       format->u.raw_audio.buffer_size *= 3;
-
-       }
-
        // Now reserve the connection, and return information about it
        fOutput.destination = where;
        fOutput.format = *format;
+
+       if (fSupplier != NULL)
+               fSupplier->SetFormat(fOutput.format);
+
        *_source = fOutput.source;
        strncpy(_name, fOutput.name, B_MEDIA_NAME_LENGTH);
        TRACE("  -> B_OK\n");
@@ -479,8 +451,8 @@
        // us a buffer group (via SetBufferGroup()) prior to this.  That can
        // happen, for example, if the consumer calls SetOutputBuffersFor() on
        // us from within its Connected() method.
-       if (!fBufferGroup)
-               _AllocateBuffers(&fOutput.format);
+       if (fBufferGroup == NULL)
+               _AllocateBuffers(fOutput.format);
 
        TRACE("AudioProducer::Connect() done\n");
 }
@@ -615,7 +587,7 @@
 AudioProducer::HandleEvent(const media_timed_event* event, bigtime_t lateness,
        bool realTimeEvent)
 {
-       TRACE("%p->AudioProducer::HandleEvent()\n", this);
+       TRACE_BUFFER("%p->AudioProducer::HandleEvent()\n", this);
 
        switch (event->type) {
                case BTimedEventQueue::B_START:
@@ -639,7 +611,7 @@
                        break;
        
                case BTimedEventQueue::B_HANDLE_BUFFER: {
-                       TRACE("AudioProducer::HandleEvent(B_HANDLE_BUFFER)\n");
+                       
TRACE_BUFFER("AudioProducer::HandleEvent(B_HANDLE_BUFFER)\n");
                        if ((RunState() == BMediaEventLooper::B_STARTED)
                                && (fOutput.destination != 
media_destination::null)) {
                                BBuffer* buffer = 
_FillNextBuffer(event->event_time);
@@ -665,9 +637,9 @@
                                        BTimedEventQueue::B_HANDLE_BUFFER);
                                EventQueue()->AddEvent(nextBufferEvent);
                        } else {
-                               fprintf(stderr, "B_HANDLE_BUFFER, but not 
started!\n");
+                               ERROR("B_HANDLE_BUFFER, but not started!\n");
                        }
-                       TRACE("AudioProducer::HandleEvent(B_HANDLE_BUFFER) 
done\n");
+                       
TRACE_BUFFER("AudioProducer::HandleEvent(B_HANDLE_BUFFER) done\n");
                        break;
                }
                default:
@@ -677,18 +649,38 @@
 
 
 void
-AudioProducer::SetRunning(bool running)
+AudioProducer::SetPeakListener(BHandler* handler)
 {
-       TRACE("%p->AudioProducer::SetRunning(%d)\n", this, running);
-
-       fRunning = running;
+       fPeakListener = handler;
 }
 
 
-void
-AudioProducer::SetPeakListener(BHandler* handler)
+status_t
+AudioProducer::ChangeFormat(media_format* format)
 {
-       fPeakListener = handler;
+       TRACE("AudioProducer::ChangeFormat()\n");
+
+       format->u.raw_audio.buffer_size = 
media_raw_audio_format::wildcard.buffer_size;
+
+       status_t ret = _SpecializeFormat(format);
+       if (ret != B_OK) {
+               TRACE("  _SpecializeFormat(): %s\n", strerror(ret));
+               return ret;
+       }
+
+       ret = BBufferProducer::ProposeFormatChange(format, fOutput.destination);
+       if (ret != B_OK) {
+               TRACE("  ProposeFormatChange(): %s\n", strerror(ret));
+               return ret;
+       }
+
+       ret = BBufferProducer::ChangeFormat(fOutput.source, 
fOutput.destination, format);
+       if (ret != B_OK) {
+               TRACE("  ChangeFormat(): %s\n", strerror(ret));
+               return ret;
+       }
+
+       return _ChangeFormat(*format);
 }
 
 
@@ -696,15 +688,79 @@
 
 
 status_t
-AudioProducer::_AllocateBuffers(media_format* format)
+AudioProducer::_SpecializeFormat(media_format* format)
 {
+       // the format may not yet be fully specialized (the consumer might have
+       // passed back some wildcards).  Finish specializing it now, and return 
an
+       // error if we don't support the requested format.
+       if (format->type != B_MEDIA_RAW_AUDIO) {
+               TRACE("  not raw audio\n");
+               return B_MEDIA_BAD_FORMAT;
+// TODO: we might want to support different audio formats
+       } else if (format->u.raw_audio.format
+                       != fPreferredFormat.u.raw_audio.format) {
+               TRACE("  format does not match\n");
+               return B_MEDIA_BAD_FORMAT;
+       }
+
+       if (format->u.raw_audio.channel_count
+               == media_raw_audio_format::wildcard.channel_count) {
+               format->u.raw_audio.channel_count = 2;
+               TRACE("  -> adjusting channel count, it was wildcard\n");
+       }
+
+       if (format->u.raw_audio.frame_rate
+               == media_raw_audio_format::wildcard.frame_rate) {
+               format->u.raw_audio.frame_rate = 44100.0;
+               TRACE("  -> adjusting frame rate, it was wildcard\n");
+       }
+
+       // check the buffer size, which may still be wildcarded
+       if (format->u.raw_audio.buffer_size
+               == media_raw_audio_format::wildcard.buffer_size) {
+               // pick something comfortable to suggest
+               TRACE("  -> adjusting buffer size, it was wildcard\n");
+
+               // NOTE: the (buffer_size * 1000000) needs to be dividable by
+               // format->u.raw_audio.frame_rate! (We assume frame rate is a 
multiple of
+               // 25, which it usually is.)
+               format->u.raw_audio.buffer_size
+                       = uint32(format->u.raw_audio.frame_rate / 25.0)
+                               * (format->u.raw_audio.format
+                                       & 
media_raw_audio_format::B_AUDIO_SIZE_MASK);
+       
+               if (!fLowLatency)
+                       format->u.raw_audio.buffer_size *= 3;
+
+       }
+
+       return B_OK;
+}
+
+
+status_t
+AudioProducer::_ChangeFormat(const media_format& format)
+{
+       fOutput.format = format;
+
+       // notify our audio supplier of the format change
+       if (fSupplier)
+               fSupplier->SetFormat(format);
+
+       return _AllocateBuffers(format);
+}
+
+
+status_t
+AudioProducer::_AllocateBuffers(const media_format& format)
+{
        TRACE("%p->AudioProducer::_AllocateBuffers()\n", this);
 
        if (fBufferGroup && fUsingOurBuffers) {
                delete fBufferGroup;
                fBufferGroup = NULL;
        }
-       size_t size = format->u.raw_audio.buffer_size;
+       size_t size = format.u.raw_audio.buffer_size;
        int32 bufferDuration = BufferDuration();
        int32 count = 0;
        if (bufferDuration > 0) {

Modified: 
haiku/trunk/src/apps/mediaplayer/media_node_framework/audio/AudioProducer.h
===================================================================
--- haiku/trunk/src/apps/mediaplayer/media_node_framework/audio/AudioProducer.h 
2009-10-20 09:59:09 UTC (rev 33677)
+++ haiku/trunk/src/apps/mediaplayer/media_node_framework/audio/AudioProducer.h 
2009-10-20 14:12:12 UTC (rev 33678)
@@ -98,13 +98,15 @@
                                                                        
bigtime_t lateness,
                                                                        bool 
realTimeEvent = false);
 
-                       void                            SetRunning(bool 
running);
-
        // AudioProducer
                        void                            
SetPeakListener(BHandler* handler);
 
+                       status_t                        
ChangeFormat(media_format* format);
+
 private:
-                       status_t                        
_AllocateBuffers(media_format* format);
+                       status_t                        
_SpecializeFormat(media_format* format);
+                       status_t                        _ChangeFormat(const 
media_format& format);
+                       status_t                        _AllocateBuffers(const 
media_format& format);
                        BBuffer*                        
_FillNextBuffer(bigtime_t eventTime);
 
                        void                            
_FillSampleBuffer(float* data,
@@ -123,7 +125,6 @@
                        bigtime_t                       fStartTime;
 
                        AudioSupplier*          fSupplier;
-       volatile bool                           fRunning;
 
                        BHandler*                       fPeakListener;
 };


Other related posts:

  • » [haiku-commits] r33678 - in haiku/trunk/src/apps/mediaplayer: . media_node_framework media_node_framework/audio - superstippi