From e4df5f1f5578ef429ad8569ae8e82e9431f5b093 Mon Sep 17 00:00:00 2001
From: xiaowusky <chenyangyang3858@dingtalk.com>
Date: Fri, 17 Nov 2023 09:58:41 +0800
Subject: [PATCH] =?UTF-8?q?desc:=E5=BD=95=E9=9F=B3=E6=B5=8B=E8=AF=95,?=
 =?UTF-8?q?=E7=BB=8F=E6=B5=8B=E8=AF=95=E5=8D=95=E7=8B=AC=E5=BD=95=E5=88=B6?=
 =?UTF-8?q?=E9=9F=B3=E9=A2=91=E6=AF=AB=E6=97=A0=E9=97=AE=E9=A2=98?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 .../library/vlc/encoder/AudioEncoderCore.java | 231 +++++++++---------
 1 file changed, 121 insertions(+), 110 deletions(-)

diff --git a/library-push/src/main/java/com/yinuo/library/vlc/encoder/AudioEncoderCore.java b/library-push/src/main/java/com/yinuo/library/vlc/encoder/AudioEncoderCore.java
index 889444c..d34a82c 100644
--- a/library-push/src/main/java/com/yinuo/library/vlc/encoder/AudioEncoderCore.java
+++ b/library-push/src/main/java/com/yinuo/library/vlc/encoder/AudioEncoderCore.java
@@ -12,9 +12,6 @@ import android.view.Surface;
 
 import com.common.commonlib.utils.LogUtils;
 
-import org.easydarwin.PushHelper;
-import org.easydarwin.easypusher.BuildConfig;
-
 import java.io.IOException;
 import java.nio.ByteBuffer;
 
@@ -34,13 +31,15 @@ public class AudioEncoderCore extends MediaEncoderCore implements Runnable {
 
     protected static final int AUDIO_FORMAT = AudioFormat.ENCODING_PCM_16BIT;
 
-    private int mSampleRate = 8000;
+    private int mSampleRate = 44100;
 
     private int mChannelCount = 1;
 
-    private int mBitRate = 16000;
+    private int mBitRate = 128000;
+
+//    private int mMaxInputSize = 16384;
 
-    private int mMaxInputSize = 1920;
+    int AUDIO_BUFFER_SIZE;
 
     private AudioRecord mAudioRecord;
 
@@ -63,14 +62,14 @@ public class AudioEncoderCore extends MediaEncoderCore implements Runnable {
         format.setInteger(MediaFormat.KEY_SAMPLE_RATE, mSampleRate);
         format.setInteger(MediaFormat.KEY_CHANNEL_COUNT, mChannelCount);
         format.setInteger(MediaFormat.KEY_BIT_RATE, mBitRate);
-        format.setInteger(MediaFormat.KEY_MAX_INPUT_SIZE, mMaxInputSize);
+//        format.setInteger(MediaFormat.KEY_MAX_INPUT_SIZE, mMaxInputSize);
 
         // Create a MediaCodec encoder, and configure it with our format.  Get a Surface
         // we can use for input and wrap it with a class that handles the EGL work.
         try {
             mEncoder = MediaCodec.createEncoderByType(MIME_TYPE);
         } catch (IOException e) {
-            LogUtils.e(e);
+            e.printStackTrace();
         }
 
         mEncoder.configure(format, null, null, MediaCodec.CONFIGURE_FLAG_ENCODE);
@@ -79,6 +78,8 @@ public class AudioEncoderCore extends MediaEncoderCore implements Runnable {
         LogUtils.v(String.format("%s prepareEncoder, mEncoder = %s", getClass().getSimpleName(), mEncoder));
     }
 
+    int minBufferSize;
+
     @SuppressLint("MissingPermission")
     private void prepareRecorder() {
         switch (mChannelCount) {
@@ -92,24 +93,25 @@ public class AudioEncoderCore extends MediaEncoderCore implements Runnable {
                 throw new IllegalArgumentException();
         }
 
-        int minBufferSize = AudioRecord.getMinBufferSize(mSampleRate,
+        minBufferSize = AudioRecord.getMinBufferSize(mSampleRate,
                 mChannelConfig, AUDIO_FORMAT);
-
+        AUDIO_BUFFER_SIZE = 2 * minBufferSize;
         mAudioRecord = new AudioRecord(
-                MediaRecorder.AudioSource.MIC, // source
+                MediaRecorder.AudioSource.CAMCORDER, // source
                 mSampleRate,            // sample rate, hz
                 mChannelConfig,         // channels
                 AUDIO_FORMAT,                        // audio format
-                minBufferSize);                  // buffer size (bytes)
+                AUDIO_BUFFER_SIZE);                  // buffer size (bytes)
     }
 
     @Override
     public void start() {
         if (!mRecording) {
-//            mRecording = true;
-//            mAudioRecord.startRecording();
-//
-//            TaskUtils.execute(this);
+            mRecording = true;
+            mAudioRecord.startRecording();
+
+            new Thread(this).start();
+
         }
     }
 
@@ -123,6 +125,87 @@ public class AudioEncoderCore extends MediaEncoderCore implements Runnable {
         return null;
     }
 
+    @Override
+    public void drainEncoder(boolean endOfStream) {
+//        LogUtils.v(String.format("%s drainEncoder: end = %b", getClass().getSimpleName(), endOfStream));
+
+        final int TIMEOUT_USEC = 10000;
+        if (VERBOSE) Log.d(TAG, "drainEncoder(" + endOfStream + ")");
+
+        if (endOfStream && isSurfaceInput()) {
+            if (VERBOSE) Log.d(TAG, "sending EOS to encoder");
+            mEncoder.signalEndOfInputStream();
+        }
+
+        ByteBuffer[] encoderOutputBuffers = mEncoder.getOutputBuffers();
+        while (true) {
+            int encoderStatus = mEncoder.dequeueOutputBuffer(mBufferInfo, TIMEOUT_USEC);
+
+            if (encoderStatus == MediaCodec.INFO_TRY_AGAIN_LATER) {
+                // no output available yet
+                if (!endOfStream) {
+                    break;      // out of while
+                } else {
+                    if (VERBOSE) Log.d(TAG, "no output available, spinning to await EOS");
+                }
+            } else if (encoderStatus == MediaCodec.INFO_OUTPUT_BUFFERS_CHANGED) {
+                // not expected for an encoder
+                encoderOutputBuffers = mEncoder.getOutputBuffers();
+            } else if (encoderStatus == MediaCodec.INFO_OUTPUT_FORMAT_CHANGED) {
+                // should happen before receiving buffers, and should only happen once
+                MediaFormat newFormat = mEncoder.getOutputFormat();
+                Log.d(TAG, "encoder output format changed: " + newFormat);
+
+                // now that we have the Magic Goodies, start the muxer
+                mTrackIndex = mMuxer.addTrack(newFormat);
+            } else if (encoderStatus < 0) {
+                Log.w(TAG, "unexpected result from encoder.dequeueOutputBuffer: " +
+                        encoderStatus);
+                // let's ignore it
+            } else {
+                ByteBuffer encodedData = encoderOutputBuffers[encoderStatus];
+                if (encodedData == null) {
+                    throw new RuntimeException("encoderOutputBuffer " + encoderStatus +
+                            " was null");
+                }
+
+                if (!mMuxer.isStarted()) {
+                    mBufferInfo.size = 0;
+                }
+
+                if ((mBufferInfo.flags & MediaCodec.BUFFER_FLAG_CODEC_CONFIG) != 0) {
+                    // The codec config data was pulled out and fed to the muxer when we got
+                    // the INFO_OUTPUT_FORMAT_CHANGED status.  Ignore it.
+                    if (VERBOSE) Log.d(TAG, "ignoring BUFFER_FLAG_CODEC_CONFIG");
+                    mBufferInfo.size = 0;
+                }
+
+                if (mBufferInfo.size != 0) {
+                    // adjust the ByteBuffer values to match BufferInfo (not needed?)
+                    encodedData.position(mBufferInfo.offset);
+                    encodedData.limit(mBufferInfo.offset + mBufferInfo.size);
+
+                    mMuxer.writeSampleData(mTrackIndex, encodedData, mBufferInfo);
+                    if (VERBOSE) {
+                        Log.d(TAG, "sent " + mBufferInfo.size + " bytes to muxer, ts=" +
+                                mBufferInfo.presentationTimeUs);
+                    }
+                }
+
+                mEncoder.releaseOutputBuffer(encoderStatus, false);
+
+                if ((mBufferInfo.flags & MediaCodec.BUFFER_FLAG_END_OF_STREAM) != 0) {
+                    if (!endOfStream) {
+                        Log.w(TAG, "reached end of stream unexpectedly");
+                    } else {
+                        if (VERBOSE) Log.d(TAG, "end of stream reached");
+                    }
+                    break;      // out of while
+                }
+            }
+        }
+    }
+
     @Override
     protected boolean isSurfaceInput() {
         return false;
@@ -131,14 +214,14 @@ public class AudioEncoderCore extends MediaEncoderCore implements Runnable {
     @Override
     public void run() {
         while (mRecording) {
-//            drainEncoder(false);
-//            drainAudio(false);
+            drainAudio(false);
+            drainEncoder(false);
         }
 
-//        drainAudio(true);
+        drainAudio(true);
 
         mAudioRecord.stop();
-//        drainEncoder(true);
+        drainEncoder(true);
 
         release();
     }
@@ -146,104 +229,32 @@ public class AudioEncoderCore extends MediaEncoderCore implements Runnable {
     private void drainAudio(boolean endOfStream) {
 //        LogUtils.v(String.format("drainAudio %b", endOfStream));
 
-        ByteBuffer[] inputBuffers = mEncoder.getInputBuffers();
         int bufferIndex = mEncoder.dequeueInputBuffer(-1); // wait indefinitely
         if (bufferIndex >= 0) {
-            ByteBuffer inputBuffer = inputBuffers[bufferIndex];
+            ByteBuffer inputBuffer = mEncoder.getInputBuffer(bufferIndex);
             inputBuffer.clear();
-
-            int len = mAudioRecord.read(inputBuffer, SAMPLES_PER_FRAME * 2); // read blocking
-            long ptsUs = System.nanoTime() / 1000;
-
+//            byte[] buffer = new byte[minBufferSize];
+//            int len = mAudioRecord.read(buffer, 0, minBufferSize); // read blocking
+//            long ptsUs = System.nanoTime() / 1000;
+//            if (len > 0) {
+//                inputBuffer.put(buffer);
+//                if (endOfStream) {
+//                    mEncoder.queueInputBuffer(bufferIndex, 0, buffer.length, ptsUs, MediaCodec.BUFFER_FLAG_END_OF_STREAM);
+//                } else {
+//                    mEncoder.queueInputBuffer(bufferIndex, 0, buffer.length, ptsUs, 0);
+//                }
+//            }
+
+            int bytesRead = mAudioRecord.read(inputBuffer, AUDIO_BUFFER_SIZE);
+            long presentationTimeUs = System.nanoTime() / 1000;
             if (endOfStream) {
-                mEncoder.queueInputBuffer(bufferIndex, 0, len, ptsUs, MediaCodec.BUFFER_FLAG_END_OF_STREAM);
-            } else {
-                mEncoder.queueInputBuffer(bufferIndex, 0, len, ptsUs, 0);
-            }
-        }
-    }
-
-    @Override
-    public void drainEncoder(boolean endOfStream) {
-        final int TIMEOUT_USEC = 10000;
-        if (VERBOSE) Log.d(TAG, "drainEncoder(" + endOfStream + ")");
-
-        if (endOfStream && isSurfaceInput()) {
-            if (VERBOSE) Log.d(TAG, "sending EOS to encoder");
-            mEncoder.signalEndOfInputStream();
-        }
-        ByteBuffer mBuffer = ByteBuffer.allocate(10240);
-        ByteBuffer[] encoderOutputBuffers = mEncoder.getOutputBuffers();
-        int encoderStatus = mEncoder.dequeueOutputBuffer(mBufferInfo, TIMEOUT_USEC);
-
-        if (encoderStatus == MediaCodec.INFO_TRY_AGAIN_LATER) {
-            // no output available yet
-            if (!endOfStream) {
+                mEncoder.queueInputBuffer(bufferIndex, 0, bytesRead, presentationTimeUs, MediaCodec.BUFFER_FLAG_END_OF_STREAM);
             } else {
-                if (VERBOSE) Log.d(TAG, "no output available, spinning to await EOS");
-            }
-        } else if (encoderStatus == MediaCodec.INFO_OUTPUT_BUFFERS_CHANGED) {
-            // not expected for an encoder
-            encoderOutputBuffers = mEncoder.getOutputBuffers();
-        } else if (encoderStatus == MediaCodec.INFO_OUTPUT_FORMAT_CHANGED) {
-            // should happen before receiving buffers, and should only happen once
-            MediaFormat newFormat = mEncoder.getOutputFormat();
-            Log.d(TAG, "encoder output format changed: " + newFormat);
-
-            // now that we have the Magic Goodies, start the muxer
-//                mTrackIndex = mMuxer.addTrack(newFormat);
-        } else if (encoderStatus < 0) {
-            Log.w(TAG, "unexpected result from encoder.dequeueOutputBuffer: " +
-                    encoderStatus);
-            // let's ignore it
-        } else {
-            ByteBuffer encodedData = encoderOutputBuffers[encoderStatus];
-            if (encodedData == null) {
-                throw new RuntimeException("encoderOutputBuffer " + encoderStatus +
-                        " was null");
-            }
-
-            if (!mMuxer.isStarted()) {
-                mBufferInfo.size = 0;
-            }
-
-            if ((mBufferInfo.flags & MediaCodec.BUFFER_FLAG_CODEC_CONFIG) != 0) {
-                // The codec config data was pulled out and fed to the muxer when we got
-                // the INFO_OUTPUT_FORMAT_CHANGED status.  Ignore it.
-                if (VERBOSE) Log.d(TAG, "ignoring BUFFER_FLAG_CODEC_CONFIG");
-                mBufferInfo.size = 0;
+                mEncoder.queueInputBuffer(bufferIndex, 0, bytesRead,
+                        presentationTimeUs, 0);
             }
 
-            if (mBufferInfo.size != 0) {
-                encodedData.get(mBuffer.array(), 7, mBufferInfo.size);
-                encodedData.clear();
-                mBuffer.position(7 + mBufferInfo.size);
-                addADTStoPacket(mBuffer.array(), mBufferInfo.size + 7);
-                mBuffer.flip();
-                PushHelper.INSTANCE.pushData(mBuffer.array(), mBufferInfo.size + 7, mBufferInfo.presentationTimeUs / 1000);
-                if (BuildConfig.DEBUG)
-                    Log.i(TAG, String.format("push audio stamp:%d", mBufferInfo.presentationTimeUs / 1000));
-            }
-
-            mEncoder.releaseOutputBuffer(encoderStatus, false);
-
-            if ((mBufferInfo.flags & MediaCodec.BUFFER_FLAG_END_OF_STREAM) != 0) {
-                if (!endOfStream) {
-                    Log.w(TAG, "reached end of stream unexpectedly");
-                } else {
-                    if (VERBOSE) Log.d(TAG, "end of stream reached");
-                }
-            }
         }
-    }
 
-    private void addADTStoPacket(byte[] packet, int packetLen) {
-        packet[0] = (byte) 0xFF;
-        packet[1] = (byte) 0xF1;
-        packet[2] = (byte) (((2 - 1) << 6) + (11 << 2) + (1 >> 2));
-        packet[3] = (byte) (((1 & 3) << 6) + (packetLen >> 11));
-        packet[4] = (byte) ((packetLen & 0x7FF) >> 3);
-        packet[5] = (byte) (((packetLen & 7) << 5) + 0x1F);
-        packet[6] = (byte) 0xFC;
     }
 }