/**
         * 
         * @param filePath
         */
        public void startPlay(string path)
        {
            eosReceived = false;
            mExtractor = new MediaExtractor();
            try
            {
                mExtractor.SetDataSource(path);
            }
            catch (IOException e)
            {
                e.PrintStackTrace();
            }

            int channel = 0;
            for (int i = 0; i < mExtractor.TrackCount; i++)
            {
                MediaFormat format = mExtractor.GetTrackFormat(i);
                string mime = format.GetString(MediaFormat.KeyMime);
                if (mime.StartsWith("audio/"))
                {
                    mExtractor.SelectTrack(i);
                    Log.Debug("TAG", "format : " + format);
                    ByteBuffer csd = format.GetByteBuffer("csd-0");

                    for (int k = 0; k < csd.Capacity(); ++k)
                    {
                        Log.Error("TAG", "csd : " + csd.ToArray<Byte>()[k]);
                    }
                    mSampleRate = format.GetInteger(MediaFormat.KeySampleRate);
                    channel = format.GetInteger(MediaFormat.KeyChannelCount);
                    break;
                }
            }
            MediaFormat format2 = makeAACCodecSpecificData(MediaCodecInfo.CodecProfileLevel.AACObjectLC, mSampleRate, channel);
            if (format2 == null)
                return;

            mDecoder = MediaCodec.createDecoderByType("audio/mp4a-latm");
            mDecoder.configure(format, null, null, 0);

            if (mDecoder == null)
            {
                Log.e("DecodeActivity", "Can't find video info!");
                return;
            }

            mDecoder.start();

            new Thread(AACDecoderAndPlayRunnable).start();
        }
Exemple #2
0
        protected static void PrintFormatInfo(MediaFormat format)
        {
            var csd0 = format.GetByteBuffer("csd-0");
            var csd1 = format.GetByteBuffer("csd-1");

            if (csd0 == null || csd1 == null)
            {
                return;
            }

            Log.Debug("csd0 buff len: ", csd0.Limit().ToString());
            Log.Debug("csd0 buff pos: ", csd0.Position().ToString());

            var sOut = "{ ";

            byte[] buff0 = new byte[csd0.Limit()];
            //int buffi = 0;
            csd0.Get(buff0, 0, buff0.Length);

            sOut = "{";
            foreach (byte b in buff0)
            {
                sOut += " " + b + ", ";
            }

            sOut = sOut.TrimEnd(",".ToCharArray()) + "}";

            Log.Debug("csd-0[] data: ", sOut);

            //while (csd0.HasRemaining)
            //{
            //    buff0[buffi] = csd0.Get();

            //    Log.Debug("csd-0[" + buffi + "] data: ",
            //                string.Format("0x{0:X}", buff0[buffi]));

            //    ++buffi;
            //}
            csd0.Position(0);
            Log.Debug("csd1 buff len: ", csd0.Limit().ToString());
            Log.Debug("csd1 buff pos: ", csd0.Position().ToString());

            byte[] buff1 = new byte[csd1.Limit()];
            //buffi = 0;

            csd1.Get(buff1, 0, buff1.Length);

            sOut = "{";
            foreach (byte b in buff1)
            {
                sOut += " " + b + ",";
            }

            sOut = sOut.TrimEnd(",".ToCharArray()) + "}";

            Log.Debug("csd-1[] data: ", sOut);
            //while (csd1.HasRemaining)
            //{
            //    buff1[buffi] = csd1.Get();

            //    Log.Debug("csd-1[] data: ",
            //                string.Format("0x{0:X}", buff1[buffi]));

            //    ++buffi;
            //}
            csd1.Position(0);
        }
        /**
         * Tries to obtain the SPS and the PPS for the encoder.
         */
        private long searchSPSandPPS()
        {
            ByteBuffer[] inputBuffers  = mEncoder.GetInputBuffers();
            ByteBuffer[] outputBuffers = mEncoder.GetOutputBuffers();
            BufferInfo   info          = new BufferInfo();

            byte[] csd = new byte[128];
            int    len = 0, p = 4, q = 4;
            long   elapsed = 0, now = timestamp();

            while (elapsed < 3000000 && (mSPS == null || mPPS == null))
            {
                // Some encoders won't give us the SPS and PPS unless they receive something to encode first...
                int bufferIndex = mEncoder.DequeueInputBuffer(1000000 / FRAMERATE);
                if (bufferIndex >= 0)
                {
                    check(inputBuffers[bufferIndex].Capacity() >= mData.Length, "The input buffer is not big enough.");
                    inputBuffers[bufferIndex].Clear();
                    inputBuffers[bufferIndex].Put(mData, 0, mData.Length);
                    mEncoder.QueueInputBuffer(bufferIndex, 0, mData.Length, timestamp(), 0);
                }
                else
                {
                    if (VERBOSE)
                    {
                        Log.e(TAG, "No buffer available !");
                    }
                }

                // We are looking for the SPS and the PPS here. As always, Android is very inconsistent, I have observed that some
                // encoders will give those parameters through the MediaFormat object (that is the normal behaviour).
                // But some other will not, in that case we try to find a NAL unit of type 7 or 8 in the byte stream outputed by the encoder...

                int index = mEncoder.DequeueOutputBuffer(info, 1000000 / FRAMERATE);

                if (index == (int)MediaCodecInfoState.OutputFormatChanged)
                {
                    // The PPS and PPS shoud be there
                    MediaFormat format = mEncoder.OutputFormat;
                    ByteBuffer  spsb   = format.GetByteBuffer("csd-0");
                    ByteBuffer  ppsb   = format.GetByteBuffer("csd-1");
                    mSPS = new byte[spsb.Capacity() - 4];
                    spsb.Position(4);
                    spsb.Get(mSPS, 0, mSPS.Length);
                    mPPS = new byte[ppsb.Capacity() - 4];
                    ppsb.Position(4);
                    ppsb.Get(mPPS, 0, mPPS.Length);
                    break;
                }
                else if (index == (int)MediaCodecInfoState.OutputBuffersChanged)
                {
                    outputBuffers = mEncoder.GetOutputBuffers();
                }
                else if (index >= 0)
                {
                    len = info.Size;
                    if (len < 128)
                    {
                        outputBuffers[index].Get(csd, 0, len);
                        if (len > 0 && csd[0] == 0 && csd[1] == 0 && csd[2] == 0 && csd[3] == 1)
                        {
                            // Parses the SPS and PPS, they could be in two different packets and in a different order
                            //depending on the phone so we don't make any assumption about that
                            while (p < len)
                            {
                                while (!(csd[p + 0] == 0 && csd[p + 1] == 0 && csd[p + 2] == 0 && csd[p + 3] == 1) && p + 3 < len)
                                {
                                    p++;
                                }
                                if (p + 3 >= len)
                                {
                                    p = len;
                                }
                                if ((csd[q] & 0x1F) == 7)
                                {
                                    mSPS = new byte[p - q];
                                    JavaSystem.Arraycopy(csd, q, mSPS, 0, p - q);
                                }
                                else
                                {
                                    mPPS = new byte[p - q];
                                    JavaSystem.Arraycopy(csd, q, mPPS, 0, p - q);
                                }
                                p += 4;
                                q  = p;
                            }
                        }
                    }
                    mEncoder.ReleaseOutputBuffer(index, false);
                }

                elapsed = timestamp() - now;
            }

            check(mPPS != null && mSPS != null, "Could not determine the SPS & PPS.");
            mB64PPS = Base64.EncodeToString(mPPS, 0, mPPS.Length, Base64Flags.NoWrap);
            mB64SPS = Base64.EncodeToString(mSPS, 0, mSPS.Length, Base64Flags.NoWrap);

            return(elapsed);
        }