Index: /pjproject/branches/1.x/pjmedia/include/pjmedia-audiodev/config.h
===================================================================
--- /pjproject/branches/1.x/pjmedia/include/pjmedia-audiodev/config.h	(revision 3747)
+++ /pjproject/branches/1.x/pjmedia/include/pjmedia-audiodev/config.h	(revision 3748)
@@ -146,4 +146,19 @@
 
 /**
+ * This setting controls whether the Symbian audio with built-in multimedia
+ * framework backend should be started synchronously. Note that synchronous
+ * start will block the application/UI, e.g: about 40ms for each direction
+ * on N95. While asynchronous start may cause invalid value (always zero)
+ * returned in input/output volume query, if the query is performed when
+ * the internal start procedure is not completely finished.
+ * 
+ * Default: 1 (yes)
+ */
+#ifndef PJMEDIA_AUDIO_DEV_MDA_USE_SYNC_START
+#   define PJMEDIA_AUDIO_DEV_MDA_USE_SYNC_START	1
+#endif
+
+
+/**
  * This setting controls whether the Audio Device API should support
  * device implementation that is based on the old sound device API
Index: /pjproject/branches/1.x/pjmedia/src/pjmedia-audiodev/symb_mda_dev.cpp
===================================================================
--- /pjproject/branches/1.x/pjmedia/src/pjmedia-audiodev/symb_mda_dev.cpp	(revision 3747)
+++ /pjproject/branches/1.x/pjmedia/src/pjmedia-audiodev/symb_mda_dev.cpp	(revision 3748)
@@ -240,4 +240,5 @@
     TInt		     lastError_;
     pj_uint32_t		     timeStamp_;
+    CActiveSchedulerWait     startAsw_;
 
     // cache variable
@@ -364,4 +365,11 @@
     iInputStream_->Open(&iStreamSettings);
     
+#if defined(PJMEDIA_AUDIO_DEV_MDA_USE_SYNC_START) && \
+    PJMEDIA_AUDIO_DEV_MDA_USE_SYNC_START != 0
+    
+    startAsw_.Start();
+    
+#endif
+    
     // Success
     PJ_LOG(4,(THIS_FILE, "Sound capture started."));
@@ -387,4 +395,8 @@
     }
     
+    if (startAsw_.IsStarted()) {
+	startAsw_.AsyncStop();
+    }
+    
     state_ = STATE_INACTIVE;
 }
@@ -400,4 +412,8 @@
 void CPjAudioInputEngine::MaiscOpenComplete(TInt aError)
 {
+    if (startAsw_.IsStarted()) {
+	startAsw_.AsyncStop();
+    }
+    
     lastError_ = aError;
     if (aError != KErrNone) {
@@ -406,5 +422,5 @@
     }
 
-    /* Apply output volume setting if specified */
+    /* Apply input volume setting if specified */
     if (parentStrm_->param.flags & 
         PJMEDIA_AUD_DEV_CAP_INPUT_VOLUME_SETTING) 
@@ -424,5 +440,10 @@
     if (err2) {
     	PJ_LOG(4,(THIS_FILE, "Exception in iInputStream_->ReadL()"));
-    }
+	lastError_ = err2;
+	return;
+    }
+
+    // input stream opened succesfully, set status to Active
+    state_ = STATE_ACTIVE;
 }
 
@@ -557,4 +578,5 @@
     TInt		     lastError_;
     unsigned		     timestamp_;
+    CActiveSchedulerWait     startAsw_;
 
     CPjAudioOutputEngine(struct mda_stream *parent_strm,
@@ -648,4 +670,11 @@
     lastError_ = KRequestPending;
     iOutputStream_->Open(&iStreamSettings);
+    
+#if defined(PJMEDIA_AUDIO_DEV_MDA_USE_SYNC_START) && \
+    PJMEDIA_AUDIO_DEV_MDA_USE_SYNC_START != 0
+    
+    startAsw_.Start();
+    
+#endif
 
     // Success
@@ -672,4 +701,8 @@
     }
     
+    if (startAsw_.IsStarted()) {
+	startAsw_.AsyncStop();
+    }
+    
     state_ = STATE_INACTIVE;
 }
@@ -677,10 +710,11 @@
 void CPjAudioOutputEngine::MaoscOpenComplete(TInt aError)
 {
+    if (startAsw_.IsStarted()) {
+	startAsw_.AsyncStop();
+    }
+
     lastError_ = aError;
     
     if (aError==KErrNone) {
-	// output stream opened succesfully, set status to Active
-	state_ = STATE_ACTIVE;
-
 	// set stream properties, 16bit 8KHz mono
 	TMdaAudioDataSettings iSettings;
@@ -737,4 +771,7 @@
 	frame_.Set(frameBuf_, frameBufSize_);
 	iOutputStream_->WriteL(frame_);
+
+	// output stream opened succesfully, set status to Active
+	state_ = STATE_ACTIVE;
     } else {
     	snd_perror("Error in MaoscOpenComplete()", aError);
@@ -900,5 +937,6 @@
     param->samples_per_frame = af->dev_info.default_samples_per_sec * 20 / 1000;
     param->bits_per_sample = BITS_PER_SAMPLE;
-    param->flags = af->dev_info.caps;
+    // Don't set the flags without specifying the flags value.
+    //param->flags = af->dev_info.caps;
 
     return PJ_SUCCESS;
@@ -974,4 +1012,18 @@
 
     pj_memcpy(pi, &strm->param, sizeof(*pi));
+    
+    /* Update the output volume setting */
+    if (stream_get_cap(s, PJMEDIA_AUD_DEV_CAP_OUTPUT_VOLUME_SETTING,
+		       &pi->output_vol) == PJ_SUCCESS)
+    {
+	pi->flags |= PJMEDIA_AUD_DEV_CAP_OUTPUT_VOLUME_SETTING;
+    }
+    
+    /* Update the input volume setting */
+    if (stream_get_cap(s, PJMEDIA_AUD_DEV_CAP_INPUT_VOLUME_SETTING,
+		       &pi->input_vol) == PJ_SUCCESS)
+    {
+	pi->flags |= PJMEDIA_AUD_DEV_CAP_INPUT_VOLUME_SETTING;
+    }
     
     return PJ_SUCCESS;
