Exemple #1
0
        /// <summary>
        /// starts a task to decode the video
        /// </summary>
        /// <returns></returns>
        public Task RunAsync()
        {
            //var DecodeThread = new Task(() => Run(), TaskCreationOptions.LongRunning);
            //DecodeThread.Start();
            //return DecodeThread;

            //so we can restart the player.
            decoder = MediaCodec.CreateDecoderByType("video/avc");

            info = new Android.Media.MediaCodec.BufferInfo();

            running = true;

            return (DecodeThread = Task.Run(() => Run()));
        }
Exemple #2
0
 public void OnCryptoError(MediaCodec.CryptoException e)
 {
     if (_internalErrorListener != null)
     {
         _internalErrorListener.OnCryptoError(e);
     }
 }
 public void OnCryptoError(MediaCodec.CryptoException e)
 {
     PrintInternalError("cryptoError", e);
 }
Exemple #4
0
        override public async void Run()
        {
            //Android.Media.MediaExtractor extractor;

            Android.Media.MediaCodec decoder = null;

            using (var extractor = new Android.Media.MediaExtractor())
            //using (Android.Media.MediaCodec decoder = null)
            {
                //extractor = new Android.Media.MediaExtractor();
                try
                {
                    await extractor.SetDataSourceAsync(SAMPLE).ConfigureAwait(false);
                }
                catch (Exception ex)
                {
                    var s = ex.ToString();
                    return;
                }

                for (int i = 0; i < extractor.TrackCount; i++)
                {
                    var format = extractor.GetTrackFormat(i);

                    Log.Debug("Format info: ", format.ToString());

                    String mime = format.GetString(Android.Media.MediaFormat.KeyMime);
                    if (mime.StartsWith("video/"))
                    {
                        Log.Debug("Format mime: ", mime);
                        //Log.Debug("Format " + MediaFormat.KeyMaxInputSize + ": ",
                        //            format.GetInteger(MediaFormat.KeyMaxInputSize).ToString());
                        Log.Debug("Format " + MediaFormat.KeyWidth + ": ",
                                  format.GetInteger(MediaFormat.KeyWidth).ToString());
                        Log.Debug("Format " + MediaFormat.KeyHeight + ": ",
                                  format.GetInteger(MediaFormat.KeyHeight).ToString());

                        PrintFormatInfo(format);

                        extractor.SelectTrack(i);
                        //decoder = Android.Media.MediaCodec.CreateDecoderByType(mime);
                        //this is where the Xamarin Android VM dies.
                        //decoder.Configure(format, surface, null, 0);
                        break;
                    }
                }

                //if (decoder == null)
                //{
                //    Android.Util.Log.Error("DecodeActivity", "Can't find video info!");
                //    return;//can't continue...
                //}
                var f = new Java.IO.File(dir + "decode.out");
                if (f.Exists())
                {
                    f.Delete();
                }

                f.CreateNewFile();

                var f2 = new Java.IO.File(dir + "decode2.out");
                if (f2.Exists())
                {
                    f2.Delete();
                }

                f2.CreateNewFile();

                //open the file for our custom extractor
                var inInfo = new System.IO.FileInfo(SAMPLE);
                if (!inInfo.Exists)
                {
                    Log.Error("input file not found!", inInfo.FullName);
                    return;
                }

                using (var inStream = inInfo.OpenRead())
                    using (var fs2 = new Java.IO.FileOutputStream(f2))   //get an output stream
                        using (var fs = new Java.IO.FileOutputStream(f)) //get an output stream
                        {
                            //var inputBuffers = decoder.GetInputBuffers();
                            //var outputBuffers = decoder.GetOutputBuffers();
                            var  info = new Android.Media.MediaCodec.BufferInfo();
                            bool started = false, isEOS = false;
                            var  sw      = new System.Diagnostics.Stopwatch();
                            long startMs = sw.ElapsedMilliseconds;
                            sw.Start();
                            byte[] peekBuf = new byte[188];
                            //for dumping the sample into instead of the decoder.
                            var buffer = Java.Nio.ByteBuffer.Allocate(165000);// decoder.GetInputBuffer(inIndex);
                            var buffEx = new BufferExtractor();
                            var tmpB   = new byte[20000];


                            while (!interrupted)
                            {
                                //sw.Restart();

                                if (!isEOS)
                                {
                                    int inIndex = 1;// decoder.DequeueInputBuffer(10000);
                                    if (inIndex >= 0)
                                    {
                                        buffer.Position(0);//reset the buffer
                                        if (buffer.Position() != 0)
                                        {
                                            Log.Debug("inBuff.Position: ", buffer.Position().ToString());
                                        }
                                        Log.Debug("inBuff: ", buffer.ToString());

                                        int sampleSize = extractor.ReadSampleData(buffer, 0);
                                        if (sampleSize < 0)
                                        {
                                            // We shouldn't stop the playback at this point, just pass the EOS
                                            // flag to decoder, we will get it again from the
                                            // dequeueOutputBuffer
                                            Log.Debug("DecodeActivity", MediaCodecBufferFlags.EndOfStream.ToString());
                                            //decoder.QueueInputBuffer(inIndex, 0, 0, 0, MediaCodecBufferFlags.EndOfStream);
                                            isEOS = true;
                                        }
                                        else
                                        {
                                            if (peekBuf.Length < sampleSize)
                                            {
                                                peekBuf = new byte[sampleSize];
                                            }
                                            peekBuf.Initialize(); //clear old data.
                                            buffer.Get(peekBuf);
                                            buffer.Position(0);   //reset for the decoder

                                            for (int i = 4; i < peekBuf.Length; ++i)
                                            {
                                                if (peekBuf[i] == 0x01 &&
                                                    peekBuf[i - 1] == 0x00 &&
                                                    peekBuf[i - 2] == 0x00 &&
                                                    peekBuf[i - 3] == 0x00)
                                                {
                                                    Log.Debug("Found h264 start code: ",
                                                              string.Format("i={0} of {1}", i, sampleSize));
                                                }
                                            }

                                            Log.Debug("ExtractorActivity, sampleSize: ", sampleSize.ToString());

                                            if (!started)//get your parser synced with theirs
                                            {
                                                do
                                                {
                                                    peekBuf = new byte[188];
                                                    await inStream.ReadAsync(peekBuf, 0, peekBuf.Length)
                                                    .ConfigureAwait(false);

                                                    buffEx.AddRaw(peekBuf);

                                                    if (buffEx.outBuffers.Count > 0 &&
                                                        buffEx.outBuffers.Peek().GetPayload().Length != sampleSize)
                                                    {
                                                        buffEx.outBuffers.Dequeue();//throw this one away
                                                    }
                                                } while (buffEx.outBuffers.Count == 0);
                                                started = true;
                                            }
                                            else
                                            {
                                                do
                                                {
                                                    peekBuf = new byte[188];
                                                    await inStream.ReadAsync(peekBuf, 0, peekBuf.Length)
                                                    .ConfigureAwait(false);

                                                    buffEx.AddRaw(peekBuf);
                                                } while (buffEx.outBuffers.Count == 0);
                                                started = true;
                                            }

                                            //write out the vid data.
                                            buffer.Limit(sampleSize);
                                            buffer.Position(0);
                                            //if (tmpB.Length < sampleSize)
                                            tmpB = new byte[sampleSize];

                                            buffer.Get(tmpB);
                                            fs.Write(tmpB);

                                            buffer.Limit(buffer.Capacity());//reset the limit for next sample
                                            buffer.Position(0);

                                            fs2.Write(buffEx.outBuffers.Dequeue().GetPayload());

                                            if (!inStream.CanRead)
                                            {
                                                isEOS = true;//end of stream.
                                            }
                                            //decoder.QueueInputBuffer(inIndex, 0, sampleSize, extractor.SampleTime, 0);
                                            await extractor.AdvanceAsync().ConfigureAwait(false);

                                            //extractor.AdvanceAsync();
                                        }
                                    }
                                }


                                // All decoded frames have been rendered, we can stop playing now
                                if ((info.Flags & MediaCodecBufferFlags.EndOfStream) != 0)
                                {
                                    Android.Util.Log.Debug("DecodeActivity",
                                                           MediaCodecBufferFlags.EndOfStream.ToString());
                                    break;
                                }
                            }

                            //decoder.Stop();
                        }
            }
        }