TMediaFormat GetFormat(AndroidJavaObject Extractor)
    {
        int TrackCount = Extractor.Call <int>("getTrackCount");
        //Log ("tracks: " + TrackCount);
        int TrackIndex = GetTrack(Extractor);

        //Log ("selectTrack " + TrackIndex);
        Extractor.Call("selectTrack", TrackIndex);

        //	Log ("getTrackFormat " + TrackIndex);
        try
        {
            TMediaFormat MediaFormat = new TMediaFormat();
            MediaFormat.Format = Extractor.Call <AndroidJavaObject>("getTrackFormat", TrackIndex);
            String FormatDescription = MediaFormat.Format.Call <String>("toString");
            //	Log("format.toString() = " + FormatDescription );

            //	sdk literals
            const String KEY_MIME   = "mime";
            const String KEY_WIDTH  = "width";
            const String KEY_HEIGHT = "height";

            MediaFormat.Mime   = MediaFormat.Format.Call <string>("getString", KEY_MIME);
            MediaFormat.Width  = MediaFormat.Format.Call <int>("getInteger", KEY_WIDTH);
            MediaFormat.Height = MediaFormat.Format.Call <int>("getInteger", KEY_HEIGHT);
            return(MediaFormat);
        }
        catch (Exception e)
        {
            Log("GetFormatException: " + e.Message);
            return(null);
        }
    }
    static TVideoDecoder CreateDecoder(AndroidJavaObject Extractor, TMediaFormat Format)
    {
        TVideoDecoder Decoder = new TVideoDecoder();

        Decoder.Texture = CreateDecoderTexture(Format.Width, Format.Height);
        if (Decoder.Texture == null)
        {
            return(null);
        }

        try
        {
            int TextureId = Decoder.Texture.GetNativeTextureID();
            Decoder.SurfaceTexture = new AndroidJavaObject("android.graphics.SurfaceTexture", TextureId);
            Decoder.Surface        = new AndroidJavaObject("android.view.Surface", Decoder.SurfaceTexture);
        }
        catch (Exception e)
        {
            Log("CreateDecoder::surface:: " + e.Message);
            return(null);
        }

        try
        {
            //	Log ("Creating codec for " + Format.Mime );
            AndroidJavaClass MediaCodecClass = new AndroidJavaClass("android.media.MediaCodec");
            Decoder.Decoder = MediaCodecClass.CallStatic <AndroidJavaObject>("createDecoderByType", Format.Mime);

            //	"configure not found" when supplying surface....
            Decoder.Decoder.Call("configure", Format.Format, Decoder.Surface, null, 0);
            Decoder.Decoder.Call("start");
        }
        catch (Exception e)
        {
            Log("CreateDecoder::create decoder:: " + e.Message);
            return(null);
        }

        return(Decoder);
    }
    static TVideoDecoder CreateDecoder(AndroidJavaObject Extractor,TMediaFormat Format)
    {
        TVideoDecoder Decoder = new TVideoDecoder ();
        Decoder.Texture = CreateDecoderTexture (Format.Width,Format.Height);
        if (Decoder.Texture == null)
            return null;

        try
        {
            int TextureId = Decoder.Texture.GetNativeTextureID();
            Decoder.SurfaceTexture = new AndroidJavaObject("android.graphics.SurfaceTexture", TextureId );
            Decoder.Surface = new AndroidJavaObject("android.view.Surface", Decoder.SurfaceTexture );
        }
        catch ( Exception e )
        {
            Log ("CreateDecoder::surface:: " + e.Message );
            return null;
        }

        try
        {
        //	Log ("Creating codec for " + Format.Mime );
            AndroidJavaClass MediaCodecClass = new AndroidJavaClass("android.media.MediaCodec");
            Decoder.Decoder = MediaCodecClass.CallStatic<AndroidJavaObject>("createDecoderByType", Format.Mime );

            //	"configure not found" when supplying surface....
            Decoder.Decoder.Call("configure", Format.Format, Decoder.Surface, null, 0);
            Decoder.Decoder.Call("start");
        }
        catch ( Exception e )
        {
            Log ("CreateDecoder::create decoder:: " + e.Message );
            return null;
        }

        return Decoder;
    }
    void Init()
    {
        int SdkLevel = GetAndroidSDKLevel();

        Log("Android SDK " + SdkLevel);

        mExtractor = LoadExtractor(mFilename);
        if (mExtractor == null)
        {
            return;
        }

        TMediaFormat Format = GetFormat(mExtractor);

        if (Format == null)
        {
            return;
        }
        Log("Format of track is " + Format.Mime + " " + Format.Width + "x" + Format.Height);
        //jo.Call<android.media.MediaCodec>("createDecoderByType");

        mDecoder     = CreateDecoder(mExtractor, Format);
        mInitialised = true;
    }
    bool ChangeFormat(AndroidJavaObject NewFormat)
    {
        TMediaFormat MediaFormat = new TMediaFormat(NewFormat);

        return(true);
    }
    TMediaFormat GetFormat(AndroidJavaObject Extractor)
    {
        int TrackCount = Extractor.Call<int>("getTrackCount");
        //Log ("tracks: " + TrackCount);
        int TrackIndex = GetTrack (Extractor);
        //Log ("selectTrack " + TrackIndex);
        Extractor.Call ("selectTrack",TrackIndex);

        //	Log ("getTrackFormat " + TrackIndex);
        try
        {
            TMediaFormat MediaFormat = new TMediaFormat();
            MediaFormat.Format = Extractor.Call<AndroidJavaObject>("getTrackFormat",TrackIndex);
            String FormatDescription = MediaFormat.Format.Call<String>("toString");
        //	Log("format.toString() = " + FormatDescription );

            //	sdk literals
            const String KEY_MIME = "mime";
            const String KEY_WIDTH = "width";
            const String KEY_HEIGHT = "height";

            MediaFormat.Mime = MediaFormat.Format.Call<string>("getString", KEY_MIME );
            MediaFormat.Width = MediaFormat.Format.Call<int>("getInteger", KEY_WIDTH );
            MediaFormat.Height = MediaFormat.Format.Call<int>("getInteger", KEY_HEIGHT );
            return MediaFormat;
        }
        catch ( Exception e )
        {
            Log ("GetFormatException: " + e.Message );
            return null;
        }
    }
    bool ChangeFormat(AndroidJavaObject NewFormat)
    {
        TMediaFormat MediaFormat = new TMediaFormat (NewFormat);

        return true;
    }