OSDN Git Service

A2DP audio HAL: fix write error behavior
[android-x86/system-bt.git] / audio_a2dp_hw / audio_a2dp_hw.c
index 6c8e30c..97acc63 100644 (file)
@@ -189,7 +189,7 @@ static int calc_audiotime(struct a2dp_config cfg, int bytes)
     ASSERTC(cfg.format == AUDIO_FORMAT_PCM_16_BIT,
             "unsupported sample sz", cfg.format);
 
-    return bytes*(1000000/(chan_count*2))/cfg.rate;
+    return (int)(((int64_t)bytes * (1000000 / (chan_count * 2))) / cfg.rate);
 }
 
 /*****************************************************************************
@@ -550,6 +550,7 @@ static ssize_t out_write(struct audio_stream_out *stream, const void* buffer,
 {
     struct a2dp_stream_out *out = (struct a2dp_stream_out *)stream;
     int sent;
+    int us_delay;
 
     DEBUG("write %zu bytes (fd %d)", bytes, out->common.audio_fd);
 
@@ -559,7 +560,7 @@ static ssize_t out_write(struct audio_stream_out *stream, const void* buffer,
     {
         DEBUG("stream suspended");
         pthread_mutex_unlock(&out->common.lock);
-        return -1;
+        goto error;
     }
 
     /* only allow autostarting if we are in stopped or standby */
@@ -568,23 +569,15 @@ static ssize_t out_write(struct audio_stream_out *stream, const void* buffer,
     {
         if (start_audio_datapath(&out->common) < 0)
         {
-            /* emulate time this write represents to avoid very fast write
-               failures during transition periods or remote suspend */
-
-            int us_delay = calc_audiotime(out->common.cfg, bytes);
-
-            DEBUG("emulate a2dp write delay (%d us)", us_delay);
-
-            usleep(us_delay);
             pthread_mutex_unlock(&out->common.lock);
-            return -1;
+            goto error;
         }
     }
     else if (out->common.state != AUDIO_A2DP_STATE_STARTED)
     {
         ERROR("stream not in stopped or standby");
         pthread_mutex_unlock(&out->common.lock);
-        return -1;
+        goto error;
     }
 
     pthread_mutex_unlock(&out->common.lock);
@@ -597,14 +590,21 @@ static ssize_t out_write(struct audio_stream_out *stream, const void* buffer,
             out->common.state = AUDIO_A2DP_STATE_STOPPED;
         else
             ERROR("write failed : stream suspended, avoid resetting state");
-    } else {
-        const size_t frames = bytes / audio_stream_out_frame_size(stream);
-        out->frames_rendered += frames;
-        out->frames_presented += frames;
+        goto error;
     }
 
-    DEBUG("wrote %d bytes out of %zu bytes", sent, bytes);
-    return sent;
+    const size_t frames = bytes / audio_stream_out_frame_size(stream);
+    out->frames_rendered += frames;
+    out->frames_presented += frames;
+    return bytes;
+
+error:
+    us_delay = calc_audiotime(out->common.cfg, bytes);
+
+    DEBUG("emulate a2dp write delay (%d us)", us_delay);
+
+    usleep(us_delay);
+    return bytes;
 }