From b0f1d9c501cdc2daca72b6f4f2b82566e001c473 Mon Sep 17 00:00:00 2001
From: Boris Grozev <boris@jitsi.org>
Date: Fri, 25 Jan 2013 17:05:32 +0000
Subject: [PATCH] Adds a JNI interface to libvpx via the
 org.jitsi.impl.neomedia.codec.video.VPX class. Adds a VP8 encoder and decoder
 based on that interface.

---
 .../org_jitsi_impl_neomedia_codec_video_VPX.c | 726 +++++++++++++
 .../org_jitsi_impl_neomedia_codec_video_VPX.h | 623 +++++++++++
 ...impl_neomedia_codec_video_VPX_StreamInfo.h |  13 +
 .../jitsi/impl/neomedia/codec/video/VPX.java  | 993 ++++++++++++++++++
 .../neomedia/codec/video/vp8/VPXDecoder.java  | 355 +++++++
 .../neomedia/codec/video/vp8/VPXEncoder.java  | 459 ++++++++
 6 files changed, 3169 insertions(+)
 create mode 100644 src/native/vpx/org_jitsi_impl_neomedia_codec_video_VPX.c
 create mode 100644 src/native/vpx/org_jitsi_impl_neomedia_codec_video_VPX.h
 create mode 100644 src/native/vpx/org_jitsi_impl_neomedia_codec_video_VPX_StreamInfo.h
 create mode 100644 src/org/jitsi/impl/neomedia/codec/video/VPX.java
 create mode 100644 src/org/jitsi/impl/neomedia/codec/video/vp8/VPXDecoder.java
 create mode 100644 src/org/jitsi/impl/neomedia/codec/video/vp8/VPXEncoder.java

diff --git a/src/native/vpx/org_jitsi_impl_neomedia_codec_video_VPX.c b/src/native/vpx/org_jitsi_impl_neomedia_codec_video_VPX.c
new file mode 100644
index 00000000..d8e7a8cf
--- /dev/null
+++ b/src/native/vpx/org_jitsi_impl_neomedia_codec_video_VPX.c
@@ -0,0 +1,726 @@
+/*
+ * Jitsi, the OpenSource Java VoIP and Instant Messaging client.
+ *
+ * Distributable under LGPL license.
+ * See terms of license at gnu.org.
+ */
+#include <stdlib.h>
+#include <string.h>
+#include "org_jitsi_impl_neomedia_codec_video_VPX.h"
+
+#include "vpx/vpx_decoder.h"
+#include "vpx/vpx_encoder.h"
+#include "vpx/vp8dx.h"
+#include "vpx/vp8cx.h"
+#define VPX_CODEC_DISABLE_COMPAT 1
+
+/* Convert the INTERFACE_* constants defined in java to
+   the (vpx_codec_iface_t *)'s used in libvpx */
+#define GET_INTERFACE(x) \
+    (((x) == org_jitsi_impl_neomedia_codec_video_VPX_INTEFACE_VP8_DEC) \
+    ? vpx_codec_vp8_dx() \
+    : (((x) == org_jitsi_impl_neomedia_codec_video_VPX_INTERFACE_VP8_ENC)) \
+        ? vpx_codec_vp8_cx() \
+        : NULL)
+
+#define DEFINE_ENC_CFG_INT_PROPERTY_SETTER(name, property) \
+    JNIEXPORT void JNICALL \
+    Java_org_jitsi_impl_neomedia_codec_video_VPX_codec_1enc_1cfg_1set_1##name \
+            (JNIEnv *env, jclass clazz, jlong cfg, jint value) \
+        { \
+            ((vpx_codec_enc_cfg_t *) (intptr_t) cfg)->property = (int) value; \
+        }
+
+#define DEFINE_IMG_INT_PROPERTY_SETTER(name, property) \
+    JNIEXPORT void JNICALL \
+    Java_org_jitsi_impl_neomedia_codec_video_VPX_img_1set_1##name \
+            (JNIEnv *env, jclass clazz, jlong img, jint value) \
+        { \
+            ((vpx_image_t *) (intptr_t) img)->property = (int) value; \
+        }
+
+
+/*
+ * Method:    codec_ctx_malloc
+ */
+JNIEXPORT jlong JNICALL
+Java_org_jitsi_impl_neomedia_codec_video_VPX_codec_1ctx_1malloc
+    (JNIEnv *env,
+     jclass clazz)
+{
+     return (jlong) (intptr_t) malloc(sizeof(vpx_codec_ctx_t));
+}
+
+/*
+ * Method:    codec_dec_init
+ */
+JNIEXPORT jint JNICALL
+Java_org_jitsi_impl_neomedia_codec_video_VPX_codec_1dec_1init
+    (JNIEnv *env,
+     jclass clazz,
+     jlong context,
+     jint iface,
+     jlong cfg,
+     jlong flags)
+{
+    return (jint) vpx_codec_dec_init(
+                        (vpx_codec_ctx_t *) (intptr_t) context,
+                        GET_INTERFACE(iface),
+                        (vpx_codec_dec_cfg_t *) (intptr_t) cfg,
+                        (vpx_codec_flags_t) flags);
+}
+
+/*
+ * Method:    codec_decode
+ */
+JNIEXPORT jint JNICALL
+Java_org_jitsi_impl_neomedia_codec_video_VPX_codec_1decode
+    (JNIEnv *env,
+     jclass clazz,
+     jlong context,
+     jbyteArray buf,
+     jint buf_offset,
+     jint buf_size,
+     jlong user_priv,
+     jlong deadline)
+{
+    jbyte *buf_ptr = (*env)->GetByteArrayElements(env, buf, NULL);
+
+    vpx_codec_err_t ret;
+    ret = vpx_codec_decode((vpx_codec_ctx_t *) (intptr_t) context,
+                           (uint8_t *) (buf_ptr + buf_offset),
+                           (unsigned int) buf_size,
+                           (void *) (intptr_t) user_priv,
+                           (long) deadline);
+    (*env)->ReleaseByteArrayElements(env, buf, buf_ptr, JNI_ABORT);
+    return (jint) ret;
+}
+
+/*
+ * Method:    codec_get_frame
+ */
+JNIEXPORT jlong JNICALL
+Java_org_jitsi_impl_neomedia_codec_video_VPX_codec_1get_1frame
+    (JNIEnv *env,
+     jclass clazz,
+     jlong context,
+     jlongArray iterArray)
+{
+    jlong *iter_ptr = (*env)->GetLongArrayElements(env, iterArray, NULL);
+
+    vpx_image_t *ret;
+    ret = vpx_codec_get_frame((vpx_codec_ctx_t *) (intptr_t) context,
+                              (vpx_codec_iter_t *) iter_ptr);
+
+    (*env)->ReleaseLongArrayElements(env, iterArray, iter_ptr, 0);
+    return (jlong) (intptr_t) ret;
+}
+
+/*
+ * Method:    codec_destroy
+ */
+JNIEXPORT jint JNICALL
+Java_org_jitsi_impl_neomedia_codec_video_VPX_codec_1destroy
+    (JNIEnv *env,
+     jclass clazz,
+     jlong context)
+{
+    return (jint) vpx_codec_destroy((vpx_codec_ctx_t *) (intptr_t) context);
+}
+
+/*
+ * Method:    codec_get_mem_map
+ */
+JNIEXPORT jint JNICALL
+Java_org_jitsi_impl_neomedia_codec_video_VPX_codec_1get_1mem_1map
+    (JNIEnv *env,
+     jclass clazz,
+     jlong context,
+     jlongArray mmapArray,
+     jlongArray iterArray)
+{
+    jlong *iter_ptr = (*env)->GetLongArrayElements(env, iterArray, NULL);
+    jlong *mmap_ptr = (*env)->GetLongArrayElements(env, mmapArray, NULL);
+
+    vpx_codec_err_t ret;
+    ret = vpx_codec_get_mem_map((vpx_codec_ctx_t *) (intptr_t) context,
+                                (vpx_codec_mmap_t *) mmap_ptr,
+                                (vpx_codec_iter_t *) iter_ptr);
+
+    (*env)->ReleaseLongArrayElements(env, iterArray, iter_ptr, 0);
+    (*env)->ReleaseLongArrayElements(env, mmapArray, mmap_ptr, 0);
+
+    return (jint) ret;
+}
+
+/*
+ * Method:    codec_set_mem_map
+ */
+JNIEXPORT jint JNICALL
+Java_org_jitsi_impl_neomedia_codec_video_VPX_codec_1set_1mem_1map
+    (JNIEnv *env,
+     jclass clazz,
+     jlong context,
+     jlong mmap,
+     jint count)
+{
+    vpx_codec_err_t ret;
+    ret = vpx_codec_set_mem_map((vpx_codec_ctx_t *) (intptr_t) context,
+                                (vpx_codec_mmap_t *) (intptr_t) mmap,
+                                (unsigned int) count);
+    return (jint) ret;
+}
+
+/*
+ * Method:    codec_enc_init
+ */
+JNIEXPORT jint JNICALL
+Java_org_jitsi_impl_neomedia_codec_video_VPX_codec_1enc_1init
+    (JNIEnv *env,
+     jclass clazz,
+     jlong context,
+     jint iface,
+     jlong cfg,
+     jlong flags)
+{
+    return (jint) vpx_codec_enc_init(
+                        (vpx_codec_ctx_t *) (intptr_t) context,
+                        GET_INTERFACE(iface),
+                        (vpx_codec_enc_cfg_t *) (intptr_t) cfg,
+                        (vpx_codec_flags_t) flags);
+}
+
+/*
+ * Method:    codec_enc_config_set
+ */
+JNIEXPORT jint JNICALL
+Java_org_jitsi_impl_neomedia_codec_video_VPX_codec_1enc_1config_1set
+    (JNIEnv *env,
+     jclass clazz,
+     jlong context,
+     jlong cfg)
+{
+    return (jint) vpx_codec_enc_config_set(
+                (vpx_codec_ctx_t *) (intptr_t) context,
+                (vpx_codec_enc_cfg_t *) (intptr_t) context);
+}
+
+/*
+ * Method:    codec_encode
+ */
+JNIEXPORT jint JNICALL
+Java_org_jitsi_impl_neomedia_codec_video_VPX_codec_1encode
+    (JNIEnv *env,
+     jclass clazz,
+     jlong context,
+     jlong jimg,
+     jbyteArray bufArray,
+     jint offset0,
+     jint offset1,
+     jint offset2,
+     jlong pts,
+     jlong duration,
+     jlong flags,
+     jlong deadline)
+{
+    unsigned char *buf
+        = (unsigned char *) (*env)->GetByteArrayElements(env, bufArray, NULL);
+    vpx_image_t *img = (vpx_image_t *) (intptr_t) jimg;
+    img->planes[0] = (buf + offset0);
+    img->planes[1] = (buf + offset1);
+    img->planes[2] = (buf + offset2);
+    img->planes[3] = 0;
+
+    jint ret = (jint) vpx_codec_encode(
+                    (vpx_codec_ctx_t *) (intptr_t) context,
+                    img,
+                    (vpx_codec_pts_t) pts,
+                    (unsigned long) duration,
+                    (vpx_enc_frame_flags_t) flags,
+                    (unsigned long) deadline);
+
+    (*env)->ReleaseByteArrayElements(env, bufArray, (jbyte *)buf, JNI_ABORT);
+    return ret;
+}
+
+/*
+ * Method:    codec_get_cx_data
+ */
+JNIEXPORT jlong JNICALL
+Java_org_jitsi_impl_neomedia_codec_video_VPX_codec_1get_1cx_1data
+    (JNIEnv *env,
+     jclass clazz,
+     jlong context,
+     jlongArray iterArray)
+{
+    jlong *iter_ptr = (*env)->GetLongArrayElements(env, iterArray, NULL);
+
+    const vpx_codec_cx_pkt_t *ret;
+    ret = vpx_codec_get_cx_data((vpx_codec_ctx_t *) (intptr_t) context,
+                                (vpx_codec_iter_t *) iter_ptr);
+
+    (*env)->ReleaseLongArrayElements(env, iterArray, iter_ptr, 0);
+    return (jlong) (intptr_t) ret;
+
+}
+
+/*
+ * Method:    codec_cx_pkt_get_kind
+ */
+JNIEXPORT jint JNICALL
+Java_org_jitsi_impl_neomedia_codec_video_VPX_codec_1cx_1pkt_1get_1kind
+    (JNIEnv *env,
+     jclass clazz,
+     jlong pkt)
+{
+    jint ret = (jint) ((vpx_codec_cx_pkt_t *) (intptr_t) pkt)->kind;
+    return ret;
+}
+
+/*
+ * Method:    codec_cx_pkt_get_size
+ */
+JNIEXPORT jint JNICALL
+Java_org_jitsi_impl_neomedia_codec_video_VPX_codec_1cx_1pkt_1get_1size
+    (JNIEnv *env,
+     jclass clazz,
+     jlong pkt)
+{
+    return (jint) ((vpx_codec_cx_pkt_t *) (intptr_t) pkt)->data.frame.sz;
+}
+
+/*
+ * Method:    codec_cx_pkt_get_data
+ */
+JNIEXPORT jlong JNICALL
+Java_org_jitsi_impl_neomedia_codec_video_VPX_codec_1cx_1pkt_1get_1data
+    (JNIEnv *env,
+     jclass clazz,
+     jlong pkt)
+{
+      return (jlong) (intptr_t)
+                    ((vpx_codec_cx_pkt_t *) (intptr_t) pkt)->data.frame.buf;
+}
+
+/*
+ * Method:    img_malloc
+ */
+JNIEXPORT jlong JNICALL
+Java_org_jitsi_impl_neomedia_codec_video_VPX_img_1malloc
+    (JNIEnv *env,
+     jclass clazz)
+{
+    return (jlong) (intptr_t) malloc(sizeof(vpx_image_t));
+}
+
+/*
+ * Method:    img_get_w
+ */
+JNIEXPORT jint JNICALL
+Java_org_jitsi_impl_neomedia_codec_video_VPX_img_1get_1w
+    (JNIEnv *env,
+     jclass clazz,
+     jlong img)
+{
+    return (jint) ((vpx_image_t *) (intptr_t) img)->w;
+}
+
+/*
+ * Method:    img_get_h
+ */
+JNIEXPORT jint JNICALL
+Java_org_jitsi_impl_neomedia_codec_video_VPX_img_1get_1h
+    (JNIEnv *env,
+     jclass clazz,
+     jlong img)
+{
+    return (jint) ((vpx_image_t *) (intptr_t) img)->h;
+}
+
+/*
+ * Method:    img_get_d_w
+ */
+JNIEXPORT jint JNICALL
+Java_org_jitsi_impl_neomedia_codec_video_VPX_img_1get_1d_1w
+    (JNIEnv *env,
+     jclass clazz,
+     jlong img)
+{
+    return (jint) ((vpx_image_t *) (intptr_t) img)->d_w;
+}
+
+/*
+ * Method:    img_get_d_h
+ */
+JNIEXPORT jint JNICALL
+Java_org_jitsi_impl_neomedia_codec_video_VPX_img_1get_1d_1h
+    (JNIEnv *env,
+     jclass clazz,
+     jlong img)
+{
+    return (jint) ((vpx_image_t *) (intptr_t) img)->d_h;
+}
+
+/*
+ * Method:    img_get_plane0
+ */
+JNIEXPORT jlong JNICALL
+Java_org_jitsi_impl_neomedia_codec_video_VPX_img_1get_1plane0
+    (JNIEnv *env,
+     jclass clazz,
+     jlong img)
+{
+    return (jlong) (intptr_t) ((vpx_image_t *) (intptr_t) img)->planes[0];
+}
+
+/*
+ * Method:    img_get_plane1
+ */
+JNIEXPORT jlong JNICALL
+Java_org_jitsi_impl_neomedia_codec_video_VPX_img_1get_1plane1
+    (JNIEnv *env,
+     jclass clazz,
+     jlong img)
+{
+    return (jlong) (intptr_t) ((vpx_image_t *) (intptr_t) img)->planes[1];
+}
+
+/*
+ * Method:    img_get_plane2
+ */
+JNIEXPORT jlong JNICALL
+Java_org_jitsi_impl_neomedia_codec_video_VPX_img_1get_1plane2
+    (JNIEnv *env,
+     jclass clazz,
+     jlong img)
+{
+    return (jlong) (intptr_t) ((vpx_image_t *) (intptr_t) img)->planes[2];
+}
+
+/*
+ * Method:    img_get_stride0
+ */
+JNIEXPORT jint JNICALL
+Java_org_jitsi_impl_neomedia_codec_video_VPX_img_1get_1stride0
+    (JNIEnv *env,
+     jclass clazz,
+     jlong img)
+{
+    return (jint) ((vpx_image_t *) (intptr_t) img)->stride[0];
+}
+
+/*
+ * Method:    img_get_stride1
+ */
+JNIEXPORT jint JNICALL
+Java_org_jitsi_impl_neomedia_codec_video_VPX_img_1get_1stride1
+    (JNIEnv *env,
+     jclass clazz,
+     jlong img)
+{
+    return (jint) ((vpx_image_t *) (intptr_t) img)->stride[1];
+}
+
+/*
+ * Method:    img_get_stride2
+ */
+JNIEXPORT jint JNICALL
+Java_org_jitsi_impl_neomedia_codec_video_VPX_img_1get_1stride2
+    (JNIEnv *env,
+     jclass clazz,
+     jlong img)
+{
+    return (jint) ((vpx_image_t *) (intptr_t) img)->stride[2];
+}
+
+/*
+ * Method:    img_get_fmt
+ */
+JNIEXPORT jint JNICALL
+Java_org_jitsi_impl_neomedia_codec_video_VPX_img_1get_1fmt
+    (JNIEnv *env,
+     jclass clazz,
+     jlong img)
+{
+    return (jint) ((vpx_image_t *) (intptr_t) img)->fmt;
+}
+
+DEFINE_IMG_INT_PROPERTY_SETTER(w, w)
+DEFINE_IMG_INT_PROPERTY_SETTER(h, h)
+DEFINE_IMG_INT_PROPERTY_SETTER(d_1w, d_w)
+DEFINE_IMG_INT_PROPERTY_SETTER(d_1h, d_h)
+DEFINE_IMG_INT_PROPERTY_SETTER(stride0, stride[0])
+DEFINE_IMG_INT_PROPERTY_SETTER(stride1, stride[1])
+DEFINE_IMG_INT_PROPERTY_SETTER(stride2, stride[2])
+DEFINE_IMG_INT_PROPERTY_SETTER(stride3, stride[3])
+DEFINE_IMG_INT_PROPERTY_SETTER(fmt, fmt)
+DEFINE_IMG_INT_PROPERTY_SETTER(bps, bps)
+
+/*
+ * Method:    img_wrap
+ */
+JNIEXPORT void JNICALL
+Java_org_jitsi_impl_neomedia_codec_video_VPX_img_1wrap
+    (JNIEnv *env,
+     jclass clazz,
+     jlong img,
+     jint fmt,
+     jint d_w,
+     jint d_h,
+     jint align,
+     jlong data)
+{
+    vpx_img_wrap((vpx_image_t *) (intptr_t) img,
+                 (vpx_img_fmt_t) fmt,
+                 (unsigned int) d_w,
+                 (unsigned int) d_h,
+                 (unsigned int) align,
+                 (unsigned char *) (intptr_t) data);
+}
+
+/*
+ * Method:    codec_dec_cfg_malloc
+ */
+JNIEXPORT jlong JNICALL
+Java_org_jitsi_impl_neomedia_codec_video_VPX_codec_1dec_1cfg_1malloc
+    (JNIEnv *env,
+     jclass clazz)
+{
+    return (jlong) (intptr_t) malloc(sizeof(vpx_codec_dec_cfg_t));
+}
+
+/*
+ * Method:    codec_dec_cfg_set_w
+ */
+JNIEXPORT void JNICALL
+Java_org_jitsi_impl_neomedia_codec_video_VPX_codec_1dec_1cfg_1set_1w
+    (JNIEnv *env,
+     jclass clazz,
+     jlong cfg,
+     jint width)
+{
+    ((vpx_codec_dec_cfg_t *) (intptr_t) cfg)->w = width;
+}
+
+/*
+ * Method:    codec_dec_cfg_set_w
+ */
+JNIEXPORT void JNICALL
+Java_org_jitsi_impl_neomedia_codec_video_VPX_codec_1dec_1cfg_1set_1h
+    (JNIEnv *env,
+     jclass clazz,
+     jlong cfg,
+     jint height)
+{
+    ((vpx_codec_dec_cfg_t *) (intptr_t) cfg)->h = height;
+}
+
+/*
+ * Method:    codec_enc_cfg_malloc
+ */
+JNIEXPORT jlong JNICALL
+Java_org_jitsi_impl_neomedia_codec_video_VPX_codec_1enc_1cfg_1malloc
+    (JNIEnv *env, jclass clazz)
+{
+    return (jlong) (intptr_t) malloc(sizeof(vpx_codec_enc_cfg_t));
+}
+
+
+/*
+ * Method:    codec_enc_config_default
+ */
+JNIEXPORT jint JNICALL
+Java_org_jitsi_impl_neomedia_codec_video_VPX_codec_1enc_1config_1default
+    (JNIEnv *env,
+     jclass clazz,
+     jint iface,
+     jlong cfg,
+     jint usage)
+{
+    return vpx_codec_enc_config_default(
+                     GET_INTERFACE(iface),
+                     (vpx_codec_enc_cfg_t *) (intptr_t) cfg,
+                     (int) usage);
+}
+
+DEFINE_ENC_CFG_INT_PROPERTY_SETTER(profile, g_profile)
+DEFINE_ENC_CFG_INT_PROPERTY_SETTER(threads, g_threads)
+DEFINE_ENC_CFG_INT_PROPERTY_SETTER(w, g_w)
+DEFINE_ENC_CFG_INT_PROPERTY_SETTER(h, g_h)
+DEFINE_ENC_CFG_INT_PROPERTY_SETTER(rc_1target_1bitrate, rc_target_bitrate)
+DEFINE_ENC_CFG_INT_PROPERTY_SETTER(rc_1dropframe_1thresh, rc_dropframe_thresh)
+DEFINE_ENC_CFG_INT_PROPERTY_SETTER(rc_1resize_1allowed, rc_resize_allowed)
+DEFINE_ENC_CFG_INT_PROPERTY_SETTER(rc_1resize_1up_1thresh, rc_resize_up_thresh)
+DEFINE_ENC_CFG_INT_PROPERTY_SETTER(rc_1resize_1down_1thresh, rc_resize_down_thresh)
+DEFINE_ENC_CFG_INT_PROPERTY_SETTER(rc_1end_1usage, rc_end_usage)
+DEFINE_ENC_CFG_INT_PROPERTY_SETTER(rc_1min_1quantizer, rc_min_quantizer)
+DEFINE_ENC_CFG_INT_PROPERTY_SETTER(rc_1max_1quantizer, rc_max_quantizer)
+DEFINE_ENC_CFG_INT_PROPERTY_SETTER(rc_1undershoot_1pct, rc_undershoot_pct)
+DEFINE_ENC_CFG_INT_PROPERTY_SETTER(rc_1overshoot_1pct, rc_overshoot_pct)
+DEFINE_ENC_CFG_INT_PROPERTY_SETTER(rc_1buf_1sz, rc_buf_sz)
+DEFINE_ENC_CFG_INT_PROPERTY_SETTER(rc_1buf_1initial_1sz, rc_buf_initial_sz)
+DEFINE_ENC_CFG_INT_PROPERTY_SETTER(rc_1buf_1optimal_1sz, rc_buf_optimal_sz)
+DEFINE_ENC_CFG_INT_PROPERTY_SETTER(kf_1mode, kf_mode)
+DEFINE_ENC_CFG_INT_PROPERTY_SETTER(kf_1min_1dist, kf_min_dist)
+DEFINE_ENC_CFG_INT_PROPERTY_SETTER(kf_1max_1dist, kf_max_dist)
+
+/*
+ * Method:    stream_info_malloc
+ */
+JNIEXPORT jlong JNICALL
+Java_org_jitsi_impl_neomedia_codec_video_VPX_stream_1info_1malloc
+    (JNIEnv *env,
+     jclass clazz)
+{
+    return (jlong) (intptr_t) malloc(sizeof(vpx_codec_stream_info_t));
+}
+
+/*
+ * Method:    stream_info_get_w
+ */
+JNIEXPORT jint JNICALL
+Java_org_jitsi_impl_neomedia_codec_video_VPX_stream_1info_1get_1w
+    (JNIEnv *env,
+     jclass clazz,
+     jlong si)
+{
+    return (jint) ((vpx_codec_stream_info_t *) (intptr_t) si)->w;
+}
+
+/*
+ * Method:    stream_info_get_h
+ */
+JNIEXPORT jint JNICALL
+Java_org_jitsi_impl_neomedia_codec_video_VPX_stream_1info_1get_1h
+    (JNIEnv *env,
+     jclass clazz,
+     jlong si)
+{
+    return (jint) ((vpx_codec_stream_info_t *) (intptr_t) si)->h;
+}
+
+/*
+ * Method:    stream_info_get_is_kf
+ */
+JNIEXPORT jint JNICALL
+Java_org_jitsi_impl_neomedia_codec_video_VPX_stream_1info_1get_1is_1kf
+    (JNIEnv *env,
+     jclass clazz,
+     jlong si)
+{
+    return (jint) ((vpx_codec_stream_info_t *) (intptr_t) si)->h;
+}
+
+/*
+ * Method:    codec_peek_stream_info
+ */
+JNIEXPORT jint JNICALL
+Java_org_jitsi_impl_neomedia_codec_video_VPX_codec_1peek_1stream_1info
+    (JNIEnv *env,
+     jclass clazz,
+     jint iface,
+     jbyteArray buf,
+     jint buf_offset,
+     jint buf_size,
+     jlong si)
+{
+    vpx_codec_err_t ret;
+    jbyte *buf_ptr = (*env)->GetByteArrayElements(env, buf, NULL);
+
+    ret = vpx_codec_peek_stream_info(GET_INTERFACE(iface),
+                                     (uint8_t *) (buf_ptr + buf_offset),
+                                     buf_size,
+                                     (vpx_codec_stream_info_t *) (intptr_t)si);
+    (*env)->ReleaseByteArrayElements(env, buf, buf_ptr, JNI_ABORT);
+    return ret;
+}
+
+/*
+ * Method:    codec_mmap_get_sz
+ */
+JNIEXPORT jlong JNICALL
+Java_org_jitsi_impl_neomedia_codec_video_VPX_codec_1mmap_1get_1sz
+    (JNIEnv *env,
+     jclass clazz,
+     jlong map)
+{
+    return (jlong) ((vpx_codec_mmap_t *) (intptr_t) map)->sz;
+}
+
+/*
+ * Method:    codec_mmap_set_base
+ */
+JNIEXPORT void JNICALL
+Java_org_jitsi_impl_neomedia_codec_video_VPX_codec_1mmap_1set_1base
+    (JNIEnv *env,
+     jclass clazz,
+     jlong map,
+     jlong base)
+{
+    ((vpx_codec_mmap_t *) (intptr_t) map)->base = (void *) (intptr_t) base;
+}
+
+/*
+ * Method:    malloc
+ */
+JNIEXPORT jlong JNICALL
+Java_org_jitsi_impl_neomedia_codec_video_VPX_malloc
+    (JNIEnv *env,
+     jclass clazz,
+     jlong size)
+{
+    return (jlong) (intptr_t) malloc((size_t) size);
+}
+
+/*
+ * Method:    free
+ */
+JNIEXPORT void JNICALL
+Java_org_jitsi_impl_neomedia_codec_video_VPX_free
+    (JNIEnv *env,
+     jclass clazz,
+     jlong ptr)
+{
+    free((void *) (intptr_t) ptr);
+}
+
+/*
+ * Method:    memcpy
+ */
+JNIEXPORT void JNICALL
+Java_org_jitsi_impl_neomedia_codec_video_VPX_memcpy
+    (JNIEnv *env,
+     jclass clazz,
+     jbyteArray dstArray,
+     jlong src,
+     jint n)
+{
+    jbyte *dst = (*env)->GetByteArrayElements(env, dstArray, NULL);
+    memcpy(dst, (char *) (intptr_t) src, n);
+    (*env)->ReleaseByteArrayElements(env, dstArray, dst, 0);
+}
+
+/*
+ * Method:    codec_err_to_string
+ */
+JNIEXPORT jint JNICALL
+Java_org_jitsi_impl_neomedia_codec_video_VPX_codec_1err_1to_1string
+    (JNIEnv *env,
+     jclass clazz,
+     jint err,
+     jbyteArray buf,
+     jint buf_size)
+{
+    const char *err_str = vpx_codec_err_to_string((vpx_codec_err_t) err);
+    jbyte *buf_ptr = (*env)->GetByteArrayElements(env, buf, NULL);
+
+    int i;
+    for(i = 0; i < buf_size-1 && err_str[i] != '\0'; i++)
+        buf_ptr[i] = (jbyte) err_str[i];
+    buf_ptr[i] = (jbyte) '\0';
+
+    (*env)->ReleaseByteArrayElements(env, buf, buf_ptr, 0);
+
+    return i;
+}
+
diff --git a/src/native/vpx/org_jitsi_impl_neomedia_codec_video_VPX.h b/src/native/vpx/org_jitsi_impl_neomedia_codec_video_VPX.h
new file mode 100644
index 00000000..16c62bbe
--- /dev/null
+++ b/src/native/vpx/org_jitsi_impl_neomedia_codec_video_VPX.h
@@ -0,0 +1,623 @@
+/* DO NOT EDIT THIS FILE - it is machine generated */
+#include <jni.h>
+/* Header for class org_jitsi_impl_neomedia_codec_video_VPX */
+
+#ifndef _Included_org_jitsi_impl_neomedia_codec_video_VPX
+#define _Included_org_jitsi_impl_neomedia_codec_video_VPX
+#ifdef __cplusplus
+extern "C" {
+#endif
+#undef org_jitsi_impl_neomedia_codec_video_VPX_CODEC_OK
+#define org_jitsi_impl_neomedia_codec_video_VPX_CODEC_OK 0L
+#undef org_jitsi_impl_neomedia_codec_video_VPX_CODEC_LIST_END
+#define org_jitsi_impl_neomedia_codec_video_VPX_CODEC_LIST_END 9L
+#undef org_jitsi_impl_neomedia_codec_video_VPX_CODEC_USE_XMA
+#define org_jitsi_impl_neomedia_codec_video_VPX_CODEC_USE_XMA 1L
+#undef org_jitsi_impl_neomedia_codec_video_VPX_IMG_FMT_I420
+#define org_jitsi_impl_neomedia_codec_video_VPX_IMG_FMT_I420 258L
+#undef org_jitsi_impl_neomedia_codec_video_VPX_RC_MODE_VBR
+#define org_jitsi_impl_neomedia_codec_video_VPX_RC_MODE_VBR 0L
+#undef org_jitsi_impl_neomedia_codec_video_VPX_RC_MODE_CBR
+#define org_jitsi_impl_neomedia_codec_video_VPX_RC_MODE_CBR 1L
+#undef org_jitsi_impl_neomedia_codec_video_VPX_RC_MODE_CQ
+#define org_jitsi_impl_neomedia_codec_video_VPX_RC_MODE_CQ 2L
+#undef org_jitsi_impl_neomedia_codec_video_VPX_KF_MODE_AUTO
+#define org_jitsi_impl_neomedia_codec_video_VPX_KF_MODE_AUTO 1L
+#undef org_jitsi_impl_neomedia_codec_video_VPX_KF_MODE_DISABLED
+#define org_jitsi_impl_neomedia_codec_video_VPX_KF_MODE_DISABLED 1L
+#undef org_jitsi_impl_neomedia_codec_video_VPX_DL_REALTIME
+#define org_jitsi_impl_neomedia_codec_video_VPX_DL_REALTIME 1L
+#undef org_jitsi_impl_neomedia_codec_video_VPX_CODEC_CX_FRAME_PKT
+#define org_jitsi_impl_neomedia_codec_video_VPX_CODEC_CX_FRAME_PKT 0L
+#undef org_jitsi_impl_neomedia_codec_video_VPX_INTEFACE_VP8_DEC
+#define org_jitsi_impl_neomedia_codec_video_VPX_INTEFACE_VP8_DEC 0L
+#undef org_jitsi_impl_neomedia_codec_video_VPX_INTERFACE_VP8_ENC
+#define org_jitsi_impl_neomedia_codec_video_VPX_INTERFACE_VP8_ENC 1L
+/*
+ * Class:     org_jitsi_impl_neomedia_codec_video_VPX
+ * Method:    codec_ctx_malloc
+ * Signature: ()J
+ */
+JNIEXPORT jlong JNICALL Java_org_jitsi_impl_neomedia_codec_video_VPX_codec_1ctx_1malloc
+  (JNIEnv *, jclass);
+
+/*
+ * Class:     org_jitsi_impl_neomedia_codec_video_VPX
+ * Method:    codec_dec_init
+ * Signature: (JIJJ)I
+ */
+JNIEXPORT jint JNICALL Java_org_jitsi_impl_neomedia_codec_video_VPX_codec_1dec_1init
+  (JNIEnv *, jclass, jlong, jint, jlong, jlong);
+
+/*
+ * Class:     org_jitsi_impl_neomedia_codec_video_VPX
+ * Method:    codec_decode
+ * Signature: (J[BIIJJ)I
+ */
+JNIEXPORT jint JNICALL Java_org_jitsi_impl_neomedia_codec_video_VPX_codec_1decode
+  (JNIEnv *, jclass, jlong, jbyteArray, jint, jint, jlong, jlong);
+
+/*
+ * Class:     org_jitsi_impl_neomedia_codec_video_VPX
+ * Method:    codec_get_frame
+ * Signature: (J[J)J
+ */
+JNIEXPORT jlong JNICALL Java_org_jitsi_impl_neomedia_codec_video_VPX_codec_1get_1frame
+  (JNIEnv *, jclass, jlong, jlongArray);
+
+/*
+ * Class:     org_jitsi_impl_neomedia_codec_video_VPX
+ * Method:    codec_destroy
+ * Signature: (J)I
+ */
+JNIEXPORT jint JNICALL Java_org_jitsi_impl_neomedia_codec_video_VPX_codec_1destroy
+  (JNIEnv *, jclass, jlong);
+
+/*
+ * Class:     org_jitsi_impl_neomedia_codec_video_VPX
+ * Method:    codec_get_mem_map
+ * Signature: (J[J[J)I
+ */
+JNIEXPORT jint JNICALL Java_org_jitsi_impl_neomedia_codec_video_VPX_codec_1get_1mem_1map
+  (JNIEnv *, jclass, jlong, jlongArray, jlongArray);
+
+/*
+ * Class:     org_jitsi_impl_neomedia_codec_video_VPX
+ * Method:    codec_set_mem_map
+ * Signature: (JJI)I
+ */
+JNIEXPORT jint JNICALL Java_org_jitsi_impl_neomedia_codec_video_VPX_codec_1set_1mem_1map
+  (JNIEnv *, jclass, jlong, jlong, jint);
+
+/*
+ * Class:     org_jitsi_impl_neomedia_codec_video_VPX
+ * Method:    codec_enc_init
+ * Signature: (JIJJ)I
+ */
+JNIEXPORT jint JNICALL Java_org_jitsi_impl_neomedia_codec_video_VPX_codec_1enc_1init
+  (JNIEnv *, jclass, jlong, jint, jlong, jlong);
+
+/*
+ * Class:     org_jitsi_impl_neomedia_codec_video_VPX
+ * Method:    codec_enc_config_set
+ * Signature: (JJ)I
+ */
+JNIEXPORT jint JNICALL Java_org_jitsi_impl_neomedia_codec_video_VPX_codec_1enc_1config_1set
+  (JNIEnv *, jclass, jlong, jlong);
+
+/*
+ * Class:     org_jitsi_impl_neomedia_codec_video_VPX
+ * Method:    codec_encode
+ * Signature: (JJ[BIIIJJJJ)I
+ */
+JNIEXPORT jint JNICALL Java_org_jitsi_impl_neomedia_codec_video_VPX_codec_1encode
+  (JNIEnv *, jclass, jlong, jlong, jbyteArray, jint, jint, jint, jlong, jlong, jlong, jlong);
+
+/*
+ * Class:     org_jitsi_impl_neomedia_codec_video_VPX
+ * Method:    codec_get_cx_data
+ * Signature: (J[J)J
+ */
+JNIEXPORT jlong JNICALL Java_org_jitsi_impl_neomedia_codec_video_VPX_codec_1get_1cx_1data
+  (JNIEnv *, jclass, jlong, jlongArray);
+
+/*
+ * Class:     org_jitsi_impl_neomedia_codec_video_VPX
+ * Method:    codec_cx_pkt_get_kind
+ * Signature: (J)I
+ */
+JNIEXPORT jint JNICALL Java_org_jitsi_impl_neomedia_codec_video_VPX_codec_1cx_1pkt_1get_1kind
+  (JNIEnv *, jclass, jlong);
+
+/*
+ * Class:     org_jitsi_impl_neomedia_codec_video_VPX
+ * Method:    codec_cx_pkt_get_size
+ * Signature: (J)I
+ */
+JNIEXPORT jint JNICALL Java_org_jitsi_impl_neomedia_codec_video_VPX_codec_1cx_1pkt_1get_1size
+  (JNIEnv *, jclass, jlong);
+
+/*
+ * Class:     org_jitsi_impl_neomedia_codec_video_VPX
+ * Method:    codec_cx_pkt_get_data
+ * Signature: (J)J
+ */
+JNIEXPORT jlong JNICALL Java_org_jitsi_impl_neomedia_codec_video_VPX_codec_1cx_1pkt_1get_1data
+  (JNIEnv *, jclass, jlong);
+
+/*
+ * Class:     org_jitsi_impl_neomedia_codec_video_VPX
+ * Method:    img_malloc
+ * Signature: ()J
+ */
+JNIEXPORT jlong JNICALL Java_org_jitsi_impl_neomedia_codec_video_VPX_img_1malloc
+  (JNIEnv *, jclass);
+
+/*
+ * Class:     org_jitsi_impl_neomedia_codec_video_VPX
+ * Method:    img_get_w
+ * Signature: (J)I
+ */
+JNIEXPORT jint JNICALL Java_org_jitsi_impl_neomedia_codec_video_VPX_img_1get_1w
+  (JNIEnv *, jclass, jlong);
+
+/*
+ * Class:     org_jitsi_impl_neomedia_codec_video_VPX
+ * Method:    img_get_h
+ * Signature: (J)I
+ */
+JNIEXPORT jint JNICALL Java_org_jitsi_impl_neomedia_codec_video_VPX_img_1get_1h
+  (JNIEnv *, jclass, jlong);
+
+/*
+ * Class:     org_jitsi_impl_neomedia_codec_video_VPX
+ * Method:    img_get_d_w
+ * Signature: (J)I
+ */
+JNIEXPORT jint JNICALL Java_org_jitsi_impl_neomedia_codec_video_VPX_img_1get_1d_1w
+  (JNIEnv *, jclass, jlong);
+
+/*
+ * Class:     org_jitsi_impl_neomedia_codec_video_VPX
+ * Method:    img_get_d_h
+ * Signature: (J)I
+ */
+JNIEXPORT jint JNICALL Java_org_jitsi_impl_neomedia_codec_video_VPX_img_1get_1d_1h
+  (JNIEnv *, jclass, jlong);
+
+/*
+ * Class:     org_jitsi_impl_neomedia_codec_video_VPX
+ * Method:    img_get_plane0
+ * Signature: (J)J
+ */
+JNIEXPORT jlong JNICALL Java_org_jitsi_impl_neomedia_codec_video_VPX_img_1get_1plane0
+  (JNIEnv *, jclass, jlong);
+
+/*
+ * Class:     org_jitsi_impl_neomedia_codec_video_VPX
+ * Method:    img_get_plane1
+ * Signature: (J)J
+ */
+JNIEXPORT jlong JNICALL Java_org_jitsi_impl_neomedia_codec_video_VPX_img_1get_1plane1
+  (JNIEnv *, jclass, jlong);
+
+/*
+ * Class:     org_jitsi_impl_neomedia_codec_video_VPX
+ * Method:    img_get_plane2
+ * Signature: (J)J
+ */
+JNIEXPORT jlong JNICALL Java_org_jitsi_impl_neomedia_codec_video_VPX_img_1get_1plane2
+  (JNIEnv *, jclass, jlong);
+
+/*
+ * Class:     org_jitsi_impl_neomedia_codec_video_VPX
+ * Method:    img_get_stride0
+ * Signature: (J)I
+ */
+JNIEXPORT jint JNICALL Java_org_jitsi_impl_neomedia_codec_video_VPX_img_1get_1stride0
+  (JNIEnv *, jclass, jlong);
+
+/*
+ * Class:     org_jitsi_impl_neomedia_codec_video_VPX
+ * Method:    img_get_stride1
+ * Signature: (J)I
+ */
+JNIEXPORT jint JNICALL Java_org_jitsi_impl_neomedia_codec_video_VPX_img_1get_1stride1
+  (JNIEnv *, jclass, jlong);
+
+/*
+ * Class:     org_jitsi_impl_neomedia_codec_video_VPX
+ * Method:    img_get_stride2
+ * Signature: (J)I
+ */
+JNIEXPORT jint JNICALL Java_org_jitsi_impl_neomedia_codec_video_VPX_img_1get_1stride2
+  (JNIEnv *, jclass, jlong);
+
+/*
+ * Class:     org_jitsi_impl_neomedia_codec_video_VPX
+ * Method:    img_get_fmt
+ * Signature: (J)I
+ */
+JNIEXPORT jint JNICALL Java_org_jitsi_impl_neomedia_codec_video_VPX_img_1get_1fmt
+  (JNIEnv *, jclass, jlong);
+
+/*
+ * Class:     org_jitsi_impl_neomedia_codec_video_VPX
+ * Method:    img_set_w
+ * Signature: (JI)V
+ */
+JNIEXPORT void JNICALL Java_org_jitsi_impl_neomedia_codec_video_VPX_img_1set_1w
+  (JNIEnv *, jclass, jlong, jint);
+
+/*
+ * Class:     org_jitsi_impl_neomedia_codec_video_VPX
+ * Method:    img_set_h
+ * Signature: (JI)V
+ */
+JNIEXPORT void JNICALL Java_org_jitsi_impl_neomedia_codec_video_VPX_img_1set_1h
+  (JNIEnv *, jclass, jlong, jint);
+
+/*
+ * Class:     org_jitsi_impl_neomedia_codec_video_VPX
+ * Method:    img_set_d_w
+ * Signature: (JI)V
+ */
+JNIEXPORT void JNICALL Java_org_jitsi_impl_neomedia_codec_video_VPX_img_1set_1d_1w
+  (JNIEnv *, jclass, jlong, jint);
+
+/*
+ * Class:     org_jitsi_impl_neomedia_codec_video_VPX
+ * Method:    img_set_d_h
+ * Signature: (JI)V
+ */
+JNIEXPORT void JNICALL Java_org_jitsi_impl_neomedia_codec_video_VPX_img_1set_1d_1h
+  (JNIEnv *, jclass, jlong, jint);
+
+/*
+ * Class:     org_jitsi_impl_neomedia_codec_video_VPX
+ * Method:    img_set_stride0
+ * Signature: (JI)V
+ */
+JNIEXPORT void JNICALL Java_org_jitsi_impl_neomedia_codec_video_VPX_img_1set_1stride0
+  (JNIEnv *, jclass, jlong, jint);
+
+/*
+ * Class:     org_jitsi_impl_neomedia_codec_video_VPX
+ * Method:    img_set_stride1
+ * Signature: (JI)V
+ */
+JNIEXPORT void JNICALL Java_org_jitsi_impl_neomedia_codec_video_VPX_img_1set_1stride1
+  (JNIEnv *, jclass, jlong, jint);
+
+/*
+ * Class:     org_jitsi_impl_neomedia_codec_video_VPX
+ * Method:    img_set_stride2
+ * Signature: (JI)V
+ */
+JNIEXPORT void JNICALL Java_org_jitsi_impl_neomedia_codec_video_VPX_img_1set_1stride2
+  (JNIEnv *, jclass, jlong, jint);
+
+/*
+ * Class:     org_jitsi_impl_neomedia_codec_video_VPX
+ * Method:    img_set_stride3
+ * Signature: (JI)V
+ */
+JNIEXPORT void JNICALL Java_org_jitsi_impl_neomedia_codec_video_VPX_img_1set_1stride3
+  (JNIEnv *, jclass, jlong, jint);
+
+/*
+ * Class:     org_jitsi_impl_neomedia_codec_video_VPX
+ * Method:    img_set_fmt
+ * Signature: (JI)V
+ */
+JNIEXPORT void JNICALL Java_org_jitsi_impl_neomedia_codec_video_VPX_img_1set_1fmt
+  (JNIEnv *, jclass, jlong, jint);
+
+/*
+ * Class:     org_jitsi_impl_neomedia_codec_video_VPX
+ * Method:    img_set_bps
+ * Signature: (JI)V
+ */
+JNIEXPORT void JNICALL Java_org_jitsi_impl_neomedia_codec_video_VPX_img_1set_1bps
+  (JNIEnv *, jclass, jlong, jint);
+
+/*
+ * Class:     org_jitsi_impl_neomedia_codec_video_VPX
+ * Method:    img_wrap
+ * Signature: (JIIIIJ)V
+ */
+JNIEXPORT void JNICALL Java_org_jitsi_impl_neomedia_codec_video_VPX_img_1wrap
+  (JNIEnv *, jclass, jlong, jint, jint, jint, jint, jlong);
+
+/*
+ * Class:     org_jitsi_impl_neomedia_codec_video_VPX
+ * Method:    codec_dec_cfg_malloc
+ * Signature: ()J
+ */
+JNIEXPORT jlong JNICALL Java_org_jitsi_impl_neomedia_codec_video_VPX_codec_1dec_1cfg_1malloc
+  (JNIEnv *, jclass);
+
+/*
+ * Class:     org_jitsi_impl_neomedia_codec_video_VPX
+ * Method:    codec_dec_cfg_set_w
+ * Signature: (JI)V
+ */
+JNIEXPORT void JNICALL Java_org_jitsi_impl_neomedia_codec_video_VPX_codec_1dec_1cfg_1set_1w
+  (JNIEnv *, jclass, jlong, jint);
+
+/*
+ * Class:     org_jitsi_impl_neomedia_codec_video_VPX
+ * Method:    codec_dec_cfg_set_h
+ * Signature: (JI)V
+ */
+JNIEXPORT void JNICALL Java_org_jitsi_impl_neomedia_codec_video_VPX_codec_1dec_1cfg_1set_1h
+  (JNIEnv *, jclass, jlong, jint);
+
+/*
+ * Class:     org_jitsi_impl_neomedia_codec_video_VPX
+ * Method:    codec_enc_cfg_malloc
+ * Signature: ()J
+ */
+JNIEXPORT jlong JNICALL Java_org_jitsi_impl_neomedia_codec_video_VPX_codec_1enc_1cfg_1malloc
+  (JNIEnv *, jclass);
+
+/*
+ * Class:     org_jitsi_impl_neomedia_codec_video_VPX
+ * Method:    codec_enc_config_default
+ * Signature: (IJI)I
+ */
+JNIEXPORT jint JNICALL Java_org_jitsi_impl_neomedia_codec_video_VPX_codec_1enc_1config_1default
+  (JNIEnv *, jclass, jint, jlong, jint);
+
+/*
+ * Class:     org_jitsi_impl_neomedia_codec_video_VPX
+ * Method:    codec_enc_cfg_set_profile
+ * Signature: (JI)V
+ */
+JNIEXPORT void JNICALL Java_org_jitsi_impl_neomedia_codec_video_VPX_codec_1enc_1cfg_1set_1profile
+  (JNIEnv *, jclass, jlong, jint);
+
+/*
+ * Class:     org_jitsi_impl_neomedia_codec_video_VPX
+ * Method:    codec_enc_cfg_set_threads
+ * Signature: (JI)V
+ */
+JNIEXPORT void JNICALL Java_org_jitsi_impl_neomedia_codec_video_VPX_codec_1enc_1cfg_1set_1threads
+  (JNIEnv *, jclass, jlong, jint);
+
+/*
+ * Class:     org_jitsi_impl_neomedia_codec_video_VPX
+ * Method:    codec_enc_cfg_set_w
+ * Signature: (JI)V
+ */
+JNIEXPORT void JNICALL Java_org_jitsi_impl_neomedia_codec_video_VPX_codec_1enc_1cfg_1set_1w
+  (JNIEnv *, jclass, jlong, jint);
+
+/*
+ * Class:     org_jitsi_impl_neomedia_codec_video_VPX
+ * Method:    codec_enc_cfg_set_h
+ * Signature: (JI)V
+ */
+JNIEXPORT void JNICALL Java_org_jitsi_impl_neomedia_codec_video_VPX_codec_1enc_1cfg_1set_1h
+  (JNIEnv *, jclass, jlong, jint);
+
+/*
+ * Class:     org_jitsi_impl_neomedia_codec_video_VPX
+ * Method:    codec_enc_cfg_set_rc_target_bitrate
+ * Signature: (JI)V
+ */
+JNIEXPORT void JNICALL Java_org_jitsi_impl_neomedia_codec_video_VPX_codec_1enc_1cfg_1set_1rc_1target_1bitrate
+  (JNIEnv *, jclass, jlong, jint);
+
+/*
+ * Class:     org_jitsi_impl_neomedia_codec_video_VPX
+ * Method:    codec_enc_cfg_set_rc_dropframe_thresh
+ * Signature: (JI)V
+ */
+JNIEXPORT void JNICALL Java_org_jitsi_impl_neomedia_codec_video_VPX_codec_1enc_1cfg_1set_1rc_1dropframe_1thresh
+  (JNIEnv *, jclass, jlong, jint);
+
+/*
+ * Class:     org_jitsi_impl_neomedia_codec_video_VPX
+ * Method:    codec_enc_cfg_set_rc_resize_allowed
+ * Signature: (JI)V
+ */
+JNIEXPORT void JNICALL Java_org_jitsi_impl_neomedia_codec_video_VPX_codec_1enc_1cfg_1set_1rc_1resize_1allowed
+  (JNIEnv *, jclass, jlong, jint);
+
+/*
+ * Class:     org_jitsi_impl_neomedia_codec_video_VPX
+ * Method:    codec_enc_cfg_set_rc_resize_up_thresh
+ * Signature: (JI)V
+ */
+JNIEXPORT void JNICALL Java_org_jitsi_impl_neomedia_codec_video_VPX_codec_1enc_1cfg_1set_1rc_1resize_1up_1thresh
+  (JNIEnv *, jclass, jlong, jint);
+
+/*
+ * Class:     org_jitsi_impl_neomedia_codec_video_VPX
+ * Method:    codec_enc_cfg_set_rc_resize_down_thresh
+ * Signature: (JI)V
+ */
+JNIEXPORT void JNICALL Java_org_jitsi_impl_neomedia_codec_video_VPX_codec_1enc_1cfg_1set_1rc_1resize_1down_1thresh
+  (JNIEnv *, jclass, jlong, jint);
+
+/*
+ * Class:     org_jitsi_impl_neomedia_codec_video_VPX
+ * Method:    codec_enc_cfg_set_rc_end_usage
+ * Signature: (JI)V
+ */
+JNIEXPORT void JNICALL Java_org_jitsi_impl_neomedia_codec_video_VPX_codec_1enc_1cfg_1set_1rc_1end_1usage
+  (JNIEnv *, jclass, jlong, jint);
+
+/*
+ * Class:     org_jitsi_impl_neomedia_codec_video_VPX
+ * Method:    codec_enc_cfg_set_rc_min_quantizer
+ * Signature: (JI)V
+ */
+JNIEXPORT void JNICALL Java_org_jitsi_impl_neomedia_codec_video_VPX_codec_1enc_1cfg_1set_1rc_1min_1quantizer
+  (JNIEnv *, jclass, jlong, jint);
+
+/*
+ * Class:     org_jitsi_impl_neomedia_codec_video_VPX
+ * Method:    codec_enc_cfg_set_rc_max_quantizer
+ * Signature: (JI)V
+ */
+JNIEXPORT void JNICALL Java_org_jitsi_impl_neomedia_codec_video_VPX_codec_1enc_1cfg_1set_1rc_1max_1quantizer
+  (JNIEnv *, jclass, jlong, jint);
+
+/*
+ * Class:     org_jitsi_impl_neomedia_codec_video_VPX
+ * Method:    codec_enc_cfg_set_rc_undershoot_pct
+ * Signature: (JI)V
+ */
+JNIEXPORT void JNICALL Java_org_jitsi_impl_neomedia_codec_video_VPX_codec_1enc_1cfg_1set_1rc_1undershoot_1pct
+  (JNIEnv *, jclass, jlong, jint);
+
+/*
+ * Class:     org_jitsi_impl_neomedia_codec_video_VPX
+ * Method:    codec_enc_cfg_set_rc_overshoot_pct
+ * Signature: (JI)V
+ */
+JNIEXPORT void JNICALL Java_org_jitsi_impl_neomedia_codec_video_VPX_codec_1enc_1cfg_1set_1rc_1overshoot_1pct
+  (JNIEnv *, jclass, jlong, jint);
+
+/*
+ * Class:     org_jitsi_impl_neomedia_codec_video_VPX
+ * Method:    codec_enc_cfg_set_rc_buf_sz
+ * Signature: (JI)V
+ */
+JNIEXPORT void JNICALL Java_org_jitsi_impl_neomedia_codec_video_VPX_codec_1enc_1cfg_1set_1rc_1buf_1sz
+  (JNIEnv *, jclass, jlong, jint);
+
+/*
+ * Class:     org_jitsi_impl_neomedia_codec_video_VPX
+ * Method:    codec_enc_cfg_set_rc_buf_initial_sz
+ * Signature: (JI)V
+ */
+JNIEXPORT void JNICALL Java_org_jitsi_impl_neomedia_codec_video_VPX_codec_1enc_1cfg_1set_1rc_1buf_1initial_1sz
+  (JNIEnv *, jclass, jlong, jint);
+
+/*
+ * Class:     org_jitsi_impl_neomedia_codec_video_VPX
+ * Method:    codec_enc_cfg_set_rc_buf_optimal_sz
+ * Signature: (JI)V
+ */
+JNIEXPORT void JNICALL Java_org_jitsi_impl_neomedia_codec_video_VPX_codec_1enc_1cfg_1set_1rc_1buf_1optimal_1sz
+  (JNIEnv *, jclass, jlong, jint);
+
+/*
+ * Class:     org_jitsi_impl_neomedia_codec_video_VPX
+ * Method:    codec_enc_cfg_set_kf_mode
+ * Signature: (JI)V
+ */
+JNIEXPORT void JNICALL Java_org_jitsi_impl_neomedia_codec_video_VPX_codec_1enc_1cfg_1set_1kf_1mode
+  (JNIEnv *, jclass, jlong, jint);
+
+/*
+ * Class:     org_jitsi_impl_neomedia_codec_video_VPX
+ * Method:    codec_enc_cfg_set_kf_min_dist
+ * Signature: (JI)V
+ */
+JNIEXPORT void JNICALL Java_org_jitsi_impl_neomedia_codec_video_VPX_codec_1enc_1cfg_1set_1kf_1min_1dist
+  (JNIEnv *, jclass, jlong, jint);
+
+/*
+ * Class:     org_jitsi_impl_neomedia_codec_video_VPX
+ * Method:    codec_enc_cfg_set_kf_max_dist
+ * Signature: (JI)V
+ */
+JNIEXPORT void JNICALL Java_org_jitsi_impl_neomedia_codec_video_VPX_codec_1enc_1cfg_1set_1kf_1max_1dist
+  (JNIEnv *, jclass, jlong, jint);
+
+/*
+ * Class:     org_jitsi_impl_neomedia_codec_video_VPX
+ * Method:    stream_info_malloc
+ * Signature: ()J
+ */
+JNIEXPORT jlong JNICALL Java_org_jitsi_impl_neomedia_codec_video_VPX_stream_1info_1malloc
+  (JNIEnv *, jclass);
+
+/*
+ * Class:     org_jitsi_impl_neomedia_codec_video_VPX
+ * Method:    stream_info_get_w
+ * Signature: (J)I
+ */
+JNIEXPORT jint JNICALL Java_org_jitsi_impl_neomedia_codec_video_VPX_stream_1info_1get_1w
+  (JNIEnv *, jclass, jlong);
+
+/*
+ * Class:     org_jitsi_impl_neomedia_codec_video_VPX
+ * Method:    stream_info_get_h
+ * Signature: (J)I
+ */
+JNIEXPORT jint JNICALL Java_org_jitsi_impl_neomedia_codec_video_VPX_stream_1info_1get_1h
+  (JNIEnv *, jclass, jlong);
+
+/*
+ * Class:     org_jitsi_impl_neomedia_codec_video_VPX
+ * Method:    stream_info_get_is_kf
+ * Signature: (J)I
+ */
+JNIEXPORT jint JNICALL Java_org_jitsi_impl_neomedia_codec_video_VPX_stream_1info_1get_1is_1kf
+  (JNIEnv *, jclass, jlong);
+
+/*
+ * Class:     org_jitsi_impl_neomedia_codec_video_VPX
+ * Method:    codec_peek_stream_info
+ * Signature: (I[BIIJ)I
+ */
+JNIEXPORT jint JNICALL Java_org_jitsi_impl_neomedia_codec_video_VPX_codec_1peek_1stream_1info
+  (JNIEnv *, jclass, jint, jbyteArray, jint, jint, jlong);
+
+/*
+ * Class:     org_jitsi_impl_neomedia_codec_video_VPX
+ * Method:    codec_mmap_get_sz
+ * Signature: (J)J
+ */
+JNIEXPORT jlong JNICALL Java_org_jitsi_impl_neomedia_codec_video_VPX_codec_1mmap_1get_1sz
+  (JNIEnv *, jclass, jlong);
+
+/*
+ * Class:     org_jitsi_impl_neomedia_codec_video_VPX
+ * Method:    codec_mmap_set_base
+ * Signature: (JJ)V
+ */
+JNIEXPORT void JNICALL Java_org_jitsi_impl_neomedia_codec_video_VPX_codec_1mmap_1set_1base
+  (JNIEnv *, jclass, jlong, jlong);
+
+/*
+ * Class:     org_jitsi_impl_neomedia_codec_video_VPX
+ * Method:    malloc
+ * Signature: (J)J
+ */
+JNIEXPORT jlong JNICALL Java_org_jitsi_impl_neomedia_codec_video_VPX_malloc
+  (JNIEnv *, jclass, jlong);
+
+/*
+ * Class:     org_jitsi_impl_neomedia_codec_video_VPX
+ * Method:    free
+ * Signature: (J)V
+ */
+JNIEXPORT void JNICALL Java_org_jitsi_impl_neomedia_codec_video_VPX_free
+  (JNIEnv *, jclass, jlong);
+
+/*
+ * Class:     org_jitsi_impl_neomedia_codec_video_VPX
+ * Method:    memcpy
+ * Signature: ([BJI)V
+ */
+JNIEXPORT void JNICALL Java_org_jitsi_impl_neomedia_codec_video_VPX_memcpy
+  (JNIEnv *, jclass, jbyteArray, jlong, jint);
+
+/*
+ * Class:     org_jitsi_impl_neomedia_codec_video_VPX
+ * Method:    codec_err_to_string
+ * Signature: (I[BI)I
+ */
+JNIEXPORT jint JNICALL Java_org_jitsi_impl_neomedia_codec_video_VPX_codec_1err_1to_1string
+  (JNIEnv *, jclass, jint, jbyteArray, jint);
+
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/src/native/vpx/org_jitsi_impl_neomedia_codec_video_VPX_StreamInfo.h b/src/native/vpx/org_jitsi_impl_neomedia_codec_video_VPX_StreamInfo.h
new file mode 100644
index 00000000..7cb5fd1e
--- /dev/null
+++ b/src/native/vpx/org_jitsi_impl_neomedia_codec_video_VPX_StreamInfo.h
@@ -0,0 +1,13 @@
+/* DO NOT EDIT THIS FILE - it is machine generated */
+#include <jni.h>
+/* Header for class org_jitsi_impl_neomedia_codec_video_VPX_StreamInfo */
+
+#ifndef _Included_org_jitsi_impl_neomedia_codec_video_VPX_StreamInfo
+#define _Included_org_jitsi_impl_neomedia_codec_video_VPX_StreamInfo
+#ifdef __cplusplus
+extern "C" {
+#endif
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/src/org/jitsi/impl/neomedia/codec/video/VPX.java b/src/org/jitsi/impl/neomedia/codec/video/VPX.java
new file mode 100644
index 00000000..d44b7928
--- /dev/null
+++ b/src/org/jitsi/impl/neomedia/codec/video/VPX.java
@@ -0,0 +1,993 @@
+/*
+ * Jitsi, the OpenSource Java VoIP and Instant Messaging client.
+ *
+ * Distributable under LGPL license.
+ * See terms of license at gnu.org.
+ */
+package org.jitsi.impl.neomedia.codec.video;
+
+/**
+ * A wrapper for the libvpx native library.
+ * See {@link "http://www.webmproject.org/docs/"}
+ *
+ * @author Boris Grozev
+ */
+public class VPX {
+    /**
+     * Operation completed without error.
+     * Corresponds to <tt>VPX_CODEC_OK</tt> from <tt>vpx/vpx_codec.h</tt>
+     */
+    public static final int CODEC_OK = 0;
+
+    /**
+     * An iterator reached the end of list.
+     * Corresponds to <tt>VPX_CODEC_LIST_END</tt> from <tt>vpx/vpx_codec.h</tt>
+     */
+    public static final int CODEC_LIST_END = 9;
+
+    /**
+     * Use eXternal Memory Allocation mode flag
+     * Corresponds to <tt>VPX_CODEC_USE_XMA</tt> from <tt>vpx/vpx_codec.h</tt>
+     */
+    public static final int CODEC_USE_XMA = 0x00000001;
+
+    /**
+     * I420 format constant
+     * Corresponds to <tt>VPX_IMG_FMT_I420</tt> from <tt>vpx/vpx_image.h</tt>
+
+     */
+    public static final int IMG_FMT_I420 = 258;
+
+    /**
+     * Variable Bitrate mode.
+     * Corresponds to <tt>VPX_VBR</tt> from <tt>vpx/vpx_encoder.h</tt>
+     */
+    public static final int RC_MODE_VBR = 0;
+
+    /**
+     * Constant Bitrate mode.
+     * Corresponds to <tt>VPX_CBR</tt> from <tt>vpx/vpx_encoder.h</tt>
+     */
+    public static final int RC_MODE_CBR = 1;
+
+    /**
+     * Constant Quality mode.
+     * Corresponds to <tt>VPX_CQ</tt> from <tt>vpx/vpx_encoder.h</tt>
+     */
+    public static final int RC_MODE_CQ = 2;
+
+    /**
+     * Encoder determines optimal placement automatically.
+     * Corresponds to <tt>VPX_KF_AUTO</tt> from in <tt>vpx/vpx_encoder.h</tt>
+     */
+    public static final int KF_MODE_AUTO = 1;
+
+    /**
+     * Encoder does not place keyframes.
+     * Corresponds to <tt>VPX_KF_DISABLED</tt> from <tt>vpx/vpx_encoder.h</tt>
+     */
+    public static final int KF_MODE_DISABLED = 1;
+
+    /**
+     * Process and return as soon as possible ('realtime' deadline)
+     * Corresponds to <tt>VPX_DL_REALTIME</tt> from <tt>vpx/vpx_encoder.h</tt>
+     */
+    public static final int DL_REALTIME = 1;
+
+    /**
+     * Compressed video frame packet type.
+     * Corresponds to <tt>VPX_CODEC_CX_FRAME_PKT</tt> from
+     * <tt>vpx/vpx_encoder.h</tt>
+     */
+    public static final int CODEC_CX_FRAME_PKT = 0;
+
+
+    /**
+     * Constant for VP8 decoder interface
+     */
+    public static final int INTEFACE_VP8_DEC = 0;
+
+    /**
+     * Constant for VP8 encoder interface
+     */
+    public static final int INTERFACE_VP8_ENC = 1;
+
+    /**
+     * Allocates memory for a <tt>vpx_codec_ctx_t</tt> on the heap.
+     *
+     * @return A pointer to the allocated memory.
+     */
+    public static native long codec_ctx_malloc();
+
+    /**
+     * Initializes a vpx decoder context.
+     * @param context Pointer to a pre-allocated <tt>vpx_codec_ctx_t</tt>.
+     * @param iface Interface to be used. Has to be one of the
+     * <tt>VPX.INTERFACE_*</tt> constants.
+     * @param cfg Pointer to a pre-allocated <tt>vpx_codec_dec_cfg_t</tt>, may
+     * be 0.
+     * @param flags Flags.
+     *
+     * @return <tt>CODEC_OK</tt> on success, or an error code otherwise. The
+     * error code can be converted to a <tt>String</tt> with
+     * {@link VPX#codec_err_to_string(int)}
+     */
+    public static native int codec_dec_init(long context,
+                                            int iface,
+                                            long cfg,
+                                            long flags);
+
+    /**
+     * Decodes the frame in <tt>buf</tt>, at offset <tt>buf_offset</tt>.
+     *
+     * @param context The context to use.
+     * @param buf Encoded frame buffer.
+     * @param buf_offset Offset into <tt>buf</tt> where the encoded frame begins.
+     * @param buf_size Size of the encoded frame.
+     * @param user_priv Application specific data to associate with this frame.
+     * @param deadline Soft deadline the decoder should attempt to meet,
+     * in microseconds. Set to zero for unlimited.
+     *
+     * @return <tt>CODEC_OK</tt> on success, or an error code otherwise. The
+     * error code can be converted to a <tt>String</tt> with
+     * {@link VPX#codec_err_to_string(int)}
+     */
+    public static native int codec_decode(long context,
+                                          byte[] buf,
+                                          int buf_offset,
+                                          int buf_size,
+                                          long user_priv,
+                                          long deadline);
+
+    /**
+     * Gets the next frame available to display from the decoder context
+     * <tt>context</tt>.
+     * The list of available frames becomes valid upon completion of the
+     * <tt>codec_decode</tt> call, and remains valid until the next call to
+     * <tt>codec_decode</tt>.
+     *
+     * @param context The decoder context to use.
+     * @param iter Iterator storage, initialized by setting it's first element
+     * to 0.
+     *
+     * @return Pointer to a <tt>vpx_image_t</tt> describing the decoded frame,
+     * or 0 if no more frames are available
+     */
+    public static native long codec_get_frame(long context,
+                                              long[] iter);
+
+    /**
+     * Destroys a codec context, freeing any associated memory buffers.
+     *
+     * @param context Pointer to the <tt>vpx_codec_ctx_t</tt> context to destroy.
+     *
+     * @return <tt>CODEC_OK</tt> on success, or an error code otherwise. The
+     * error code can be converted to a <tt>String</tt> with
+     * {@link VPX#codec_err_to_string(int)}
+     */
+    public static native int codec_destroy(long context);
+
+    /**
+     * Iterate over the list of segments to allocate.
+     *
+     * This function can only be used on codec implementations which have the
+     * XMA (eXternam Memory Allocation) capability.
+     *
+     * Iterates over a list of the segments to allocate. The iterator storage
+     * should be initialized to NULL to start the iteration. Iteration is
+     * complete when this function returns VPX_CODEC_LIST_END. The amount of
+     * memory needed to allocate is dependent upon the size of the encoded
+     * stream. In cases where the stream is not available at allocation time,
+     * a fixed size must be requested. The codec will not be able to operate on
+     * streams larger than the size used at allocation time.
+     *
+     * @param context The codec context to use.
+     * @param mmap Pointer to a <tt>vpx_codec_mmap_t</tt> to populate
+     * @param iter Iterator storage, initialized by setting it's first element
+     * to 0.
+     *
+     * @return <tt>CODEC_OK</tt> on success, or an error code otherwise. The
+     * error code can be converted to a <tt>String</tt> with
+     * {@link VPX#codec_err_to_string(int)}
+     */
+    public static native int codec_get_mem_map(long context,
+                                               long mmap[],
+                                               long[] iter);
+
+    /**
+     * Identify allocated segments to codec instance.
+     *
+     * This function can only be used on codec implementations which have the
+     * XMA (eXternam Memory Allocation) capability.
+     *
+     * @param context The codec context to use.
+     * @param mmap Pointer to the first memory map entry in the list.
+     * @param count Number of entries being set at this time.
+     *
+     * @return <tt>CODEC_OK</tt> on success, or an error code otherwise. The
+     * error code can be converted to a <tt>String</tt> with
+     * {@link VPX#codec_err_to_string(int)}
+     */
+    public static native int codec_set_mem_map(long context,
+                                               long mmap,
+                                               int count);
+
+    /**
+     * Initializes a vpx encoder context.
+     *
+     * @param context Pointer to a pre-allocated <tt>vpx_codec_ctx_t</tt>.
+     * @param iface Interface to be used. Has to be one of the
+     * <tt>VPX.INTERFACE_*</tt> constants.
+     * @param cfg Pointer to a pre-allocated <tt>vpx_codec_enc_cfg_t</tt>,
+     * may be 0.
+     * @param flags Flags.
+     *
+     * @return <tt>CODEC_OK</tt> on success, or an error code otherwise. The
+     * error code can be converted to a <tt>String</tt> with
+     * {@link VPX#codec_err_to_string(int)}
+     */
+    public static native int codec_enc_init(long context,
+                                            int iface,
+                                            long cfg,
+                                            long flags);
+
+    /**
+     *
+     * @param context Pointer to the codec context on which to set the
+     * confirutation
+     * @param cfg Pointer to a <tt>vpx_codec_enc_cfg_t</tt> to set.
+     *
+     * @return <tt>CODEC_OK</tt> on success, or an error code otherwise. The
+     * error code can be converted to a <tt>String</tt> with
+     * {@link VPX#codec_err_to_string(int)}
+     */
+    public static native int codec_enc_config_set(long context,
+                                                  long cfg);
+
+    /**
+     * Encodes the frame described by <tt>img</tt>, <tt>buf</tt>,
+     * <tt>offset0</tt>, <tt>offset1</tt> and <tt>offset2</tt>.
+     *
+     * Note that <tt>buf</tt> and the offsets describe where the frames is
+     * stored, but <tt>img</tt> has to have all of it's other parameters (format,
+     * dimensions, strides) already set.
+     *
+     * The reason <tt>buf</tt> and the offsets are treated differently is to
+     * allow for the encoder to operate on java memory and avoid copying the raw
+     * frame to native memory.
+     *
+     * @param context Pointer to the codec context to use.
+     * @param img Pointer to a <tt>vpx_image_t</tt> describing the raw frame
+     * @param buf Contains the raw frame
+     * @param offset0 Offset of the first plane
+     * @param offset1 Offset of the second plane
+     * @param offset2 Offset of the third plane
+     * @param pts Presentation time stamp, in timebase units.
+     * @param duration Duration to show frame, in timebase units.
+     * @param flags Flags to use for encoding this frame.
+     * @param deadline Time to spend encoding, in microseconds. (0=infinite)
+     *
+     * @return <tt>CODEC_OK</tt> on success, or an error code otherwise. The
+     * error code can be converted to a <tt>String</tt> with
+     * {@link VPX#codec_err_to_string(int)}
+     */
+    public static native int codec_encode(long context,
+                                          long img,
+                                          byte[] buf,
+                                          int offset0,
+                                          int offset1,
+                                          int offset2,
+                                          long pts,
+                                          long duration,
+                                          long flags,
+                                          long deadline);
+
+    /**
+     * Encoded data iterator.
+     * Iterates over a list of data packets to be passed from the encoder to
+     * the application. The kind of a packet can be determined using
+     * {@link VPX#codec_cx_pkt_get_kind}
+     * Packets of kind <tt>CODEC_CX_FRAME_PKT</tt> should be passed to the
+     * application's muxer.
+     *
+     * @param context The codec context to use.
+     * @param iter Iterator storage, initialized by setting it's first element
+     * to 0.
+     *
+     * @return Pointer to a vpx_codec_cx_pkt_t containing the output data
+     * packet, or 0 to indicate the end of available packets
+     */
+    public static native long codec_get_cx_data(long context,
+                                                long[] iter);
+
+    /**
+     * Returns the <tt>kind</tt> of the <tt>vpx_codec_cx_pkt_t</tt> pointed to
+     * by <tt>pkt</tt>.
+     *
+     * @param pkt Pointer to the <tt>vpx_codec_cx_pkt_t</tt> to return the
+     * <tt>kind</tt> of.
+     * @return The kind of <tt>pkt</tt>.
+     */
+    public static native int codec_cx_pkt_get_kind(long pkt);
+
+    /**
+     * Returns the size of the data in the <tt>vpx_codec_cx_pkt_t</tt> pointed
+     * to by <tt>pkt</tt>. Can only be used for packets of <tt>kind</tt>
+     * <tt>CODEC_CX_FRAME_PKT</tt>.
+     *
+     * @param pkt Pointer to a <tt>vpx_codec_cx_pkt_t</tt>.
+     *
+     * @return The size of the data of <tt>pkt</tt>.
+     */
+    public static native int codec_cx_pkt_get_size(long pkt);
+
+    /**
+     * Returns a pointer to the data in the <tt>vpx_codec_cx_pkt_t</tt> pointed
+     * to by<tt>pkt</tt>. Can only be used for packets of <tt>kind</tt>
+     * <tt>CODEC_CX_FRAME_PKT</tt>.
+     *
+     * @param pkt Pointer to the <tt>vpx_codec_cx_pkt_t</tt>.
+     * @return Pointer to the data of <tt>pkt</tt>.
+     */
+    public static native long codec_cx_pkt_get_data(long pkt);
+
+    //img
+    /**
+     * Allocates memory for a <tt>vpx_image_t</tt> on the heap.
+     *
+     * @return A pointer to the allocated memory.
+     */
+    public static native long img_malloc();
+
+    /**
+     * Returns the value of the <tt>w</tt> (width) field of a
+     * <tt>vpx_image_t</tt>.
+     *
+     * @param img Pointer to a <tt>vpx_image_t</tt>.
+     *
+     * @return The <tt>w</tt> (width) field of <tt>img</tt>.
+     */
+    public static native int img_get_w(long img);
+
+    /**
+     * Returns the value of the <tt>h</tt> (height) field of a
+     * <tt>vpx_image_t</tt>.
+     *
+     * @param img Pointer to a <tt>vpx_image_t</tt>.
+     *
+     * @return The <tt>h</tt> (height) field of <tt>img</tt>.
+     */
+    public static native int img_get_h(long img);
+
+    /**
+     * Returns the value of the <tt>d_w</tt> (displayed width) field of a
+     * <tt>vpx_image_t</tt>.
+     *
+     * @param img Pointer to a <tt>vpx_image_t</tt>.
+     *
+     * @return The <tt>d_w</tt> (displayed width) field of <tt>img</tt>.
+     */
+    public static native int img_get_d_w(long img);
+
+    /**
+     * Returns the value of the <tt>d_h</tt> (displayed height) field of a
+     * <tt>vpx_image_t</tt>.
+     *
+     * @param img Pointer to a <tt>vpx_image_t</tt>.
+     *
+     * @return The <tt>d_h</tt> (displayed height) field of <tt>img</tt>.
+     */
+    public static native int img_get_d_h(long img);
+
+    /**
+     * Returns the value of the <tt>planes[0]</tt> field of a
+     * <tt>vpx_image_t</tt>.
+     *
+     * @param img Pointer to a <tt>vpx_image_t</tt>.
+     *
+     * @return The <tt>planes[0]</tt> field of <tt>img</tt>.
+     */
+    public static native long img_get_plane0(long img);
+
+    /**
+     * Returns the value of the <tt>planes[1]</tt> field of a
+     * <tt>vpx_image_t</tt>.
+     *
+     * @param img Pointer to a <tt>vpx_image_t</tt>.
+     *
+     * @return The <tt>planes[1]</tt> field of <tt>img</tt>.
+     */
+    public static native long img_get_plane1(long img);
+
+    /**
+     * Returns the value of the <tt>planes[2]</tt> field of a
+     * <tt>vpx_image_t</tt>.
+     *
+     * @param img Pointer to a <tt>vpx_image_t</tt>.
+     *
+     * @return The <tt>planes[2]</tt> field of <tt>img</tt>.
+     */
+    public static native long img_get_plane2(long img);
+
+    /**
+     * Returns the value of the <tt>stride[0]</tt> field of a
+     * <tt>vpx_image_t</tt>.
+     *
+     * @param img Pointer to a <tt>vpx_image_t</tt>.
+     *
+     * @return The <tt>stride[0]</tt> field of <tt>img</tt>.
+     */
+    public static native int img_get_stride0(long img);
+
+    /**
+     * Returns the value of the <tt>stride[1]</tt> field of a
+     * <tt>vpx_image_t</tt>.
+     *
+     * @param img Pointer to a <tt>vpx_image_t</tt>.
+     *
+     * @return The <tt>stride[1]</tt> field of <tt>img</tt>.
+     */
+    public static native int img_get_stride1(long img);
+
+    /**
+     * Returns the value of the <tt>stride[2]</tt> field of a
+     * <tt>vpx_image_t</tt>.
+     *
+     * @param img Pointer to a <tt>vpx_image_t</tt>.
+     *
+     * @return The <tt>stride[2]</tt> field of <tt>img</tt>.
+     */
+    public static native int img_get_stride2(long img);
+
+    /**
+     * Returns the value of the <tt>fmt</tt> field of a
+     * <tt>vpx_image_t</tt>.
+     *
+     * @param img Pointer to a <tt>vpx_image_t</tt>.
+     *
+     * @return The <tt>fmt</tt> field of <tt>img</tt>.
+     */
+    public static native int img_get_fmt(long img);
+
+    /**
+     * Sets the <tt>w</tt> (width) field of a <tt>vpx_image_t</tt>.
+     * @param img Pointer to a <tt>vpx_image_t</tt>.
+     * @param value The value to set.
+     */
+    public static native void img_set_w(long img, int value);
+
+    /**
+     * Sets the <tt>h</tt> (height) field of a <tt>vpx_image_t</tt>.
+     * @param img Pointer to a <tt>vpx_image_t</tt>.
+     * @param value The value to set.
+     */
+    public static native void img_set_h(long img, int value);
+
+    /**
+     * Sets the <tt>d_w</tt> (displayed width) field of a <tt>vpx_image_t</tt>.
+     * @param img Pointer to a <tt>vpx_image_t</tt>.
+     * @param value The value to set.
+     */
+    public static native void img_set_d_w(long img, int value);
+
+    /**
+     * Sets the <tt>d_h</tt> (displayed height) field of a <tt>vpx_image_t</tt>.
+     * @param img Pointer to a <tt>vpx_image_t</tt>.
+     * @param value The value to set.
+     */
+    public static native void img_set_d_h(long img, int value);
+
+    /**
+     * Sets the <tt>stride[0]</tt> field of a <tt>vpx_image_t</tt>.
+     * @param img Pointer to a <tt>vpx_image_t</tt>.
+     * @param value The value to set.
+     */
+    public static native void img_set_stride0(long img, int value);
+
+    /**
+     * Sets the <tt>stride[1]</tt> field of a <tt>vpx_image_t</tt>.
+     * @param img Pointer to a <tt>vpx_image_t</tt>.
+     * @param value The value to set.
+     */
+    public static native void img_set_stride1(long img, int value);
+
+    /**
+     * Sets the <tt>stride[2]</tt> field of a <tt>vpx_image_t</tt>.
+     * @param img Pointer to a <tt>vpx_image_t</tt>.
+     * @param value The value to set.
+     */
+    public static native void img_set_stride2(long img, int value);
+
+    /**
+     * Sets the <tt>stride[3]</tt> field of a <tt>vpx_image_t</tt>.
+     * @param img Pointer to a <tt>vpx_image_t</tt>.
+     * @param value The value to set.
+     */
+    public static native void img_set_stride3(long img, int value);
+
+    /**
+     * Sets the <tt>fmt</tt> (format) field of a <tt>vpx_image_t</tt>.
+     * @param img Pointer to a <tt>vpx_image_t</tt>.
+     * @param value The value to set.
+     */
+    public static native void img_set_fmt(long img, int value);
+
+    /**
+     * Sets the <tt>bps</tt> (bits per sample) field of a <tt>vpx_image_t</tt>.
+     * @param img Pointer to a <tt>vpx_image_t</tt>.
+     * @param value The value to set.
+     */
+    public static native void img_set_bps(long img, int value);
+
+    /**
+     * Open a descriptor, using existing storage for the underlying image.
+     *
+     * Returns a descriptor for storing an image of the given format. The
+     * storage for descriptor has been allocated elsewhere, and a descriptor is
+     * desired to "wrap" that storage.
+     *
+     * @param img Pointer to a <tt>vpx_image_t</tt>.
+     * @param fmt Format of the image.
+     * @param d_w Width of the image.
+     * @param d_h Height of the image.
+     * @param align Alignment, in bytes, of each row in the image.
+     * @param data Storage to use for the image
+     */
+    public static native void img_wrap(long img,
+                                       int fmt,
+                                       int d_w,
+                                       int d_h,
+                                       int align,
+                                       long data);
+
+    /**
+     * Allocates memory for a <tt>vpx_codec_dec_cfg_t</tt> on the heap.
+     *
+     * @return A pointer to the allocated memory.
+     */
+    public static native long codec_dec_cfg_malloc();
+
+    /**
+     * Sets the <tt>w</tt> field of a <tt>vpx_codec_dec_cfg_t</tt>.
+     *
+     * @param cfg Pointer to a <tt>vpx_codec_dec_cfg_t</tt>.
+     * @param value The value to set.
+     */
+    public static native void codec_dec_cfg_set_w(long cfg, int value);
+
+    /**
+     * Sets the <tt>h</tt> field of a <tt>vpx_codec_dec_cfg_t</tt>.
+     *
+     * @param cfg Pointer to a <tt>vpx_codec_dec_cfg_t</tt>.
+     * @param value The value to set.
+     */
+    public static native void codec_dec_cfg_set_h(long cfg, int value);
+
+    /**
+     * Allocates memory for a <tt>vpx_codec_enc_cfg_t</tt> on the heap.
+     *
+     * @return A pointer to the allocated memory.
+     */
+    public static native long codec_enc_cfg_malloc();
+
+    /**
+     * Initializes a encoder configuration structure with default values.
+     *
+     * @param iface Interface. Should be one of the <tt>INTERFACE_*</tt>
+     * constants
+     * @param cfg Pointer to the vpx_codec_enc_cfg_t to initialize
+     * @param usage End usage. Set to 0 or use codec specific values.
+     *
+     * @return <tt>CODEC_OK</tt> on success, or an error code otherwise. The
+     * error code can be converted to a <tt>String</tt> with
+     * {@link VPX#codec_err_to_string(int)}
+     */
+    public static native int codec_enc_config_default(int iface,
+                                                      long cfg,
+                                                      int usage);
+
+    /**
+     * Sets the <tt>g_profile</tt> field of a <tt>vpx_codec_enc_cfg_t</tt>.
+     *
+     * @param cfg Pointer to a <tt>vpx_codec_enc_cfg_t</tt>
+     * @param value The value to set.
+     */
+    public static native void codec_enc_cfg_set_profile(long cfg,
+                                                        int value);
+
+    /**
+     * Sets the <tt>g_threads</tt> field of a <tt>vpx_codec_enc_cfg_t</tt>.
+     *
+     * @param cfg Pointer to a <tt>vpx_codec_enc_cfg_t</tt>.
+     * @param value The value to set.
+     */
+    public static native void codec_enc_cfg_set_threads(long cfg,
+                                                        int value);
+
+    /**
+     * Sets the <tt>g_w</tt> field of a <tt>vpx_codec_enc_cfg_t</tt>.
+     *
+     * @param cfg Pointer to a <tt>vpx_codec_enc_cfg_t</tt>.
+     * @param value The value to set.
+     */
+    public static native void codec_enc_cfg_set_w(long cfg,
+                                                  int value);
+
+    /**
+     * Sets the <tt>g_h</tt> field of a <tt>vpx_codec_enc_cfg_t</tt>.
+     *
+     * @param cfg Pointer to a <tt>vpx_codec_enc_cfg_t</tt>.
+     * @param value The value to set.
+     */
+    public static native void codec_enc_cfg_set_h(long cfg,
+                                                  int value);
+
+    /**
+     * Sets the <tt>rc_target_bitrate</tt> field of a
+     * <tt>vpx_codec_enc_cfg_t</tt>.
+     *
+     * @param cfg Pointer to a <tt>vpx_codec_enc_cfg_t</tt>.
+     * @param value The value to set.
+     */
+    public static native void codec_enc_cfg_set_rc_target_bitrate(long cfg,
+                                                                  int value);
+
+    /**
+     * Sets the <tt>rc_dropframe_thresh</tt> field of a
+     * <tt>vpx_codec_enc_cfg_t</tt>.
+     *
+     * @param cfg Pointer to a <tt>vpx_codec_enc_cfg_t</tt>.
+     * @param value The value to set.
+     */
+    public static native void codec_enc_cfg_set_rc_dropframe_thresh(long cfg,
+                                                                    int value);
+
+    /**
+     * Sets the <tt>rc_resize_allowed</tt> field of a
+     * <tt>vpx_codec_enc_cfg_t</tt>.
+     *
+     * @param cfg Pointer to a <tt>vpx_codec_enc_cfg_t</tt>.
+     * @param value The value to set.
+     */
+    public static native void codec_enc_cfg_set_rc_resize_allowed(long cfg,
+                                                                  int value);
+
+    /**
+     * Sets the <tt>rc_resize_up_thresh</tt> field of a
+     * <tt>vpx_codec_enc_cfg_t</tt>.
+     *
+     * @param cfg Pointer to a <tt>vpx_codec_enc_cfg_t</tt>.
+     * @param value The value to set.
+     */
+    public static native void codec_enc_cfg_set_rc_resize_up_thresh(long cfg,
+                                                                    int value);
+
+    /**
+     * Sets the <tt>rc_resize_down_thresh</tt> field of a
+     * <tt>vpx_codec_enc_cfg_t</tt>.
+     *
+     * @param cfg Pointer to a <tt>vpx_codec_enc_cfg_t</tt>.
+     * @param value The value to set.
+     */
+    public static native void codec_enc_cfg_set_rc_resize_down_thresh(long cfg,
+                                                                      int value);
+
+    /**
+     * Sets the <tt>rc_end_usage</tt> field of a <tt>vpx_codec_enc_cfg_t</tt>.
+     *
+     * @param cfg Pointer to a <tt>vpx_codec_enc_cfg_t</tt>.
+     * @param value The value to set.
+     */
+    public static native void codec_enc_cfg_set_rc_end_usage(long cfg,
+                                                             int value);
+
+    /**
+     * Sets the <tt>rc_min_quantizer</tt> field of a <tt>vpx_codec_enc_cfg_t</tt>.
+     *
+     * @param cfg Pointer to a <tt>vpx_codec_enc_cfg_t</tt>.
+     * @param value The value to set.
+     */
+    public static native void codec_enc_cfg_set_rc_min_quantizer(long cfg,
+                                                                 int value);
+
+    /**
+     * Sets the <tt>rc_max_quantizer</tt> field of a <tt>vpx_codec_enc_cfg_t</tt>.
+     *
+     * @param cfg Pointer to a <tt>vpx_codec_enc_cfg_t</tt>.
+     * @param value The value to set.
+     */
+    public static native void codec_enc_cfg_set_rc_max_quantizer(long cfg,
+                                                                 int value);
+
+    /**
+     * Sets the <tt>rc_undershoot_pct</tt> field of a <tt>vpx_codec_enc_cfg_t</tt>.
+     *
+     * @param cfg Pointer to a <tt>vpx_codec_enc_cfg_t</tt>.
+     * @param value The value to set.
+     */
+    public static native void codec_enc_cfg_set_rc_undershoot_pct(long cfg,
+                                                                  int value);
+
+    /**
+     * Sets the <tt>rc_overshoot_pct</tt> field of a
+     * <tt>vpx_codec_enc_cfg_t</tt>.
+     *
+     * @param cfg Pointer to a <tt>vpx_codec_enc_cfg_t</tt>.
+     * @param value The value to set.
+     */
+    public static native void codec_enc_cfg_set_rc_overshoot_pct(long cfg,
+                                                                 int value);
+
+    /**
+     * Sets the <tt>rc_buf_sz</tt> field of a <tt>vpx_codec_enc_cfg_t</tt>.
+     *
+     * @param cfg Pointer to a <tt>vpx_codec_enc_cfg_t</tt>.
+     * @param value The value to set.
+     */
+    public static native void codec_enc_cfg_set_rc_buf_sz(long cfg,
+                                                          int value);
+
+    /**
+     * Sets the <tt>rc_buf_initial_sz</tt> field of a
+     * <tt>vpx_codec_enc_cfg_t</tt>.
+     *
+     * @param cfg Pointer to a <tt>vpx_codec_enc_cfg_t</tt>.
+     * @param value The value to set.
+     */
+    public static native void codec_enc_cfg_set_rc_buf_initial_sz(long cfg,
+                                                                  int value);
+
+    /**
+     * Sets the <tt>rc_buf_optimal_sz</tt> field of a
+     * <tt>vpx_codec_enc_cfg_t</tt>.
+     *
+     * @param cfg Pointer to a <tt>vpx_codec_enc_cfg_t</tt>.
+     * @param value The value to set.
+     */
+    public static native void codec_enc_cfg_set_rc_buf_optimal_sz(long cfg,
+                                                                  int value);
+
+    /**
+     * Sets the <tt>kf_mode</tt> field of a <tt>vpx_codec_enc_cfg_t</tt>.
+     *
+     * @param cfg Pointer to a <tt>vpx_codec_enc_cfg_t</tt>.
+     * @param value The value to set.
+     */
+    public static native void codec_enc_cfg_set_kf_mode(long cfg,
+                                                        int value);
+
+    /**
+     * Sets the <tt>kf_min_dist</tt> field of a <tt>vpx_codec_enc_cfg_t</tt>.
+     *
+     * @param cfg Pointer to a <tt>vpx_codec_enc_cfg_t</tt>.
+     * @param value The value to set.
+     */
+    public static native void codec_enc_cfg_set_kf_min_dist(long cfg,
+                                                            int value);
+
+    /**
+     * Sets the <tt>kf_max_dist</tt> field of a <tt>vpx_codec_enc_cfg_t</tt>.
+     *
+     * @param cfg Pointer to a <tt>vpx_codec_enc_cfg_t</tt>.
+     * @param value The value to set.
+     */
+    public static native void codec_enc_cfg_set_kf_max_dist(long cfg,
+                                                            int value);
+
+    /**
+     * Allocates memory for a <tt>vpx_codec_stream_info_t</tt> on the heap.
+     *
+     * @return A pointer to the allocated memory.
+     */
+    public static native long stream_info_malloc();
+
+
+    /**
+     * Returns the <tt>w</tt> field of a <tt>vpx_codec_stream_info_t</tt>.
+     *
+     * @param stream_info Pointer to a <tt>vpx_codec_stream_info_t</tt>.
+     *
+     * @return The <tt>w</tt> field of a <tt>stream_info</tt>.
+     */
+    public static native int stream_info_get_w(long stream_info);
+
+    /**
+     * Returns the <tt>h</tt> field of a <tt>vpx_codec_stream_info_t</tt>.
+     *
+     * @param stream_info Pointer to a <tt>vpx_codec_stream_info_t</tt>.
+     *
+     * @return The <tt>h</tt> field of a <tt>stream_info</tt>.
+     */
+    public static native int stream_info_get_h(long stream_info);
+
+
+    /**
+     * Returns the <tt>is_kf</tt> field of a <tt>vpx_codec_stream_info_t</tt>.
+     *
+     * @param stream_info Pointer to a <tt>vpx_codec_stream_info_t</tt>.
+     *
+     * @return The <tt>w</tt> field of a <tt>stream_info</tt>.
+     */
+    public static native int stream_info_get_is_kf(long stream_info);
+
+
+    /**
+     * Performs high level parsing of the bitstream. Construction of a decoder
+     * context is not necessary. Can be used to determine if the bitstream is
+     * of the proper format, and to extract information from the stream.
+     *
+     * @param iface Interface, should be one of the <tt>INTERFACE_*</tt>
+     * constants.
+     * @param buf Buffer containing a compressed frame.
+     * @param buf_offset Offset into <tt>buf</tt> where the compressed frame
+     * begins.
+     * @param buf_size Size of the compressed frame.
+     * @param si_ptr Pointer to a <tt>vpx_codec_stream_info_t</tt> which will
+     * be filled with information about the compressed frame.
+     *
+     * @return <tt>CODEC_OK</tt> on success, or an error code otherwise. The
+     * error code can be converted to a <tt>String</tt> with
+     * {@link VPX#codec_err_to_string(int)}
+     */
+    public static native int codec_peek_stream_info(int iface,
+                                                    byte[] buf,
+                                                    int buf_offset,
+                                                    int buf_size,
+                                                    long si_ptr);
+
+    /**
+     * Gets the <tt>sz</tt> field of a <tt>vpx_codec_mmap_t</tt>.
+     *
+     * @param mmap Pointer to a <tt>vpx_codec_mmap_t</tt>
+     * @return The <tt>sz</tt> field of <tt>mmap</tt>
+     */
+    public static native long codec_mmap_get_sz(long mmap);
+
+    /**
+     * Sets the <tt>base</tt> field of a <tt>vpx_codec_mmap_t</tt>
+     *
+     * @param mmap Pointer to a <tt>vpx_codec_mmap_t</tt>
+     * @param base The value to set.
+     */
+    public static native void codec_mmap_set_base(long mmap, long base);
+
+
+    /**
+     * Allocates memorry on the heap (a simple wrapped around the native
+     * <tt>malloc()</tt>)
+     * @param s Number of bytes to allocate
+     *
+     * @return Pointer to the memory allocated.
+     */
+    public static native long malloc(long s);
+
+    /**
+     * Frees memory, which has been allocated with {@link VPX#malloc(long)} or
+     * one of the <tt>*_malloc()</tt> functions.
+     *
+     * @param ptr Pointer to the memory to free.
+     */
+    public static native void free(long ptr);
+
+    /**
+     * Copies <tt>n</tt> bytes from <tt>src</tt> to <tt>dst</tt>. Simple wrapper
+     * around the native <tt>memcpy()</tt> funciton.
+     *
+     * @param dst Destination.
+     * @param src Source.
+     * @param n Number of bytes to copy.
+     */
+    public static native void memcpy(byte[] dst, long src, int n);
+
+    /**
+     * Fills in <tt>buf</tt> with a string description of the error code
+     * <tt>err</tt>. Fills at most <tt>buf_size</tt> bytes of <tt>buf</tt>
+     *
+     * @param err Error code
+     * @param buf Buffer to copy the string into
+     * @param buf_size Buffer size
+     *
+     * @return The number of bytes written to <tt>buf</tt>
+     */
+    public static native int codec_err_to_string(int err,
+                                                 byte[] buf,
+                                                 int buf_size);
+
+    /**
+     * Returns a <tt>String</tt> describing the error code <tt>err</tt>.
+     * @param err Error code
+     *
+     * @return A <tt>String</tt> describing the error code <tt>err</tt>.
+     */
+    public static String codec_err_to_string(int err)
+    {
+        byte[] buf = new byte[100];
+        codec_err_to_string(err, buf, buf.length);
+        return new String(buf);
+    }
+
+
+
+    static
+    {
+        System.loadLibrary("jnvpx");
+    }
+
+    /**
+     * Java wrapper around vpx_codec_stream_info_t. Contains basic information,
+     * obtainable from an encoded frame without a decoder context.
+     */
+    static class StreamInfo
+    {
+        /**
+         * Width
+         */
+        int w;
+
+        /**
+         * Height
+         */
+        int h;
+
+        /**
+         * Is keyframe
+         */
+        boolean is_kf;
+
+        /**
+         * Initializes this instance by parsing <tt>buf</tt>
+         *
+         * @param iface Interface, should be one of the <tt>INTERFACE_*</tt>
+         * constants.
+         * @param buf Buffer containing a compressed frame to parse.
+         * @param buf_offset Offset into buffer where the compressed frame
+         * begins.
+         * @param buf_size Size of the compressed frame.
+         */
+        StreamInfo(int iface, byte[] buf, int buf_offset, int buf_size)
+        {
+            long si = stream_info_malloc();
+
+            if(codec_peek_stream_info(iface, buf, buf_offset, buf_size, si)
+                    != CODEC_OK)
+                return;
+
+            w = stream_info_get_w(si);
+            h = stream_info_get_h(si);
+            is_kf = stream_info_get_is_kf(si) != 0;
+
+            if(si != 0)
+                free(si);
+        }
+
+        /**
+         * Gets the <tt>w</tt> (width) field of this instance.
+         *
+         * @return the <tt>w</tt> (width) field of this instance.
+         */
+        public int getW()
+        {
+            return w;
+        }
+
+        /**
+         * Gets the <tt>h</tt> (height) field of this instance.
+         *
+         * @return the <tt>h</tt> (height) field of this instance.
+         */
+        public int getH()
+        {
+            return h;
+        }
+
+        /**
+         * Gets the <tt>is_kf</tt> (is keyframe) field of this instance.
+         *
+         * @return the <tt>is_kf</tt> (is keyframe) field of this instance.
+         */
+        public boolean isKf()
+        {
+            return is_kf;
+        }
+    }
+}
diff --git a/src/org/jitsi/impl/neomedia/codec/video/vp8/VPXDecoder.java b/src/org/jitsi/impl/neomedia/codec/video/vp8/VPXDecoder.java
new file mode 100644
index 00000000..405cb609
--- /dev/null
+++ b/src/org/jitsi/impl/neomedia/codec/video/vp8/VPXDecoder.java
@@ -0,0 +1,355 @@
+/*
+ * Jitsi, the OpenSource Java VoIP and Instant Messaging client.
+ *
+ * Distributable under LGPL license.
+ * See terms of license at gnu.org.
+ */
+package org.jitsi.impl.neomedia.codec.video.vp8;
+
+import org.jitsi.impl.neomedia.codec.*;
+import org.jitsi.impl.neomedia.codec.video.*;
+import org.jitsi.service.neomedia.codec.*;
+import org.jitsi.util.*;
+
+import javax.media.*;
+import javax.media.format.*;
+import java.awt.*;
+
+/**
+ * Implements a VP8 decoder.
+ *
+ * @author Boris Grozev
+ */
+public class VPXDecoder
+        extends AbstractCodecExt
+{
+    /**
+     * The <tt>Logger</tt> used by the <tt>VPXDecoder</tt> class
+     * for logging output.
+     */
+    private static final Logger logger
+            = Logger.getLogger(VPXDecoder.class);
+
+    /**
+     * The decoder interface to use
+     */
+    private static final int INTERFACE = VPX.INTEFACE_VP8_DEC;
+
+    /**
+     * Pointer to the libvpx codec context to be used
+     */
+    private long context = 0;
+
+    /**
+     * Whether there are unprocessed frames left from a previous call to
+     * VP8.codec_decode()
+     */
+    private boolean leftoverFrames = false;
+
+    /**
+     * Iterator for the frames in the decoder context. Can be re-initialized by
+     * setting it's only element to 0.
+     */
+    private long[] iter = new long[1];
+
+    /**
+     * Pointer to a native vpx_image structure, containing a decoded frame.
+     * When doProcess() is called, this is either 0 or it has the address of
+     * the next unprocessed image from the decoder
+     */
+    private long img = 0;
+
+    /**
+     * Pointer to a native vpx_codec_dec_cfg structure containing
+     * the decoder configuration
+     */
+    private long cfg = 0;
+
+    /**
+     * The last known height of the video output by this
+     * <tt>VPXDecoder</tt>. Used to detect changes in the output size.
+     */
+    private int width = Constants.VIDEO_WIDTH;
+
+    /**
+     * The last known width of the video output by this
+     * <tt>VPXDecoder</tt>. Used to detect changes in the output size.
+     */
+    private int height = Constants.VIDEO_HEIGHT;
+
+    /**
+     * Default output formats
+     */
+    private static final VideoFormat[] SUPPORTED_OUTPUT_FORMATS
+            = new VideoFormat[]{new AVFrameFormat(
+            new Dimension(
+                    Constants.VIDEO_WIDTH,
+                    Constants.VIDEO_HEIGHT),
+            Format.NOT_SPECIFIED,
+            FFmpeg.PIX_FMT_YUV420P,
+            Format.NOT_SPECIFIED)};
+
+    /**
+     * Initializes a new <tt>VPXDecoder</tt> instance.
+     */
+    public VPXDecoder()
+    {
+        super("VP8 VPX Decoder",
+                VideoFormat.class,
+                SUPPORTED_OUTPUT_FORMATS);
+
+        inputFormat = null;
+        outputFormat = null;
+        inputFormats = new VideoFormat[] {new VideoFormat(Constants.VP8)};
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    protected void doClose()
+    {
+        if(logger.isDebugEnabled())
+            logger.debug("Closing decoder");
+
+        if(context != 0)
+        {
+            VPX.codec_destroy(context);
+            VPX.free(context);
+        }
+        if(cfg != 0)
+            VPX.free(cfg);
+    }
+
+    /**
+     * {@inheritDoc}
+     *
+     * @throws ResourceUnavailableException if initialization failed
+     */
+    protected void doOpen() throws ResourceUnavailableException
+    {
+        context = VPX.codec_ctx_malloc();
+        //cfg = VPX.codec_dec_cfg_malloc();
+        long flags = 0; //VPX.CODEC_USE_XMA;
+
+        int ret = VPX.codec_dec_init(context, INTERFACE, 0, flags);
+        if(ret != VPX.CODEC_OK)
+            throw new RuntimeException("Failed to initialize decoder, libvpx"
+                    + " error:\n"
+                    + VPX.codec_err_to_string(ret));
+
+        if(logger.isDebugEnabled())
+            logger.debug("VP8 decoder opened succesfully");
+    }
+
+    /**
+     * {@inheritDoc}
+     *
+     * Decodes a VP8 frame contained in <tt>inputBuffer</tt> into
+     * <tt>outputBuffer</tt> (in <tt>AVFrameFormat</tt>)
+     * @param inputBuffer input <tt>Buffer</tt>
+     * @param outputBuffer output <tt>Buffer</tt>
+     * @return <tt>BUFFER_PROCESSED_OK</tt> if <tt>inBuffer</tt> has been
+     * successfully processed
+     */
+    protected int doProcess(Buffer inputBuffer, Buffer outputBuffer)
+    {
+        if(leftoverFrames)
+        {
+            /*
+             * There are more decoded frames available in the context. Fill
+             * outputBuffer with the next frame.
+             */
+            updateOutputFormat(
+                    VPX.img_get_d_w(img),
+                    VPX.img_get_d_h(img),
+                    ((VideoFormat) inputBuffer.getFormat()).getFrameRate());
+            outputBuffer.setFormat(outputFormat);
+
+
+            AVFrame avframe = makeAVFrame(img);
+            outputBuffer.setData(avframe);
+
+            //YUV420p format , 12 bits per pixel
+            outputBuffer.setLength(width * height * 3 / 2);
+            outputBuffer.setTimeStamp(Buffer.TIME_UNKNOWN);
+        }
+        else
+        {
+            /*
+             * All frames from the decoder context have been processed. Decode
+             * the next VP8 frame, and fill outputBuffer with the first decoded
+             * frame.
+             */
+
+            byte[] buf = (byte[])inputBuffer.getData();
+            int buf_offset = inputBuffer.getOffset();
+            int buf_size = inputBuffer.getLength();
+
+            int ret = VPX.codec_decode(context,
+                    buf,
+                    buf_offset,
+                    buf_size,
+                    0, 0);
+            if(ret != VPX.CODEC_OK)
+            {
+                if(logger.isDebugEnabled())
+                    logger.debug("Discarding a frame, codec_decode() error: "
+                            + VPX.codec_err_to_string(ret));
+                outputBuffer.setDiscard(true);
+                return BUFFER_PROCESSED_OK;
+            }
+
+            leftoverFrames = false;
+            iter[0] = 0;  //decode has just been called, reset iterator
+            img = VPX.codec_get_frame(context, iter);
+
+            if(img == 0)
+            {
+                outputBuffer.setDiscard(true);
+                return BUFFER_PROCESSED_OK;
+            }
+
+            updateOutputFormat(
+                    VPX.img_get_d_w(img),
+                    VPX.img_get_d_h(img),
+                    ((VideoFormat) inputBuffer.getFormat()).getFrameRate());
+            outputBuffer.setFormat(outputFormat);
+
+
+            AVFrame avframe = makeAVFrame(img);
+            outputBuffer.setData(avframe);
+
+            //YUV420p format , 12 bits per pixel
+            outputBuffer.setLength(width * height * 3 / 2);
+            outputBuffer.setTimeStamp(Buffer.TIME_UNKNOWN);
+        }
+
+
+        /*
+         * outputBuffer is all setup now. Check the decoder context for more
+         * decoded frames.
+         */
+        img = VPX.codec_get_frame(context, iter);
+        if(img == 0) //no more frames
+        {
+            leftoverFrames = false;
+            return BUFFER_PROCESSED_OK;
+        }
+        else
+        {
+            leftoverFrames = true;
+            return INPUT_BUFFER_NOT_CONSUMED;
+        }
+    }
+
+    /**
+     * Changes the output format, if necessary, according to the new dimentions
+     * given via <tt>width</tt> and <tt>height</tt>.
+     * @param width new width
+     * @param height new height
+     * @param frameRate frame rate
+     */
+    private void updateOutputFormat(int width, int height, float frameRate)
+    {
+        if ((width > 0) && (height > 0)
+                && ((this.width != width) || (this.height != height)))
+        {
+            this.width = width;
+            this.height = height;
+            outputFormat = new AVFrameFormat(
+                    new Dimension(width, height),
+                    frameRate,
+                    FFmpeg.PIX_FMT_YUV420P,
+                    Format.NOT_SPECIFIED);
+        }
+    }
+
+    /**
+     * Allocates a new AVFrame and set it's data fields to the data fields
+     * from the <tt>vpx_image_t</tt> pointed to by <tt>img</tt>. Also set it's
+     * 'linesize' according to <tt>img</tt>.
+     *
+     * @param img pointer to a <tt>vpx_image_t</tt> whose data will be used
+     *
+     * @return an AVFrame instance with it's data fields set to the fields from
+     * <tt>img</tt>
+     */
+    private AVFrame makeAVFrame(long img)
+    {
+        AVFrame avframe = new AVFrame();
+        long p0 = VPX.img_get_plane0(img);
+        long p1 = VPX.img_get_plane1(img);
+        long p2 = VPX.img_get_plane2(img);
+
+        //p0, p1, p2 are pointers, while avframe_set_data uses offsets
+        FFmpeg.avframe_set_data(avframe.getPtr(),
+                                p0,
+                                p1-p0,
+                                p2-p1);
+
+        FFmpeg.avframe_set_linesize(avframe.getPtr(),
+                VPX.img_get_stride0(img),
+                VPX.img_get_stride1(img),
+                VPX.img_get_stride2(img));
+
+        return avframe;
+    }
+
+    /**
+     * Get matching outputs for a specified input <tt>Format</tt>.
+     *
+     * @param in input <tt>Format</tt>
+     * @return array of matching outputs or null if there are no matching
+     * outputs.
+     */
+    protected Format[] getMatchingOutputFormats(Format in)
+    {
+        VideoFormat ivf = (VideoFormat) in;
+        Dimension inSize = ivf.getSize();
+        Dimension outSize;
+
+        // return the default size/currently decoder and encoder
+        // set to transmit/receive at this size
+        if (inSize == null)
+        {
+            VideoFormat ovf = SUPPORTED_OUTPUT_FORMATS[0];
+
+            if (ovf == null)
+                return null;
+            else
+                outSize = ovf.getSize();
+        }
+        else
+            outSize = inSize; // Output in same size as input.
+
+        return
+                new Format[]
+                        {
+                                new AVFrameFormat(
+                                        outSize,
+                                        ivf.getFrameRate(),
+                                        FFmpeg.PIX_FMT_YUV420P,
+                                        Format.NOT_SPECIFIED)
+                        };
+    }
+
+    /**
+     * Sets the <tt>Format</tt> of the media data to be input for processing in
+     * this <tt>Codec</tt>.
+     *
+     * @param format the <tt>Format</tt> of the media data to be input for
+     * processing in this <tt>Codec</tt>
+     * @return the <tt>Format</tt> of the media data to be input for processing
+     * in this <tt>Codec</tt> if <tt>format</tt> is compatible with this
+     * <tt>Codec</tt>; otherwise, <tt>null</tt>
+     */
+    @Override
+    public Format setInputFormat(Format format)
+    {
+        Format setFormat = super.setInputFormat(format);
+
+        if (setFormat != null)
+            reset();
+        return setFormat;
+    }
+}
\ No newline at end of file
diff --git a/src/org/jitsi/impl/neomedia/codec/video/vp8/VPXEncoder.java b/src/org/jitsi/impl/neomedia/codec/video/vp8/VPXEncoder.java
new file mode 100644
index 00000000..06001b52
--- /dev/null
+++ b/src/org/jitsi/impl/neomedia/codec/video/vp8/VPXEncoder.java
@@ -0,0 +1,459 @@
+/*
+ * Jitsi, the OpenSource Java VoIP and Instant Messaging client.
+ *
+ * Distributable under LGPL license.
+ * See terms of license at gnu.org.
+ */
+package org.jitsi.impl.neomedia.codec.video.vp8;
+
+import org.jitsi.impl.neomedia.codec.*;
+import org.jitsi.impl.neomedia.codec.video.*;
+import org.jitsi.service.neomedia.codec.*;
+import org.jitsi.util.*;
+
+import javax.media.*;
+import javax.media.format.*;
+import java.awt.*;
+
+/**
+ * Implements a VP8 encoder.
+ *
+ * @author Boris Grozev
+ */
+public class VPXEncoder
+        extends AbstractCodecExt
+{
+    /**
+     * The <tt>Logger</tt> used by the <tt>VPXEncoder</tt> class and its
+     * instances for logging output.
+     */
+    private static final Logger logger = Logger.getLogger(VPXEncoder.class);
+
+    /**
+     * VPX interface to use
+     */
+    private static final int INTERFACE = VPX.INTERFACE_VP8_ENC;
+
+    /**
+     * Pointer to the libvpx codec context to be used
+     */
+    private long context = 0;
+
+    /**
+     * Pointer to a native vpx_codec_dec_cfg structure containing
+     * encoder configuration
+     */
+    private long cfg = 0;
+
+    /**
+     * Pointer to a native vpx_image instance used to feed frames to the encoder
+     */
+    private long img = 0;
+
+    /**
+     * Pointer to a vpx_codec_cx_pkt_t
+     */
+    private long pkt = 0;
+
+    /**
+     * Iterator for the compressed frames in the encoder context. Can be
+     * re-initialized by setting it's only element to 0.
+     */
+    private long[] iter = new long[1];
+
+    /**
+     * Whether there are unprocessed packets left from a previous call to
+     * VP8.codec_encode()
+     */
+    private boolean leftoverPackets = false;
+
+    /**
+     * Default output formats
+     */
+    private static final VideoFormat[] SUPPORTED_OUTPUT_FORMATS
+            = new VideoFormat[] { new VideoFormat(Constants.VP8) };
+
+    /**
+     * The frame rate to be assumed by <tt>JNIEncoder</tt> instances in the
+     * absence of any other frame rate indication.
+     */
+    static final int DEFAULT_FRAME_RATE = 30;
+
+    /**
+     * Number of encoder frames so far. Used as pst (presentation time stamp)
+     */
+    private long frameCount = 0;
+
+    /**
+     * Current width of the input and output frames
+     */
+    private int width = Constants.VIDEO_WIDTH;
+
+    /**
+     * Current height of the input and output frames
+     */
+    private int height = Constants.VIDEO_HEIGHT;
+
+    /**
+     * Flags passed when (re-)initializing the encoder context
+     */
+    private long flags = 0;
+
+    /**
+     * Initializes a new <tt>VPXEncoder</tt> instance.
+     */
+    public VPXEncoder()
+    {
+        super("VP8 Encoder",
+                VideoFormat.class,
+                SUPPORTED_OUTPUT_FORMATS);
+        inputFormats
+                = new VideoFormat[]
+                {
+                        new YUVFormat(
+                                null,
+                                Format.NOT_SPECIFIED,
+                                Format.byteArray,
+                                DEFAULT_FRAME_RATE,
+                                YUVFormat.YUV_420,
+                                Format.NOT_SPECIFIED, Format.NOT_SPECIFIED,
+                                0, Format.NOT_SPECIFIED, Format.NOT_SPECIFIED)
+                };
+        inputFormat = null;
+        outputFormat = null;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    protected void doClose()
+    {
+        if(logger.isDebugEnabled())
+            logger.debug("Closing encoder");
+        if(context != 0)
+        {
+            VPX.codec_destroy(context);
+            VPX.free(context);
+            context = 0;
+        }
+        if(img != 0)
+        {
+            VPX.free(img);
+            img = 0;
+        }
+        if(cfg != 0)
+        {
+            VPX.free(cfg);
+            cfg = 0;
+        }
+
+
+    }
+
+    /**
+     * {@inheritDoc}
+     *
+     * @throws ResourceUnavailableException
+     */
+    protected void doOpen() throws ResourceUnavailableException
+    {
+        img = VPX.img_malloc();
+        if(img == 0)
+        {
+            throw new RuntimeException("Could not img_malloc()");
+        }
+        VPX.img_set_fmt(img, VPX.IMG_FMT_I420);
+        VPX.img_set_bps(img, 12);
+
+        cfg = VPX.codec_enc_cfg_malloc();
+        if(cfg == 0)
+        {
+            throw new RuntimeException("Could not codec_enc_cfg_malloc()");
+        }
+        VPX.codec_enc_config_default(INTERFACE, cfg, 0);
+
+        //set some settings
+        VPX.codec_enc_cfg_set_rc_target_bitrate(cfg, 192);
+        VPX.codec_enc_cfg_set_rc_resize_allowed(cfg, 1);
+        VPX.codec_enc_cfg_set_rc_end_usage(cfg, VPX.RC_MODE_CBR);
+        VPX.codec_enc_cfg_set_kf_mode(cfg, VPX.KF_MODE_AUTO);
+        VPX.codec_enc_cfg_set_w(cfg, width);
+        VPX.codec_enc_cfg_set_h(cfg, height);
+
+        context = VPX.codec_ctx_malloc();
+        int ret = VPX.codec_enc_init(context, INTERFACE, cfg, flags);
+
+        if(ret != VPX.CODEC_OK)
+            throw new RuntimeException("Failed to initialize encoder, libvpx"
+                    + " error:\n"
+                    + VPX.codec_err_to_string(ret));
+
+        if (inputFormat == null)
+            throw new ResourceUnavailableException("No input format selected");
+        if (outputFormat == null)
+            throw new ResourceUnavailableException("No output format selected");
+
+        if(logger.isDebugEnabled())
+            logger.debug("VP8 encoder opened succesfully");
+    }
+
+    /**
+     * {@inheritDoc}
+     *
+     * Encodes the frame in <tt>inputBuffer</tt> (in <tt>YUVFormat</tt>) into
+     * a VP8 frame (in <tt>outputBuffer</tt>)
+     *
+     * @param inputBuffer input <tt>Buffer</tt>
+     * @param outputBuffer output <tt>Buffer</tt>
+     *
+     * @return <tt>BUFFER_PROCESSED_OK</tt> if <tt>inBuffer</tt> has been
+     * successfully processed
+     */
+    protected int doProcess(Buffer inputBuffer, Buffer outputBuffer)
+    {
+        if(inputBuffer.isDiscard())
+        {
+            outputBuffer.setDiscard(true);
+            return BUFFER_PROCESSED_OK;
+        }
+
+        int ret = BUFFER_PROCESSED_OK;
+        byte[] output;
+        if(leftoverPackets)
+        {
+            if(VPX.codec_cx_pkt_get_kind(pkt) == VPX.CODEC_CX_FRAME_PKT)
+            {
+                int size = VPX.codec_cx_pkt_get_size(pkt);
+                output = validateByteArraySize(inputBuffer, size);
+                VPX.memcpy(output,
+                           VPX.codec_cx_pkt_get_data(pkt),
+                           size);
+                outputBuffer.setOffset(0);
+                outputBuffer.setLength(size);
+                outputBuffer.setTimeStamp(inputBuffer.getTimeStamp());
+            }
+            else
+            {
+                //not a compressed frame, skip this packet
+                ret |= OUTPUT_BUFFER_NOT_FILLED;
+            }
+        }
+        else
+        {
+            frameCount++;
+
+            YUVFormat format = (YUVFormat) inputBuffer.getFormat();
+            int width = (int) format.getSize().getWidth();
+            int height = (int) format.getSize().getHeight();
+
+            if (width > 0 && height > 0 &&
+                    (width != this.width || height != this.height))
+            {
+                if(logger.isInfoEnabled())
+                    logger.info("Setting new width/height: "+width + "/"
+                            + height);
+                this.width = width;
+                this.height = height;
+                VPX.img_set_w(img, width);
+                VPX.img_set_d_w(img, width);
+                VPX.img_set_h(img, height);
+                VPX.img_set_d_h(img, height);
+                VPX.codec_enc_cfg_set_w(cfg, width);
+                VPX.codec_enc_cfg_set_h(cfg, height);
+                reinit();
+            }
+
+            //setup img
+            int strideY = format.getStrideY();
+            if (strideY == Format.NOT_SPECIFIED)
+                strideY = width;
+            int strideUV = format.getStrideUV();
+            if (strideUV == Format.NOT_SPECIFIED)
+                strideUV = width/2;
+            VPX.img_set_stride0(img, strideY);
+            VPX.img_set_stride1(img, strideUV);
+            VPX.img_set_stride2(img, strideUV);
+            VPX.img_set_stride3(img, 0);
+
+            int offsetY = format.getOffsetY();
+            if (offsetY == Format.NOT_SPECIFIED)
+                offsetY = 0;
+            int offsetU = format.getOffsetU();
+            if (offsetU == Format.NOT_SPECIFIED)
+                offsetU = offsetY + width * height;
+            int offsetV = format.getOffsetV();
+            if (offsetV == Format.NOT_SPECIFIED)
+                offsetV = offsetU + (width * height) / 4;
+
+            int result = VPX.codec_encode(
+                    context,
+                    img,
+                    (byte[]) inputBuffer.getData(),
+                    offsetY,
+                    offsetU,
+                    offsetV,
+                    frameCount, //pts
+                    1, //duration
+                    0, //flags
+                    VPX.DL_REALTIME);
+            if(result != VPX.CODEC_OK)
+            {
+                logger.warn("Failed to encode a frame: "
+                        + VPX.codec_err_to_string(result));
+                outputBuffer.setDiscard(true);
+                return BUFFER_PROCESSED_OK;
+            }
+
+            iter[0] = 0;
+            pkt = VPX.codec_get_cx_data(context, iter);
+            if(pkt != 0 &&
+                    VPX.codec_cx_pkt_get_kind(pkt) == VPX.CODEC_CX_FRAME_PKT)
+            {
+                int size = VPX.codec_cx_pkt_get_size(pkt);
+                long data = VPX.codec_cx_pkt_get_data(pkt);
+                output = validateByteArraySize(outputBuffer, size);
+                VPX.memcpy(output, data, size);
+                outputBuffer.setOffset(0);
+                outputBuffer.setLength(size);
+                outputBuffer.setTimeStamp(inputBuffer.getTimeStamp());
+            }
+            else
+            {
+                //not a compressed frame, skip this packet
+                ret |= OUTPUT_BUFFER_NOT_FILLED;
+            }
+        }
+
+        pkt = VPX.codec_get_cx_data(context, iter);
+        leftoverPackets = pkt != 0;
+
+        if(leftoverPackets)
+            return ret | INPUT_BUFFER_NOT_CONSUMED;
+        else
+            return ret;
+
+    }
+
+    /**
+     * Reinitializes the encoder context. Needed in order to encode frames
+     * with different width or height
+     */
+    private void reinit()
+    {
+        VPX.codec_destroy(context);
+
+        int ret = VPX.codec_enc_init(context, INTERFACE, cfg, flags);
+
+        if(ret != VPX.CODEC_OK)
+            throw new RuntimeException("Failed to re-initialize encoder, libvpx"
+                    + " error:\n"
+                    + VPX.codec_err_to_string(ret));
+    }
+
+    /**
+     * Sets the input format.
+     *
+     * @param in format to set
+     * @return format
+     */
+    @Override
+    public Format setInputFormat(Format in)
+    {
+        if(!(in instanceof VideoFormat) || (matches(in, inputFormats) == null))
+            return null;
+
+        YUVFormat yuv = (YUVFormat) in;
+
+        if (yuv.getOffsetU() > yuv.getOffsetV())
+            return null;
+        Dimension size = yuv.getSize();
+
+        if (size == null)
+            size = new Dimension(Constants.VIDEO_WIDTH, Constants.VIDEO_HEIGHT);
+
+        int strideY = size.width;
+        int strideUV = strideY / 2;
+        int offsetU = strideY * size.height;
+        int offsetV = offsetU + strideUV * size.height / 2;
+
+        int yuvMaxDataLength = (strideY + strideUV) * size.height;
+
+        inputFormat
+                = new YUVFormat(
+                size,
+                yuvMaxDataLength + FFmpeg.FF_INPUT_BUFFER_PADDING_SIZE,
+                Format.byteArray,
+                yuv.getFrameRate(),
+                YUVFormat.YUV_420,
+                strideY, strideUV,
+                0, offsetU, offsetV);
+
+        // Return the selected inputFormat
+        return inputFormat;
+    }
+
+    /**
+     * Sets the <tt>Format</tt> in which this <tt>Codec</tt> is to output media
+     * data.
+     *
+     * @param out the <tt>Format</tt> in which this <tt>Codec</tt> is to
+     * output media data
+     * @return the <tt>Format</tt> in which this <tt>Codec</tt> is currently
+     * configured to output media data or <tt>null</tt> if <tt>format</tt> was
+     * found to be incompatible with this <tt>Codec</tt>
+     */
+    @Override
+    public Format setOutputFormat(Format out)
+    {
+        if(!(out instanceof VideoFormat) ||
+                (matches(out, getMatchingOutputFormats(inputFormat)) == null))
+            return null;
+
+        VideoFormat videoOut = (VideoFormat) out;
+        Dimension outSize = videoOut.getSize();
+
+        if (outSize == null)
+        {
+            Dimension inSize = ((VideoFormat) inputFormat).getSize();
+
+            outSize
+                    = (inSize == null)
+                    ? new Dimension(
+                    Constants.VIDEO_WIDTH,
+                    Constants.VIDEO_HEIGHT)
+                    : inSize;
+        }
+
+        outputFormat = new VideoFormat(
+                videoOut.getEncoding(),
+                outSize,
+                Format.NOT_SPECIFIED,
+                Format.byteArray,
+                videoOut.getFrameRate());
+
+        // Return the selected outputFormat
+        return outputFormat;
+    }
+
+    /**
+     * Gets the matching output formats for a specific format.
+     *
+     * @param in input format
+     * @return array of formats matching input format
+     */
+    protected Format[] getMatchingOutputFormats(Format in)
+    {
+        VideoFormat videoIn = (VideoFormat) in;
+
+        return
+                new VideoFormat[]
+                        {
+                                new VideoFormat(
+                                        Constants.VP8,
+                                        videoIn.getSize(),
+                                        Format.NOT_SPECIFIED,
+                                        Format.byteArray,
+                                        videoIn.getFrameRate())
+                        };
+    }
+}
-- 
GitLab