* #27232: jni: added pjproject checkout as regular git content

We will remove it once the next release of pjsip (with Android support)
comes out and is merged into SFLphone.
diff --git a/jni/pjproject-android/pjmedia/src/test/vid_codec_test.c b/jni/pjproject-android/pjmedia/src/test/vid_codec_test.c
new file mode 100644
index 0000000..8710412
--- /dev/null
+++ b/jni/pjproject-android/pjmedia/src/test/vid_codec_test.c
@@ -0,0 +1,486 @@
+/* $Id: vid_codec_test.c 4537 2013-06-19 06:47:43Z riza $ */
+/* 
+ * Copyright (C) 2011 Teluu Inc. (http://www.teluu.com)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA 
+ */
+#include "test.h"
+#include <pjmedia-codec/ffmpeg_vid_codecs.h>
+#include <pjmedia-videodev/videodev.h>
+#include <pjmedia/vid_codec.h>
+#include <pjmedia/port.h>
+
+
+#if defined(PJMEDIA_HAS_VIDEO) && (PJMEDIA_HAS_VIDEO != 0)
+
+
+#define THIS_FILE "vid_codec.c"
+
+/* 
+ * Capture device setting: 
+ *   -1 = colorbar, 
+ *   -2 = any non-colorbar capture device (first found)
+ *    x = specified capture device id
+ */
+#define CAPTURE_DEV	    -1
+
+
+typedef struct codec_port_data_t
+{
+    pjmedia_vid_codec   *codec;
+    pjmedia_vid_port    *rdr_port;
+    pj_uint8_t          *enc_buf;
+    pj_size_t            enc_buf_size;
+    pj_uint8_t          *pack_buf;
+    pj_size_t            pack_buf_size;
+} codec_port_data_t;
+
+static pj_status_t codec_on_event(pjmedia_event *event,
+                                  void *user_data)
+{
+    codec_port_data_t *port_data = (codec_port_data_t*)user_data;
+
+    if (event->type == PJMEDIA_EVENT_FMT_CHANGED) {
+	pjmedia_vid_codec *codec = port_data->codec;
+	pjmedia_vid_codec_param codec_param;
+	pj_status_t status;
+
+	status = pjmedia_vid_codec_get_param(codec, &codec_param);
+	if (status != PJ_SUCCESS)
+	    return status;
+
+	status = pjmedia_vid_dev_stream_set_cap(
+			pjmedia_vid_port_get_stream(port_data->rdr_port),
+			PJMEDIA_VID_DEV_CAP_FORMAT,
+			&codec_param.dec_fmt);
+	if (status != PJ_SUCCESS)
+	    return status;
+    }
+
+    return PJ_SUCCESS;
+}
+
+static pj_status_t codec_put_frame(pjmedia_port *port,
+			           pjmedia_frame *frame)
+{
+    enum { MAX_PACKETS = 50 };
+    codec_port_data_t *port_data = (codec_port_data_t*)port->port_data.pdata;
+    pj_status_t status;
+    pjmedia_vid_codec *codec = port_data->codec;
+    unsigned enc_cnt = 0;
+    pj_uint8_t *enc_buf;
+    unsigned enc_size_left;
+    pjmedia_frame enc_frames[MAX_PACKETS];
+    pj_bool_t has_more = PJ_FALSE;
+
+    enc_buf = port_data->enc_buf;
+    enc_size_left = (unsigned)port_data->enc_buf_size;
+
+    /*
+     * Encode
+     */
+    enc_frames[enc_cnt].buf = enc_buf;
+    enc_frames[enc_cnt].size = enc_size_left;
+
+    status = pjmedia_vid_codec_encode_begin(codec, NULL, frame, enc_size_left,
+                                            &enc_frames[enc_cnt], &has_more);
+    if (status != PJ_SUCCESS) goto on_error;
+
+    enc_buf += enc_frames[enc_cnt].size;
+    enc_size_left -= (unsigned)enc_frames[enc_cnt].size;
+
+    ++enc_cnt;
+    while (has_more) {
+	enc_frames[enc_cnt].buf = enc_buf;
+	enc_frames[enc_cnt].size = enc_size_left;
+
+	status = pjmedia_vid_codec_encode_more(codec, enc_size_left,
+						&enc_frames[enc_cnt],
+						&has_more);
+	if (status != PJ_SUCCESS)
+	    break;
+
+	enc_buf += enc_frames[enc_cnt].size;
+	enc_size_left -= (unsigned)enc_frames[enc_cnt].size;
+
+	++enc_cnt;
+
+	if (enc_cnt >= MAX_PACKETS) {
+	    assert(!"Too many packets!");
+	    break;
+	}
+    }
+
+    /*
+     * Decode
+     */
+    status = pjmedia_vid_codec_decode(codec, enc_cnt, enc_frames,
+				      (unsigned)frame->size, frame);
+    if (status != PJ_SUCCESS) goto on_error;
+
+    /* Display */
+    status = pjmedia_port_put_frame(
+			pjmedia_vid_port_get_passive_port(port_data->rdr_port),
+			frame);
+    if (status != PJ_SUCCESS) goto on_error;
+
+    return PJ_SUCCESS;
+
+on_error:
+    pj_perror(3, THIS_FILE, status, "codec_put_frame() error");
+    return status;
+}
+
+static const char* dump_codec_info(const pjmedia_vid_codec_info *info)
+{
+    static char str[80];
+    unsigned i;
+    char *p = str;
+
+    /* Raw format ids */
+    for (i=0; (i<info->dec_fmt_id_cnt) && (p-str+5<sizeof(str)); ++i) {
+        pj_memcpy(p, &info->dec_fmt_id[i], 4);
+        p += 4;
+        *p++ = ' ';
+    }
+    *p = '\0';
+
+    return str;
+}
+
+static int enum_codecs()
+{
+    unsigned i, cnt;
+    pjmedia_vid_codec_info info[PJMEDIA_CODEC_MGR_MAX_CODECS];
+    pj_status_t status;
+
+    PJ_LOG(3, (THIS_FILE, "  codec enums"));
+    cnt = PJ_ARRAY_SIZE(info);
+    status = pjmedia_vid_codec_mgr_enum_codecs(NULL, &cnt, info, NULL);
+    if (status != PJ_SUCCESS)
+        return 100;
+
+    for (i = 0; i < cnt; ++i) {
+        PJ_LOG(3, (THIS_FILE, "  %-16.*s %c%c %s",
+                   info[i].encoding_name.slen, info[i].encoding_name.ptr,
+                   (info[i].dir & PJMEDIA_DIR_ENCODING? 'E' : ' '),
+                   (info[i].dir & PJMEDIA_DIR_DECODING? 'D' : ' '),
+                   dump_codec_info(&info[i])));
+    }
+
+    return PJ_SUCCESS;
+}
+
+static int encode_decode_test(pj_pool_t *pool, const char *codec_id,
+                              pjmedia_vid_packing packing)
+{
+    const pj_str_t port_name = {"codec", 5};
+
+    pjmedia_vid_codec *codec=NULL;
+    pjmedia_port codec_port;
+    codec_port_data_t codec_port_data;
+    pjmedia_vid_codec_param codec_param;
+    const pjmedia_vid_codec_info *codec_info;
+    const char *packing_name;
+    pjmedia_vid_dev_index cap_idx, rdr_idx;
+    pjmedia_vid_port *capture=NULL, *renderer=NULL;
+    pjmedia_vid_port_param vport_param;
+    pjmedia_video_format_detail *vfd;
+    char codec_name[5];
+    pj_status_t status;
+    int rc = 0;
+
+    switch (packing) {
+    case PJMEDIA_VID_PACKING_PACKETS:
+	packing_name = "framed";
+	break;
+    case PJMEDIA_VID_PACKING_WHOLE:
+	packing_name = "whole";
+	break;
+    default:
+	packing_name = "unknown";
+	break;
+    }
+
+    PJ_LOG(3, (THIS_FILE, "  encode decode test: codec=%s, packing=%s",
+	       codec_id, packing_name));
+
+    /* Lookup codec */
+    {
+        pj_str_t codec_id_st;
+        unsigned info_cnt = 1;
+
+        /* Lookup codec */
+        pj_cstr(&codec_id_st, codec_id);
+        status = pjmedia_vid_codec_mgr_find_codecs_by_id(NULL, &codec_id_st, 
+                                                         &info_cnt, 
+                                                         &codec_info, NULL);
+        if (status != PJ_SUCCESS) {
+            rc = 205; goto on_return;
+        }
+    }
+
+
+#if CAPTURE_DEV == -1
+    /* Lookup colorbar source */
+    status = pjmedia_vid_dev_lookup("Colorbar", "Colorbar generator", &cap_idx);
+    if (status != PJ_SUCCESS) {
+	rc = 206; goto on_return;
+    }
+#elif CAPTURE_DEV == -2
+    /* Lookup any first non-colorbar source */
+    {
+	unsigned i, cnt;
+	pjmedia_vid_dev_info info;
+
+	cap_idx = -1;
+	cnt = pjmedia_vid_dev_count();
+	for (i = 0; i < cnt; ++i) {
+	    status = pjmedia_vid_dev_get_info(i, &info);
+	    if (status != PJ_SUCCESS) {
+		rc = 206; goto on_return;
+	    }
+	    if (info.dir & PJMEDIA_DIR_CAPTURE && 
+		pj_ansi_stricmp(info.driver, "Colorbar"))
+	    {
+		cap_idx = i;
+		break;
+	    }
+	}
+
+	if (cap_idx == -1) {
+	    status = PJ_ENOTFOUND;
+	    rc = 206; goto on_return;
+	}
+    }
+#else
+    cap_idx = CAPTURE_DEV;
+#endif
+
+    /* Lookup SDL renderer */
+    status = pjmedia_vid_dev_lookup("SDL", "SDL renderer", &rdr_idx);
+    if (status != PJ_SUCCESS) {
+	rc = 207; goto on_return;
+    }
+
+    /* Prepare codec */
+    {
+        pj_str_t codec_id_st;
+        unsigned info_cnt = 1;
+        const pjmedia_vid_codec_info *codec_info;
+
+        /* Lookup codec */
+        pj_cstr(&codec_id_st, codec_id);
+        status = pjmedia_vid_codec_mgr_find_codecs_by_id(NULL, &codec_id_st, 
+                                                         &info_cnt, 
+                                                         &codec_info, NULL);
+        if (status != PJ_SUCCESS) {
+            rc = 245; goto on_return;
+        }
+        status = pjmedia_vid_codec_mgr_get_default_param(NULL, codec_info,
+                                                         &codec_param);
+        if (status != PJ_SUCCESS) {
+            rc = 246; goto on_return;
+        }
+
+        codec_param.packing = packing;
+
+        /* Open codec */
+        status = pjmedia_vid_codec_mgr_alloc_codec(NULL, codec_info,
+                                                   &codec);
+        if (status != PJ_SUCCESS) {
+	    rc = 250; goto on_return;
+        }
+
+        status = pjmedia_vid_codec_init(codec, pool);
+        if (status != PJ_SUCCESS) {
+	    rc = 251; goto on_return;
+        }
+
+        status = pjmedia_vid_codec_open(codec, &codec_param);
+        if (status != PJ_SUCCESS) {
+	    rc = 252; goto on_return;
+        }
+
+	/* After opened, codec will update the param, let's sync encoder & 
+	 * decoder format detail.
+	 */
+	codec_param.dec_fmt.det = codec_param.enc_fmt.det;
+
+	/* Subscribe to codec events */
+	pjmedia_event_subscribe(NULL, &codec_on_event, &codec_port_data,
+                                codec);
+    }
+
+    pjmedia_vid_port_param_default(&vport_param);
+
+    /* Create capture, set it to active (master) */
+    status = pjmedia_vid_dev_default_param(pool, cap_idx,
+					   &vport_param.vidparam);
+    if (status != PJ_SUCCESS) {
+	rc = 220; goto on_return;
+    }
+    pjmedia_format_copy(&vport_param.vidparam.fmt, &codec_param.dec_fmt);
+    vport_param.vidparam.dir = PJMEDIA_DIR_CAPTURE;
+    vport_param.active = PJ_TRUE;
+
+    if (vport_param.vidparam.fmt.detail_type != PJMEDIA_FORMAT_DETAIL_VIDEO) {
+	rc = 221; goto on_return;
+    }
+
+    vfd = pjmedia_format_get_video_format_detail(&vport_param.vidparam.fmt,
+						 PJ_TRUE);
+    if (vfd == NULL) {
+	rc = 225; goto on_return;
+    }
+
+    status = pjmedia_vid_port_create(pool, &vport_param, &capture);
+    if (status != PJ_SUCCESS) {
+	rc = 226; goto on_return;
+    }
+
+    /* Create renderer, set it to passive (slave)  */
+    vport_param.active = PJ_FALSE;
+    vport_param.vidparam.dir = PJMEDIA_DIR_RENDER;
+    vport_param.vidparam.rend_id = rdr_idx;
+    vport_param.vidparam.disp_size = vfd->size;
+
+    status = pjmedia_vid_port_create(pool, &vport_param, &renderer);
+    if (status != PJ_SUCCESS) {
+	rc = 230; goto on_return;
+    }
+
+    /* Init codec port */
+    pj_bzero(&codec_port, sizeof(codec_port));
+    status = pjmedia_port_info_init2(&codec_port.info, &port_name, 0x1234,
+                                     PJMEDIA_DIR_ENCODING, 
+                                     &codec_param.dec_fmt);
+    if (status != PJ_SUCCESS) {
+	rc = 260; goto on_return;
+    }
+
+    codec_port_data.codec = codec;
+    codec_port_data.rdr_port = renderer;
+    codec_port_data.enc_buf_size = codec_param.dec_fmt.det.vid.size.w *
+				   codec_param.dec_fmt.det.vid.size.h * 4;
+    codec_port_data.enc_buf = pj_pool_alloc(pool, 
+					    codec_port_data.enc_buf_size);
+    codec_port_data.pack_buf_size = codec_port_data.enc_buf_size;
+    codec_port_data.pack_buf = pj_pool_alloc(pool, 
+					     codec_port_data.pack_buf_size);
+
+    codec_port.put_frame = &codec_put_frame;
+    codec_port.port_data.pdata = &codec_port_data;
+
+    /* Connect capture to codec port */
+    status = pjmedia_vid_port_connect(capture,
+				      &codec_port,
+				      PJ_FALSE);
+    if (status != PJ_SUCCESS) {
+	rc = 270; goto on_return;
+    }
+
+    PJ_LOG(3, (THIS_FILE, "    starting codec test: %s<->%.*s %dx%d",
+	pjmedia_fourcc_name(codec_param.dec_fmt.id, codec_name),
+	codec_info->encoding_name.slen,
+	codec_info->encoding_name.ptr,
+        codec_param.dec_fmt.det.vid.size.w,
+        codec_param.dec_fmt.det.vid.size.h
+        ));
+
+    /* Start streaming.. */
+    status = pjmedia_vid_port_start(renderer);
+    if (status != PJ_SUCCESS) {
+	rc = 275; goto on_return;
+    }
+    status = pjmedia_vid_port_start(capture);
+    if (status != PJ_SUCCESS) {
+	rc = 280; goto on_return;
+    }
+
+    /* Sleep while the video is being displayed... */
+    pj_thread_sleep(10000);
+
+on_return:
+    if (status != PJ_SUCCESS) {
+        PJ_PERROR(3, (THIS_FILE, status, "  error"));
+    }
+    if (capture)
+        pjmedia_vid_port_stop(capture);
+    if (renderer)
+        pjmedia_vid_port_stop(renderer);
+    if (capture)
+	pjmedia_vid_port_destroy(capture);
+    if (renderer)
+	pjmedia_vid_port_destroy(renderer);
+    if (codec) {
+	pjmedia_event_unsubscribe(NULL, &codec_on_event, &codec_port_data,
+                                  codec);
+        pjmedia_vid_codec_close(codec);
+        pjmedia_vid_codec_mgr_dealloc_codec(NULL, codec);
+    }
+
+    return rc;
+}
+
+int vid_codec_test(void)
+{
+    pj_pool_t *pool;
+    int rc = 0;
+    pj_status_t status;
+    int orig_log_level;
+    
+    orig_log_level = pj_log_get_level();
+    pj_log_set_level(3);
+
+    PJ_LOG(3, (THIS_FILE, "Performing video codec tests.."));
+
+    pool = pj_pool_create(mem, "Vid codec test", 256, 256, 0);
+
+    status = pjmedia_vid_dev_subsys_init(mem);
+    if (status != PJ_SUCCESS)
+        return -10;
+
+#if PJMEDIA_HAS_FFMPEG_VID_CODEC
+    status = pjmedia_codec_ffmpeg_vid_init(NULL, mem);
+    if (status != PJ_SUCCESS)
+        return -20;
+#endif
+
+    rc = enum_codecs();
+    if (rc != 0)
+	goto on_return;
+
+    rc = encode_decode_test(pool, "h263-1998", PJMEDIA_VID_PACKING_WHOLE);
+    if (rc != 0)
+	goto on_return;
+
+    rc = encode_decode_test(pool, "h263-1998", PJMEDIA_VID_PACKING_PACKETS);
+    if (rc != 0)
+	goto on_return;
+
+on_return:
+#if PJMEDIA_HAS_FFMPEG_VID_CODEC
+    pjmedia_codec_ffmpeg_vid_deinit();
+#endif
+    pjmedia_vid_dev_subsys_shutdown();
+    pj_pool_release(pool);
+    pj_log_set_level(orig_log_level);
+
+    return rc;
+}
+
+
+#endif /* PJMEDIA_HAS_VIDEO */