Example #1
0
        public LibVpxEnc(LibVpxEncConfig cfg)
        {
            vpxCodecIface = Java_com_google_libvpx_LibVpxCom_vpxCodecAllocCodec(JNIEnv.Handle, IntPtr.Zero);
            if (vpxCodecIface == 0)
            {
                throw new LibVpxException("Can not allocate JNI codec object");
            }

            Java_com_google_libvpx_LibVpxEnc_vpxCodecEncInit(JNIEnv.Handle, IntPtr.Zero, vpxCodecIface, cfg.handle());
            if (isError())
            {
                String errorMsg = errorDetailString();
                Java_com_google_libvpx_LibVpxCom_vpxCodecFreeCodec(JNIEnv.Handle, IntPtr.Zero, vpxCodecIface);
                throw new LibVpxException(errorMsg);
            }
        }
Example #2
0
        public void Destroy()
        {
            try
            {
                if (Codec != null)
                {
                    Codec.close();
                    Codec = null;
                }

                if (Config != null)
                {
                    Config.close();
                    Config = null;
                }
            }
            catch (Exception) { }
        }
Example #3
0
        public byte[] Encode(int width, int height, byte[] frame, long fourcc, int rotation)
        {
            try
            {
                if (Codec != null && (width != Config.getWidth() || height != Config.getHeight() || _Bitrate != Config.getRCTargetBitrate() || _MaxQuantizer != Config.getRCMaxQuantizer()))
                {
                    if (Codec != null)
                    {
                        Codec.close();
                        Codec = null;
                    }

                    if (Config != null)
                    {
                        Config.close();
                        Config = null;
                    }
                }

                if (Codec == null)
                {
                    // define configuration options
                    Config = new LibVpxEncConfig(width, height);
                    Config.setTimebase(1, 30);
                    Config.setRCTargetBitrate(_Bitrate);
                    Config.setRCEndUsage(1);      // vpx_rc_mode.VPX_CBR
                    //Config.setKFMode(1); // vpx_kf_mode.VPX_KF_AUTO
                    Config.setKFMinDist(30 * 60); // 1 per min @ 30fps
                    Config.setKFMaxDist(30 * 60); // 1 per min @ 30fps
                    Config.setErrorResilient(1);
                    Config.setLagInFrames(0);
                    Config.setPass(0); // vpx_enc_pass.VPX_RC_ONE_PASS
                    Config.setRCMinQuantizer(0);
                    Config.setRCMaxQuantizer(_MaxQuantizer);
                    Config.setProfile(0);

                    // initialize encoder
                    Codec = new LibVpxEnc(Config);

                    // additional tuning
                    int VP8_ONE_TOKENPARTITION = 0;
                    Codec.setStaticThreshold(1);
                    Codec.setCpuUsed(-12); // only on mobile
                    Codec.setTokenPartitions(VP8_ONE_TOKENPARTITION);
                    Codec.setNoiseSensitivity(0);
                    Codec.setMaxIntraBitratePct(Math.Min(300, (int)(Config.getRCBufOptimalSz() * 0.5f * MaxFramerate / 10)));
                }

                // set flags
                long flag = 0;
                if (SendKeyframe)
                {
                    flag        |= (1 << 0); // VPX_EFLAG_FORCE_KF;
                    SendKeyframe = false;
                }

                // encode
                long deadline = 1; // VPX_DL_REALTIME
                long duration = 90000 / MaxFramerate;
                var  buffer   = Codec.convertByteEncodeFrame(frame, FrameCount, duration, flag, deadline, fourcc, rotation);

                FrameCount++;

                // get frame
                return(buffer);
            }
            catch (Exception ex)
            {
                Log.Error("Could not encode frame.", ex);
            }

            return(null);
        }