web-dev-qa-db-fra.com

PCM -> AAC (Encoder) -> PCM (Decoder) en temps réel avec une optimisation correcte

J'essaye d'implémenter

AudioRecord (MIC) ->

PCM -> AAC Encoder
AAC -> PCM Decode

-> AudioTrack??  (SPEAKER)

avec MediaCodec sur Android 4.1+ (API16).

Premièrement, j'ai réussi (mais je ne suis pas sûr qu'il soit correctement optimisé) implémenté PCM -> AAC Encoder Par MediaCodec comme prévu ci-dessous

private boolean setEncoder(int rate)
{
    encoder = MediaCodec.createEncoderByType("audio/mp4a-latm");
    MediaFormat format = new MediaFormat();
    format.setString(MediaFormat.KEY_MIME, "audio/mp4a-latm");
    format.setInteger(MediaFormat.KEY_CHANNEL_COUNT, 1);
    format.setInteger(MediaFormat.KEY_SAMPLE_RATE, 44100);
    format.setInteger(MediaFormat.KEY_BIT_RATE, 64 * 1024);//AAC-HE 64kbps
    format.setInteger(MediaFormat.KEY_AAC_PROFILE, MediaCodecInfo.CodecProfileLevel.AACObjectHE);
    encoder.configure(format, null, null, MediaCodec.CONFIGURE_FLAG_ENCODE);
    return true;
}

ENTRÉE: Débit PCM = 44100 (Hz) x 16 (bit) x 1(Monoral) = 705600 bit/s

SORTIE: AAC-HE Bitrate = 64 x 1024 (bit) = 65536 bit/s

Ainsi, la taille des données est approximativement compressée x11, et j'ai confirmé ce fonctionnement en observant un journal

  • AudioRecoder ﹕ 4096 octets lus
  • AudioEncoder ﹕ 369 octets encodés

la taille des données est approximativement compressée x11, jusqu'ici tout va bien.

Maintenant, j'ai un serveur UDP pour recevoir les données encodées, puis les décoder.

Le profil du décodeur est défini comme suit:

private boolean setDecoder(int rate)
{
    decoder = MediaCodec.createDecoderByType("audio/mp4a-latm");
    MediaFormat format = new MediaFormat();
    format.setString(MediaFormat.KEY_MIME, "audio/mp4a-latm");
    format.setInteger(MediaFormat.KEY_CHANNEL_COUNT, 1);
    format.setInteger(MediaFormat.KEY_SAMPLE_RATE, 44100);
    format.setInteger(MediaFormat.KEY_BIT_RATE, 64 * 1024);//AAC-HE 64kbps
    format.setInteger(MediaFormat.KEY_AAC_PROFILE, MediaCodecInfo.CodecProfileLevel.AACObjectHE);
    decoder.configure(format, null, null, 0);

    return true;
}

Étant donné que la taille de la mémoire tampon des paquets UDPserver est 1024

  • Serveur UDP ﹕ 1024 octets reçus

et comme ce sont les données AAC compressées, je m'attends à ce que la taille de décodage soit

environ 1024 x11, mais le résultat réel est

  • AudioDecoder ﹕ 8192 octets décodés

C'est environ x8, Et je sens quelque chose de mal.

Le code du décodeur est le suivant:

    IOudpPlayer = new Thread(new Runnable()
    {
        public void run()
        {
            SocketAddress sockAddress;
            String address;

            int len = 1024;
            byte[] buffer2 = new byte[len];
            DatagramPacket packet;

            byte[] data;

            ByteBuffer[] inputBuffers;
            ByteBuffer[] outputBuffers;

            ByteBuffer inputBuffer;
            ByteBuffer outputBuffer;

            MediaCodec.BufferInfo bufferInfo;
            int inputBufferIndex;
            int outputBufferIndex;
            byte[] outData;
            try
            {
                decoder.start();
                isPlaying = true;
                while (isPlaying)
                {
                    try
                    {
                        packet = new DatagramPacket(buffer2, len);
                        ds.receive(packet);

                        sockAddress = packet.getSocketAddress();
                        address = sockAddress.toString();

                        Log.d("UDP Receiver"," received !!! from " + address);

                        data = new byte[packet.getLength()];
                        System.arraycopy(packet.getData(), packet.getOffset(), data, 0, packet.getLength());

                        Log.d("UDP Receiver",  data.length + " bytes received");

                        //===========
                        inputBuffers = decoder.getInputBuffers();
                        outputBuffers = decoder.getOutputBuffers();
                        inputBufferIndex = decoder.dequeueInputBuffer(-1);
                        if (inputBufferIndex >= 0)
                        {
                            inputBuffer = inputBuffers[inputBufferIndex];
                            inputBuffer.clear();

                            inputBuffer.put(data);

                            decoder.queueInputBuffer(inputBufferIndex, 0, data.length, 0, 0);
                        }

                        bufferInfo = new MediaCodec.BufferInfo();
                        outputBufferIndex = decoder.dequeueOutputBuffer(bufferInfo, 0);

                        while (outputBufferIndex >= 0)
                        {
                            outputBuffer = outputBuffers[outputBufferIndex];

                            outputBuffer.position(bufferInfo.offset);
                            outputBuffer.limit(bufferInfo.offset + bufferInfo.size);

                            outData = new byte[bufferInfo.size];
                            outputBuffer.get(outData);

                            Log.d("AudioDecoder", outData.length + " bytes decoded");

                            decoder.releaseOutputBuffer(outputBufferIndex, false);
                            outputBufferIndex = decoder.dequeueOutputBuffer(bufferInfo, 0);

                        }



                        //===========

                    }
                    catch (IOException e)
                    {
                    }
                }

                decoder.stop();

            }
            catch (Exception e)
            {
            }
        }
    });

le code complet:

https://Gist.github.com/kenokabe/9029256

également besoin de permission:

 <uses-permission Android:name="Android.permission.INTERNET"></uses-permission>
 <uses-permission Android:name="Android.permission.RECORD_AUDIO"></uses-permission>

Un membre fadden qui travaille pour Google m'a dit

On dirait que je ne règle pas la position et la limite sur le tampon de sortie.

J'ai lu VP8 Encoding Nexus 5 renvoie vide/0-Frames , mais je ne sais pas comment l'implémenter correctement.


MISE À JOUR: J'ai en quelque sorte compris où modifier pour

On dirait que je ne règle pas la position et la limite sur le tampon de sortie.

, ajoutez donc 2 lignes dans la boucle while de l'encodeur et du décodeur comme suit:

 outputBuffer.position(bufferInfo.offset);
 outputBuffer.limit(bufferInfo.offset + bufferInfo.size);

https://Gist.github.com/kenokabe/9029256/revisions

Cependant, le résultat est le même.

et maintenant, je pense, les erreurs: W/SoftAAC2﹕ AAC decoder returned error 16388, substituting silence. indique que ce décodeur échoue complètement dès le premier. C'est à nouveau le problème de the data is not seekable. Recherche dans les flux AAC sur Android C'est très décevant si le décodeur AAC ne peut pas gérer les données de streaming de cette manière, mais uniquement en ajoutant un en-tête.


UPDATE2: le récepteur UDP a mal tourné, donc modifié

https://Gist.github.com/kenokabe/9029256

Maintenant, l'erreur

W/SoftAAC2﹕ AAC decoder returned error 16388, substituting silence. A disparu !!

Donc, cela indique que le décodeur fonctionne sans erreur, au moins,

cependant, c'est le journal de 1 cycle:

D/AudioRecoder﹕ 4096 bytes read
D/AudioEncoder﹕ 360 bytes encoded
D/UDP Receiver﹕ received !!! from /127.0.0.1:39000
D/UDP Receiver﹕ 360 bytes received
D/AudioDecoder﹕ 8192 bytes decoded

PCM (4096) -> codé AAC (360) -> UDP-AAC (360) -> (supposé être) PCM (8192)

Le résultat final est d'environ 2x la taille du PCM d'origine, quelque chose ne va toujours pas.


Donc ma question ici serait

  1. Pouvez-vous optimiser correctement mon exemple de code pour qu'il fonctionne correctement?

  2. Est-ce une bonne façon d'utiliser l'API AudioTrack pour lire les données brutes PCM décodées à la volée, et pouvez-vous me montrer la bonne façon de le faire? Un exemple de code est apprécié.

Je vous remercie.

PS. Mon projet cible sur Android4.1 + (API16), j'ai lu que les choses sont plus faciles sur API18 (Andeoid 4.3+), mais pour des raisons de compatibilité évidentes, malheureusement, je dois sauter MediaMuxer etc. ici ...

21
user1028880

Après avoir testé, voici ce que j'ai trouvé en modifiant votre code:

 package com.example.app;

    import Android.app.Activity;

    import Android.media.AudioManager;
    import Android.media.MediaCodecInfo;
    import Android.media.MediaFormat;
    import Android.os.Bundle;

    import Android.media.AudioFormat;
    import Android.media.AudioRecord;
    import Android.media.AudioTrack;
    import Android.media.MediaCodec;

    import Android.media.MediaRecorder.AudioSource;

    import Android.util.Log;

    import Java.io.IOException;
    import Java.net.DatagramPacket;
    import Java.net.DatagramSocket;
    import Java.net.InetAddress;
    import Java.net.SocketAddress;
    import Java.net.SocketException;
    import Java.nio.ByteBuffer;

    public class MainActivity extends Activity
    {
        private AudioRecord recorder;
        private AudioTrack player;

        private MediaCodec encoder;
        private MediaCodec decoder;

        private short audioFormat = AudioFormat.ENCODING_PCM_16BIT;
        private short channelConfig = AudioFormat.CHANNEL_IN_MONO;

        private int bufferSize;
        private boolean isRecording;
        private boolean isPlaying;

        private Thread IOrecorder;

        private Thread IOudpPlayer;


        private DatagramSocket ds;
        private final int localPort = 39000;

        @Override
        protected void onCreate(Bundle savedInstanceState)
        {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);

            IOrecorder = new Thread(new Runnable()
            {
                public void run()
                {
                    int read;
                    byte[] buffer1 = new byte[bufferSize];

                    ByteBuffer[] inputBuffers;
                    ByteBuffer[] outputBuffers;

                    ByteBuffer inputBuffer;
                    ByteBuffer outputBuffer;

                    MediaCodec.BufferInfo bufferInfo;
                    int inputBufferIndex;
                    int outputBufferIndex;

                    byte[] outData;

                    DatagramPacket packet;
                    try
                    {
                        encoder.start();
                        recorder.startRecording();
                        isRecording = true;
                        while (isRecording)
                        {
                            read = recorder.read(buffer1, 0, bufferSize);
                           // Log.d("AudioRecoder", read + " bytes read");
                            //------------------------

                            inputBuffers = encoder.getInputBuffers();
                            outputBuffers = encoder.getOutputBuffers();
                            inputBufferIndex = encoder.dequeueInputBuffer(-1);
                            if (inputBufferIndex >= 0)
                            {
                                inputBuffer = inputBuffers[inputBufferIndex];
                                inputBuffer.clear();

                                inputBuffer.put(buffer1);

                                encoder.queueInputBuffer(inputBufferIndex, 0, buffer1.length, 0, 0);
                            }

                            bufferInfo = new MediaCodec.BufferInfo();
                            outputBufferIndex = encoder.dequeueOutputBuffer(bufferInfo, 0);



                            while (outputBufferIndex >= 0)
                            {
                                outputBuffer = outputBuffers[outputBufferIndex];

                                outputBuffer.position(bufferInfo.offset);
                                outputBuffer.limit(bufferInfo.offset + bufferInfo.size);

                                outData = new byte[bufferInfo.size];
                                outputBuffer.get(outData);


                               // Log.d("AudioEncoder ", outData.length + " bytes encoded");
                                //-------------
                                packet = new DatagramPacket(outData, outData.length,
                                        InetAddress.getByName("127.0.0.1"), localPort);
                                ds.send(packet);
                                //------------

                                encoder.releaseOutputBuffer(outputBufferIndex, false);
                                outputBufferIndex = encoder.dequeueOutputBuffer(bufferInfo, 0);

                            }
                            // ----------------------;

                        }
                        encoder.stop();
                        recorder.stop();
                    }
                    catch (Exception e)
                    {
                        e.printStackTrace();
                    }
                }
            });



            IOudpPlayer = new Thread(new Runnable()
            {
                public void run()
                {
                    SocketAddress sockAddress;
                    String address;

                    int len = 2048
                    byte[] buffer2 = new byte[len];
                    DatagramPacket packet;

                    byte[] data;

                    ByteBuffer[] inputBuffers;
                    ByteBuffer[] outputBuffers;

                    ByteBuffer inputBuffer;
                    ByteBuffer outputBuffer;

                    MediaCodec.BufferInfo bufferInfo;
                    int inputBufferIndex;
                    int outputBufferIndex;
                    byte[] outData;
                    try
                    {
                        player.play();
                        decoder.start();
                        isPlaying = true;
                        while (isPlaying)
                        {
                            try
                            {
                                packet = new DatagramPacket(buffer2, len);
                                ds.receive(packet);

                                sockAddress = packet.getSocketAddress();
                                address = sockAddress.toString();

                             //   Log.d("UDP Receiver"," received !!! from " + address);

                                data = new byte[packet.getLength()];
                                System.arraycopy(packet.getData(), packet.getOffset(), data, 0, packet.getLength());

                               // Log.d("UDP Receiver",  data.length + " bytes received");

                                //===========
                                inputBuffers = decoder.getInputBuffers();
                                outputBuffers = decoder.getOutputBuffers();
                                inputBufferIndex = decoder.dequeueInputBuffer(-1);
                                if (inputBufferIndex >= 0)
                                {
                                    inputBuffer = inputBuffers[inputBufferIndex];
                                    inputBuffer.clear();

                                    inputBuffer.put(data);

                                    decoder.queueInputBuffer(inputBufferIndex, 0, data.length, 0, 0);
                                }

                                bufferInfo = new MediaCodec.BufferInfo();
                                outputBufferIndex = decoder.dequeueOutputBuffer(bufferInfo, 0);

                                while (outputBufferIndex >= 0)
                                {
                                    outputBuffer = outputBuffers[outputBufferIndex];

                                    outputBuffer.position(bufferInfo.offset);
                                    outputBuffer.limit(bufferInfo.offset + bufferInfo.size);

                                    outData = new byte[bufferInfo.size];
                                    outputBuffer.get(outData);

                                  //  Log.d("AudioDecoder", outData.length + " bytes decoded");

                                    player.write(outData, 0, outData.length);

                                    decoder.releaseOutputBuffer(outputBufferIndex, false);
                                    outputBufferIndex = decoder.dequeueOutputBuffer(bufferInfo, 0..
11
sexp1stol

Auto-réponse, voici mon meilleur effort jusqu'à présent

package com.example.app;

import Android.app.Activity;

import Android.media.AudioManager;
import Android.media.MediaCodecInfo;
import Android.media.MediaFormat;
import Android.os.Bundle;

import Android.media.AudioFormat;
import Android.media.AudioRecord;
import Android.media.AudioTrack;
import Android.media.MediaCodec;

import Android.media.MediaRecorder.AudioSource;

import Android.util.Log;

import Java.io.IOException;
import Java.net.DatagramPacket;
import Java.net.DatagramSocket;
import Java.net.InetAddress;
import Java.net.SocketAddress;
import Java.net.SocketException;
import Java.nio.ByteBuffer;

public class MainActivity extends Activity
{
    private AudioRecord recorder;
    private AudioTrack player;

    private MediaCodec encoder;
    private MediaCodec decoder;

    private short audioFormat = AudioFormat.ENCODING_PCM_16BIT;
    private short channelConfig = AudioFormat.CHANNEL_IN_MONO;

    private int bufferSize;
    private boolean isRecording;
    private boolean isPlaying;

    private Thread IOrecorder;

    private Thread IOudpPlayer;


    private DatagramSocket ds;
    private final int localPort = 39000;

    @Override
    protected void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        IOrecorder = new Thread(new Runnable()
        {
            public void run()
            {
                int read;
                byte[] buffer1 = new byte[bufferSize];

                ByteBuffer[] inputBuffers;
                ByteBuffer[] outputBuffers;

                ByteBuffer inputBuffer;
                ByteBuffer outputBuffer;

                MediaCodec.BufferInfo bufferInfo;
                int inputBufferIndex;
                int outputBufferIndex;

                byte[] outData;

                DatagramPacket packet;
                try
                {
                    encoder.start();
                    recorder.startRecording();
                    isRecording = true;
                    while (isRecording)
                    {
                        read = recorder.read(buffer1, 0, bufferSize);
                       // Log.d("AudioRecoder", read + " bytes read");
                        //------------------------

                        inputBuffers = encoder.getInputBuffers();
                        outputBuffers = encoder.getOutputBuffers();
                        inputBufferIndex = encoder.dequeueInputBuffer(-1);
                        if (inputBufferIndex >= 0)
                        {
                            inputBuffer = inputBuffers[inputBufferIndex];
                            inputBuffer.clear();

                            inputBuffer.put(buffer1);

                            encoder.queueInputBuffer(inputBufferIndex, 0, buffer1.length, 0, 0);
                        }

                        bufferInfo = new MediaCodec.BufferInfo();
                        outputBufferIndex = encoder.dequeueOutputBuffer(bufferInfo, 0);



                        while (outputBufferIndex >= 0)
                        {
                            outputBuffer = outputBuffers[outputBufferIndex];

                            outputBuffer.position(bufferInfo.offset);
                            outputBuffer.limit(bufferInfo.offset + bufferInfo.size);

                            outData = new byte[bufferInfo.size];
                            outputBuffer.get(outData);


                           // Log.d("AudioEncoder", outData.length + " bytes encoded");
                            //-------------
                            packet = new DatagramPacket(outData, outData.length,
                                    InetAddress.getByName("127.0.0.1"), localPort);
                            ds.send(packet);
                            //------------

                            encoder.releaseOutputBuffer(outputBufferIndex, false);
                            outputBufferIndex = encoder.dequeueOutputBuffer(bufferInfo, 0);

                        }
                        // ----------------------;

                    }
                    encoder.stop();
                    recorder.stop();
                }
                catch (Exception e)
                {
                    e.printStackTrace();
                }
            }
        });



        IOudpPlayer = new Thread(new Runnable()
        {
            public void run()
            {
                SocketAddress sockAddress;
                String address;

                int len = 1024;
                byte[] buffer2 = new byte[len];
                DatagramPacket packet;

                byte[] data;

                ByteBuffer[] inputBuffers;
                ByteBuffer[] outputBuffers;

                ByteBuffer inputBuffer;
                ByteBuffer outputBuffer;

                MediaCodec.BufferInfo bufferInfo;
                int inputBufferIndex;
                int outputBufferIndex;
                byte[] outData;
                try
                {
                    player.play();
                    decoder.start();
                    isPlaying = true;
                    while (isPlaying)
                    {
                        try
                        {
                            packet = new DatagramPacket(buffer2, len);
                            ds.receive(packet);

                            sockAddress = packet.getSocketAddress();
                            address = sockAddress.toString();

                         //   Log.d("UDP Receiver"," received !!! from " + address);

                            data = new byte[packet.getLength()];
                            System.arraycopy(packet.getData(), packet.getOffset(), data, 0, packet.getLength());

                           // Log.d("UDP Receiver",  data.length + " bytes received");

                            //===========
                            inputBuffers = decoder.getInputBuffers();
                            outputBuffers = decoder.getOutputBuffers();
                            inputBufferIndex = decoder.dequeueInputBuffer(-1);
                            if (inputBufferIndex >= 0)
                            {
                                inputBuffer = inputBuffers[inputBufferIndex];
                                inputBuffer.clear();

                                inputBuffer.put(data);

                                decoder.queueInputBuffer(inputBufferIndex, 0, data.length, 0, 0);
                            }

                            bufferInfo = new MediaCodec.BufferInfo();
                            outputBufferIndex = decoder.dequeueOutputBuffer(bufferInfo, 0);

                            while (outputBufferIndex >= 0)
                            {
                                outputBuffer = outputBuffers[outputBufferIndex];

                                outputBuffer.position(bufferInfo.offset);
                                outputBuffer.limit(bufferInfo.offset + bufferInfo.size);

                                outData = new byte[bufferInfo.size];
                                outputBuffer.get(outData);

                              //  Log.d("AudioDecoder", outData.length + " bytes decoded");

                                player.write(outData, 0, outData.length);

                                decoder.releaseOutputBuffer(outputBufferIndex, false);
                                outputBufferIndex = decoder.dequeueOutputBuffer(bufferInfo, 0);

                            }

                            //===========

                        }
                        catch (IOException e)
                        {
                        }
                    }

                    decoder.stop();
                    player.stop();

                }
                catch (Exception e)
                {
                }
            }
        });

//===========================================================
        int rate = findAudioRecord();
        if (rate != -1)
        {
            Log.v("=========media ", "ready: " + rate);
            Log.v("=========media channel ", "ready: " + channelConfig);

            boolean encoderReady = setEncoder(rate);
            Log.v("=========encoder ", "ready: " + encoderReady);
            if (encoderReady)
            {
                boolean decoderReady = setDecoder(rate);
                Log.v("=========decoder ", "ready: " + decoderReady);
                if (decoderReady)
                {
                    Log.d("=======bufferSize========", "" + bufferSize);
                    try
                    {
                        setPlayer(rate);

                        ds = new DatagramSocket(localPort);
                        IOudpPlayer.start();

                        IOrecorder.start();

                    }
                    catch (SocketException e)
                    {
                        e.printStackTrace();
                    }


                }

            }
        }
    }


    protected void onDestroy()
    {

        recorder.release();
        player.release();
        encoder.release();
        decoder.release();

    }
/*
    protected void onResume()
    {

        // isRecording = true;
    }

    protected void onPause()
    {

        isRecording = false;
    }
*/

    private int findAudioRecord()
    {
        for (int rate : new int[]{44100})
        {
            try
            {
                Log.v("===========Attempting rate ", rate + "Hz, bits: " + audioFormat + ", channel: " + channelConfig);
                bufferSize = AudioRecord.getMinBufferSize(rate, channelConfig, audioFormat);

                if (bufferSize != AudioRecord.ERROR_BAD_VALUE)
                {
                    // check if we can instantiate and have a success
                    recorder = new AudioRecord(AudioSource.MIC, rate, channelConfig, audioFormat, bufferSize);

                    if (recorder.getState() == AudioRecord.STATE_INITIALIZED)
                    {
                        Log.v("===========final rate ", rate + "Hz, bits: " + audioFormat + ", channel: " + channelConfig);

                        return rate;
                    }
                }
            }
            catch (Exception e)
            {
                Log.v("error", "" + rate);
            }

        }
        return -1;
    }

    private boolean setEncoder(int rate)
    {
        encoder = MediaCodec.createEncoderByType("audio/mp4a-latm");
        MediaFormat format = new MediaFormat();
        format.setString(MediaFormat.KEY_MIME, "audio/mp4a-latm");
        format.setInteger(MediaFormat.KEY_CHANNEL_COUNT, 1);
        format.setInteger(MediaFormat.KEY_SAMPLE_RATE, rate);
        format.setInteger(MediaFormat.KEY_BIT_RATE, 64 * 1024);//AAC-HE 64kbps
        format.setInteger(MediaFormat.KEY_AAC_PROFILE, MediaCodecInfo.CodecProfileLevel.AACObjectHE);
        encoder.configure(format, null, null, MediaCodec.CONFIGURE_FLAG_ENCODE);
        return true;
    }

    private boolean setDecoder(int rate)
    {
        decoder = MediaCodec.createDecoderByType("audio/mp4a-latm");
        MediaFormat format = new MediaFormat();
        format.setString(MediaFormat.KEY_MIME, "audio/mp4a-latm");
        format.setInteger(MediaFormat.KEY_CHANNEL_COUNT, 1);
        format.setInteger(MediaFormat.KEY_SAMPLE_RATE, rate);
        format.setInteger(MediaFormat.KEY_BIT_RATE, 64 * 1024);//AAC-HE 64kbps
        format.setInteger(MediaFormat.KEY_AAC_PROFILE, MediaCodecInfo.CodecProfileLevel.AACObjectHE);

        decoder.configure(format, null, null, 0);

        return true;
    }

    private boolean setPlayer(int rate)
    {
        int bufferSizePlayer = AudioTrack.getMinBufferSize(rate, AudioFormat.CHANNEL_OUT_MONO, audioFormat);
        Log.d("====buffer Size player ", String.valueOf(bufferSizePlayer));

        player= new AudioTrack(AudioManager.STREAM_MUSIC, rate, AudioFormat.CHANNEL_OUT_MONO, audioFormat, bufferSizePlayer, AudioTrack.MODE_STREAM);


        if (player.getState() == AudioTrack.STATE_INITIALIZED)
        {

            return true;
        }
        else
        {
            return false;
        }

    }


}
5
user1028880

J'ai essayé le code ci-dessus et cela n'a pas fonctionné correctement. J'obtenais beaucoup de silence injecté à la sortie décodée. Le problème ne définissait pas la valeur "csd" appropriée pour le décodeur.

Donc, si vous voyez "silence" dans le journal ou une erreur de lancement du décodeur, assurez-vous d'avoir ajouté ce qui suit à votre format de décodeur multimédia

int profile = 2;  //AAC LC
int freqIdx = 11;  //8KHz
int chanCfg = 1;  //Mono

ByteBuffer csd = ByteBuffer.allocate(2);
csd.put(0, (byte) (profile << 3 | freqIdx >> 1));
csd.put(1, (byte)((freqIdx & 0x01) << 7 | chanCfg << 3));
mediaFormat.setByteBuffer("csd-0", csd);
2
Sojan P R

D/AudioRecoder ﹕ 4096 octets lus D/AudioEncoder ﹕ 360 octets codés D/UDP Receiver ﹕ reçus !!! de /127.0.0.1:39000 Récepteur D/UDP DP 360 octets reçus D/AudioDecoder ﹕ 8192 octets décodés

En effet, le décodeur acc décode toujours vers les canaux stéréo, même si les données encodées sont MONO. donc si votre côté encodage est réglé sur des canaux stéréo, ce sera comme:

D/AudioRecoder ﹕ 8192 octets lus D/AudioEncoder ﹕ Récepteur D/UDP encodé à 360 octets ﹕ reçu !!! de /127.0.0.1:39000 Récepteur D/UDP DP 360 octets reçus D/AudioDecoder ﹕ 8192 octets décodés

0
cantonics

Votre code de réseau combine des données. Vous avez obtenu 369 octets de données compressées, mais du côté réception, vous vous êtes retrouvé avec 1024 octets. Ces 1024 octets se composent de deux trames entières et d'une trame partielle. Les deux trames entières décodent chacune à nouveau à 4096 octets, pour le total de 8192 octets que vous avez vu. La trame partielle restante sera probablement décodée une fois que vous aurez envoyé suffisamment de données au décodeur, mais vous ne devez généralement envoyer que des trames entières au décodeur.

De plus, MediaCodec.dequeueOutputBuffer() ne renvoie pas seulement des indices de tampon (positifs), mais aussi des codes d'état (négatifs). L'un des codes possibles est MediaCodec.INFO_OUTPUT_FORMAT_CHANGED, Ce qui indique que vous devez appeler MediaCodec.getOutputFormat() pour obtenir le format des données audio. Vous pouvez voir la sortie stéréo du codec même si l'entrée est mono. Le code que vous avez publié sort simplement de la boucle lorsqu'il reçoit l'un de ces codes d'état.

0
marcone

J'ai testé avec ta souce. il y a quelques points.

  1. Le débit binaire est un nombre naturel de K, mais pas de l'ordinateur K. 64k = 64000, mais pas 64 * 1024

  2. Il n'est pas recommandé d'écrire un code long qui partage certaines variables. A. Séparez le fil de codeur et le fil de décodeur en 2 classes indépendantes. B. Le DatagramSocket est partagé par l'expéditeur et le récepteur, ce n'est pas bon.

  3. Enumerate Audio Format a besoin de plus de valeurs. c'est-à-dire que les taux d'échantillonnage doivent être choisis parmi: 8000, 11025, 22050, 44100

0
Stephen