- Add RGB/YUV intArray/shortArray as input/output support for SwScaler;

- Add updated JNI libraries;
- Add "long-time" patch to compile x264 on *BSD.
cusax-fix
Sebastien Vincent 16 years ago
parent c995f95647
commit 353c53e7a6

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

@ -10,7 +10,14 @@ make
./configure --disable-pthread --disable-avs-input --disable-asm
make
- Linux, Mac OS X, FreeBSD
- FreeBSD
Apply x264_bsd.diff patch first and compile:
patch -p1 < /path/to/x264_bsd.diff
./configure --enable-pic
gmake
- Linux, Mac OS X
./configure --enable-pic
make

@ -4,6 +4,7 @@
* Distributable under LGPL license.
* See terms of license at gnu.org.
*/
#include "net_java_sip_communicator_impl_neomedia_codec_video_FFMPEG.h"
#include <string.h>
@ -59,7 +60,6 @@ Java_net_java_sip_communicator_impl_neomedia_codec_video_FFMPEG_avcodec_1decode_
if (buf) {
jbyte *buf_ptr = (*jniEnv)->GetByteArrayElements (jniEnv, buf, NULL);
if (buf_ptr)
{
AVPacket avpkt;
@ -434,11 +434,9 @@ Java_net_java_sip_communicator_impl_neomedia_codec_video_FFMPEG_avpicture_1get_1
return (jint) avpicture_get_size ((int) pix_fmt, (int) width, (int) height);
}
static int image_convert(
AVPicture* dst, int dst_pix_fmt,
const AVPicture* src, int pix_fmt, int width, int height, jint newWidth, jint newHeight)
const AVPicture* src, int pix_fmt, int width, int height, int newWidth, int newHeight)
{
struct SwsContext *img_convert_ctx =
sws_getContext(
@ -471,44 +469,35 @@ Java_net_java_sip_communicator_impl_neomedia_codec_video_FFMPEG_img_1convert__JI
}
JNIEXPORT jint JNICALL
Java_net_java_sip_communicator_impl_neomedia_codec_video_FFMPEG_img_1convert___3BI_3BIIIII
(JNIEnv *jniEnv, jclass clazz, jbyteArray dst, jint dst_pix_fmt,
jbyteArray src, jint pix_fmt, jint width, jint height, jint newWidth, jint newHeight)
Java_net_java_sip_communicator_impl_neomedia_codec_video_FFMPEG_img_1convert__Ljava_lang_Object_2ILjava_lang_Object_2IIIII
(JNIEnv *jniEnv, jclass clazz, jobject dst, jint dst_pix_fmt,
jobject src, jint pix_fmt, jint width, jint height, jint newWidth, jint newHeight)
{
AVPicture dst_dummy;
AVPicture src_dummy;
int size = width * height;
jint ret = 0;
/*
uint8_t* dst_buf = (*jniEnv)->GetPrimitiveArrayCritical(jniEnv, dst, 0);
uint8_t* src_buf = (*jniEnv)->GetPrimitiveArrayCritical(jniEnv, src, 0);
*/
uint8_t* dst_buf = (*jniEnv)->GetByteArrayElements(jniEnv, dst, 0);
uint8_t* src_buf = (*jniEnv)->GetByteArrayElements(jniEnv, src, 0);
if(!src || !dst)
{
return -1;
}
/* assign AVPicture with buffer */
avpicture_fill(&dst_dummy, dst_buf, (int)dst_pix_fmt, newWidth, newHeight);
avpicture_fill(&src_dummy, src_buf, (int)pix_fmt, width, height);
ret = image_convert(&dst_dummy, (int)dst_pix_fmt, &src_dummy, (int)pix_fmt,
(int)width, (int)height, (int)newWidth, (int)newHeight);
/* release pointers */
/*
(*jniEnv)->ReleasePrimitiveArrayCritical(jniEnv, dst, dst_buf, 0);
(*jniEnv)->ReleasePrimitiveArrayCritical(jniEnv, src, src_buf, 0);
*/
(*jniEnv)->ReleaseByteArrayElements(jniEnv, dst, dst_buf, 0);
(*jniEnv)->ReleaseByteArrayElements(jniEnv, src, src_buf, 0);
return ret;
uint8_t* src_buf = (*jniEnv)->GetPrimitiveArrayCritical(jniEnv, (jarray)src, 0);
uint8_t* dst_buf = (*jniEnv)->GetPrimitiveArrayCritical(jniEnv, (jarray)dst, 0);
AVPicture dst_dummy;
AVPicture src_dummy;
int size = width * height;
jint ret = 0;
if(!src_buf || !dst_buf)
{
return -1;
}
/* assign AVPicture with buffer */
avpicture_fill(&dst_dummy, dst_buf, (int)dst_pix_fmt, newWidth, newHeight);
avpicture_fill(&src_dummy, src_buf, (int)pix_fmt, width, height);
ret = image_convert(&dst_dummy, (int)dst_pix_fmt, &src_dummy, (int)pix_fmt,
(int)width, (int)height, (int)newWidth, (int)newHeight);
/* release pointers */
(*jniEnv)->ReleasePrimitiveArrayCritical(jniEnv, dst, dst_buf, 0);
(*jniEnv)->ReleasePrimitiveArrayCritical(jniEnv, src, src_buf, 0);
return ret;
}
JNIEXPORT void JNICALL
Java_net_java_sip_communicator_impl_neomedia_codec_video_FFMPEG_memcpy___3IIIJ (
JNIEnv *jniEnv, jclass clazz, jintArray dst, jint dst_offset,
@ -526,10 +515,20 @@ Java_net_java_sip_communicator_impl_neomedia_codec_video_FFMPEG_memcpy__J_3BII (
}
JNIEXPORT jint JNICALL
Java_net_java_sip_communicator_impl_neomedia_codec_video_FFMPEG_getRGB32Format
(JNIEnv *env, jclass clazz)
Java_net_java_sip_communicator_impl_neomedia_codec_video_FFMPEG_getRGB24Format
(JNIEnv *jniEnv, jclass clazz)
{
return PIX_FMT_RGB32;
uint32_t test = 1;
int little_endian = *((uint8_t*)&test);
if(little_endian)
{
return PIX_FMT_RGB24;
}
else /* big endian */
{
return PIX_FMT_BGR24;
}
}
JNIEXPORT jint JNICALL

@ -23,18 +23,18 @@ extern "C" {
#define net_java_sip_communicator_impl_neomedia_codec_video_FFMPEG_X264_RC_ABR 2L
/*
* Class: net_java_sip_communicator_impl_neomedia_codec_video_FFMPEG
* Method: getRGB32Format
* Method: getRGBAFormat
* Signature: ()I
*/
JNIEXPORT jint JNICALL Java_net_java_sip_communicator_impl_neomedia_codec_video_FFMPEG_getRGB32Format
JNIEXPORT jint JNICALL Java_net_java_sip_communicator_impl_neomedia_codec_video_FFMPEG_getRGBAFormat
(JNIEnv *, jclass);
/*
* Class: net_java_sip_communicator_impl_neomedia_codec_video_FFMPEG
* Method: getRGBAFormat
* Method: getRGB24Format
* Signature: ()I
*/
JNIEXPORT jint JNICALL Java_net_java_sip_communicator_impl_neomedia_codec_video_FFMPEG_getRGBAFormat
JNIEXPORT jint JNICALL Java_net_java_sip_communicator_impl_neomedia_codec_video_FFMPEG_getRGB24Format
(JNIEnv *, jclass);
/*
@ -472,10 +472,10 @@ JNIEXPORT jint JNICALL Java_net_java_sip_communicator_impl_neomedia_codec_video_
/*
* Class: net_java_sip_communicator_impl_neomedia_codec_video_FFMPEG
* Method: img_convert
* Signature: ([BI[BIIIII)I
* Signature: (Ljava/lang/Object;ILjava/lang/Object;IIIII)I
*/
JNIEXPORT jint JNICALL Java_net_java_sip_communicator_impl_neomedia_codec_video_FFMPEG_img_1convert___3BI_3BIIIII
(JNIEnv *, jclass, jbyteArray, jint, jbyteArray, jint, jint, jint, jint, jint);
JNIEXPORT jint JNICALL Java_net_java_sip_communicator_impl_neomedia_codec_video_FFMPEG_img_1convert__Ljava_lang_Object_2ILjava_lang_Object_2IIIII
(JNIEnv *, jclass, jobject, jint, jobject, jint, jint, jint, jint, jint);
/*
* Class: net_java_sip_communicator_impl_neomedia_codec_video_FFMPEG

@ -0,0 +1,270 @@
diff -Nru a/version.sh b/version.sh
--- a/version.sh 2009-12-08 22:45:08.000000000 +0100
+++ b/version.sh 2010-01-19 19:10:23.000000000 +0100
@@ -1,4 +1,4 @@
-#!/bin/bash
+#!/usr/local/bin/bash
git rev-list HEAD | sort > config.git-hash
LOCALVER=`wc -l config.git-hash | awk '{print $1}'`
if [ $LOCALVER \> 1 ] ; then
diff -Nru a/Makefile b/Makefile
--- a/Makefile 2009-12-08 22:45:08.000000000 +0100
+++ b/Makefile 2010-01-19 19:10:40.000000000 +0100
@@ -10,7 +10,8 @@
common/quant.c common/vlc.c \
encoder/analyse.c encoder/me.c encoder/ratecontrol.c \
encoder/set.c encoder/macroblock.c encoder/cabac.c \
- encoder/cavlc.c encoder/encoder.c encoder/lookahead.c
+ encoder/cavlc.c encoder/encoder.c encoder/lookahead.c \
+ bsdlogf.c
SRCCLI = x264.c input/yuv.c input/y4m.c output/raw.c \
output/matroska.c output/matroska_ebml.c \
diff -Nru a/bsdlog.h b/bsdlog.h
--- a/bsdlog.h 1970-01-01 01:00:00.000000000 +0100
+++ b/bsdlog.h 2010-01-19 19:08:07.000000000 +0100
@@ -0,0 +1,143 @@
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunSoft, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+
+#ifndef bsdlog_headerfile
+#define bsdlog_headerfile
+
+#include <math.h>
+#include <sys/types.h>
+
+
+float log2f(float);
+
+
+
+
+#if (__BYTE_ORDER == __LITTLE_ENDIAN) && !defined(__arm__)
+
+typedef union
+{
+double value;
+struct
+{
+u_int32_t lsw;
+u_int32_t msw;
+} parts;
+} ieee_double_shape_type;
+
+#endif
+
+
+
+
+#if (__BYTE_ORDER == __BIG_ENDIAN) || defined(__arm__)
+
+/* this should be on a BIG ENDIAN platform instead of the previous code */
+/* I commented this because my compiler have a mess with macros *_ENDIAN */
+
+/*
+typedef union
+{
+double value;
+struct
+{
+u_int32_t msw;
+u_int32_t lsw;
+} parts;
+} ieee_double_shape_type;
+*/
+
+#endif
+
+
+
+
+
+#define EXTRACT_WORDS(ix0,ix1,d) \
+do { \
+ieee_double_shape_type ew_u; \
+ew_u.value = (d); \
+(ix0) = ew_u.parts.msw; \
+(ix1) = ew_u.parts.lsw; \
+} while (0)
+/* Get the more significant 32 bit int from a double. */
+
+#define GET_HIGH_WORD(i,d) \
+do { \
+ieee_double_shape_type gh_u; \
+gh_u.value = (d); \
+(i) = gh_u.parts.msw; \
+} while (0)
+
+/* Get the less significant 32 bit int from a double. */
+
+#define GET_LOW_WORD(i,d) \
+do { \
+ieee_double_shape_type gl_u; \
+gl_u.value = (d); \
+(i) = gl_u.parts.lsw; \
+} while (0)
+
+/* Set a double from two 32 bit ints. */
+
+
+/* Set the more significant 32 bits of a double from an int. */
+
+#define SET_HIGH_WORD(d,v) \
+do { \
+ieee_double_shape_type sh_u; \
+sh_u.value = (d); \
+sh_u.parts.msw = (v); \
+(d) = sh_u.value; \
+} while (0)
+
+/* Set the less significant 32 bits of a double from an int. */
+
+#define SET_LOW_WORD(d,v) \
+do { \
+ieee_double_shape_type sl_u; \
+sl_u.value = (d); \
+sl_u.parts.lsw = (v); \
+(d) = sl_u.value; \
+} while (0)
+
+
+
+/* A union which permits us to convert between a float and a 32 bit
+int. */
+
+typedef union
+{
+float value;
+u_int32_t word;
+} ieee_float_shape_type;
+
+/* Get a 32 bit int from a float. */
+
+#define GET_FLOAT_WORD(i,d) \
+do { \
+ieee_float_shape_type gf_u; \
+gf_u.value = (d); \
+(i) = gf_u.word; \
+} while (0)
+
+/* Set a float from a 32 bit int. */
+
+#define SET_FLOAT_WORD(d,i) \
+do { \
+ieee_float_shape_type sf_u; \
+sf_u.word = (i); \
+(d) = sf_u.value; \
+} while (0)
+
+
+
+#endif
diff -Nru a/bsdlogf.c b/bsdlogf.c
--- a/bsdlogf.c 1970-01-01 01:00:00.000000000 +0100
+++ b/bsdlogf.c 2010-01-19 19:08:07.000000000 +0100
@@ -0,0 +1,77 @@
+/*
+ * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@xxxxxxxxxxx
+ */
+
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+
+#include "bsdlog.h"
+
+
+static const float
+ln2 = 0.6931471805599452862268,
+two25 = 3.355443200e+07, /* 0x4c000000 */
+Lg1 = 6.6666668653e-01, /* 3F2AAAAB */
+Lg2 = 4.0000000596e-01, /* 3ECCCCCD */
+Lg3 = 2.8571429849e-01, /* 3E924925 */
+Lg4 = 2.2222198546e-01, /* 3E638E29 */
+Lg5 = 1.8183572590e-01, /* 3E3A3325 */
+Lg6 = 1.5313838422e-01, /* 3E1CD04F */
+Lg7 = 1.4798198640e-01; /* 3E178897 */
+
+static const float zero = 0.0;
+
+
+
+float log2f(float x)
+{
+ float hfsq,f,s,z,R,w,t1,t2,dk;
+ int32_t k,ix,i,j;
+
+ GET_FLOAT_WORD(ix,x);
+
+ k=0;
+ if (ix < 0x00800000) { /* x < 2**-126 */
+ if ((ix&0x7fffffff)==0)
+ return -two25/zero; /* log(+-0)=-inf */
+ if (ix<0) return (x-x)/zero; /* log(-#) = NaN */
+ k -= 25; x *= two25; /* subnormal number, scale up x */
+ GET_FLOAT_WORD(ix,x);
+ }
+ if (ix >= 0x7f800000) return x+x;
+ k += (ix>>23)-127;
+ ix &= 0x007fffff;
+ i = (ix+(0x95f64<<3))&0x800000;
+ SET_FLOAT_WORD(x,ix|(i^0x3f800000)); /* normalize x or x/2 */
+ k += (i>>23);
+ dk = (float)k;
+ f = x-(float)1.0;
+ if((0x007fffff&(15+ix))<16) { /* |f| < 2**-20 */
+ if (f==zero)
+ return (dk);
+ R = f*f*((float)0.5-(float)0.33333333333333333*f);
+ return (dk-(R-f)/ln2);
+ }
+ s = f/((float)2.0+f);
+ z = s*s;
+ i = ix-(0x6147a<<3);
+ w = z*z;
+ j = (0x6b851<<3)-ix;
+ t1= w*(Lg2+w*(Lg4+w*Lg6));
+ t2= z*(Lg1+w*(Lg3+w*(Lg5+w*Lg7)));
+ i |= j;
+ R = t2+t1;
+ if(i>0) {
+ hfsq=(float)0.5*f*f;
+ return (dk-(hfsq-s*(hfsq+R)-f)/ln2);
+ } else
+ return (dk-((s*(f-R))-f)/ln2);
+}
diff -Nru a/configure b/configure
--- a/configure 2009-12-08 22:45:08.000000000 +0100
+++ b/configure 2010-01-19 19:10:14.000000000 +0100
@@ -1,4 +1,4 @@
-#!/bin/bash
+#!/usr/local/bin/bash
if test x"$1" = x"-h" -o x"$1" = x"--help" ; then
diff -Nru a/encoder/analyse.c b/encoder/analyse.c
--- a/encoder/analyse.c 2009-12-08 22:45:08.000000000 +0100
+++ b/encoder/analyse.c 2010-01-19 19:08:07.000000000 +0100
@@ -33,6 +33,7 @@
#include "ratecontrol.h"
#include "analyse.h"
#include "rdo.c"
+#include "../bsdlog.h"
typedef struct
{

@ -76,8 +76,6 @@ static int windows_grab_screen(jbyte* data, int32_t x, int32_t y, int32_t w, int
RGBQUAD *pixels = NULL;
size_t i = 0;
size_t off = 0;
uint32_t test = 1;
int little_endian = *((uint8_t*)&test);
/* get handle to the entire screen of Windows */
desktop = GetDC(NULL);
@ -194,16 +192,8 @@ static int windows_grab_screen(jbyte* data, int32_t x, int32_t y, int32_t w, int
{
RGBQUAD* quad = &pixels[i];
uint32_t pixel = 0xFF000000 | quad->rgbRed << 16 | quad->rgbGreen << 8 | quad->rgbBlue;
if(little_endian)
{
uint8_t r = (pixel >> 16) & 0xff;
uint8_t g = (pixel >> 8) & 0xff;
uint8_t b = pixel & 0xff;
pixel = 0xff << 24 | b << 16 | g << 8 | r;
}
/* Java int is always big endian so output as ARGB */
memcpy(data + off, &pixel, 4);
off += 4;
}
@ -239,8 +229,6 @@ static int quartz_grab_screen(jbyte* data, int32_t x, int32_t y, int32_t w, int3
size_t off = 0;
size_t i = 0;
CGRect rect;
uint32_t test_endian = 1;
int little_endian = *((uint8_t*)&test_endian);
rect = CGRectMake(x, y, w, h);
img = CGWindowListCreateImage(rect, kCGWindowListOptionOnScreenOnly, kCGNullWindowID, kCGWindowImageDefault);
@ -261,16 +249,12 @@ static int quartz_grab_screen(jbyte* data, int32_t x, int32_t y, int32_t w, int3
for(i = 0 ; i < len ; i+=4)
{
uint32_t pixel = *((uint32_t*)&pixels[i]);
uint8_t r = (pixel >> 16) & 0xff;
uint8_t g = (pixel >> 8) & 0xff;
uint8_t b = pixel & 0xff;
if(little_endian)
{
uint8_t r = (pixel >> 16) & 0xff;
uint8_t g = (pixel >> 8) & 0xff;
uint8_t b = pixel & 0xff;
pixel = 0xff << 24 | b << 16 | g << 8 | r;
}
/* Java int is always big endian so output as ARGB */
pixel = 0xff << 24 | r << 16 | g << 8 | b;
memcpy(data + off, &pixel, 4);
off += 4;
}
@ -310,8 +294,6 @@ static int x11_grab_screen(const char* x11display, jbyte* data, int32_t x, int32
int i = 0;
int j = 0;
size_t size = 0;
uint32_t test_endian = 1;
int little_endian = *((uint8_t*)&test_endian);
display_str = x11display ? x11display : getenv("DISPLAY");
@ -418,20 +400,16 @@ static int x11_grab_screen(const char* x11display, jbyte* data, int32_t x, int32
{
for(i = 0 ; i < w ; i++)
{
/* do not care about hight 32-bit for Linux 64 bit
/* do not care about high 32-bit for Linux 64 bit
* machine (sizeof(unsigned long) = 8)
*/
uint32_t pixel = (uint32_t)XGetPixel(img, i, j);
uint8_t r = (pixel >> 16) & 0xff;
uint8_t g = (pixel >> 8) & 0xff;
uint8_t b = pixel & 0xff;
if(little_endian)
{
uint8_t r = (pixel >> 16) & 0xff;
uint8_t g = (pixel >> 8) & 0xff;
uint8_t b = pixel & 0xff;
pixel = 0xff << 24 | b << 16 | g << 8 | r;
}
/* Java int is always big endian so output as ARGB */
pixel = 0xff << 24 | r << 16 | g << 8 | b;
memcpy(data + off, &pixel, 4);
off += 4;
}

@ -331,6 +331,7 @@ public void registerCustomCodecs()
/* remove JavaRGBToYUV */
PlugInManager.removePlugIn("com.sun.media.codec.video.colorspace.JavaRGBToYUV", PlugInManager.CODEC);
PlugInManager.removePlugIn("com.sun.media.codec.video.colorspace.JavaRGBConverter", PlugInManager.CODEC);
for (String className : CUSTOM_CODECS)
{

@ -23,18 +23,18 @@ public class FFMPEG
public static final int FF_MB_DECISION_SIMPLE = 0;
public static final int PIX_FMT_RGB32;
public static final int PIX_FMT_RGBA;
public static final int PIX_FMT_RGB24;
public static final int PIX_FMT_YUV420P;
public static final int X264_RC_ABR = 2;
public static native int getRGB32Format();
public static native int getRGBAFormat();
public static native int getRGB24Format();
public static native int getYUV420PFormat();
public static native void av_free(long ptr);
@ -177,10 +177,22 @@ public static native int avpicture_get_size(int pix_fmt, int width,
public static native int img_convert(long dst, int dst_pix_fmt, long src,
int pix_fmt, int width, int height);
public static native int img_convert(byte dst[], int dst_pix_fmt,
byte src[], int pix_fmt, int width, int height, int newWidth,
/**
* Convert image bytes (scale/format).
*
* @param dst destination image. Its type must be an array (int[], byte[]
* or short[])
* @param dst_pix_fmt destination format
* @param src source image. Its type must be an array (int[], byte[] or short[])
* @param width original width
* @param height original height
* @param newWidth new width
* @param newHeight new height
*/
public static native int img_convert(Object dst, int dst_pix_fmt,
Object src, int pix_fmt, int width, int height, int newWidth,
int newHeight);
public static native void memcpy(int[] dst, int dst_offset, int dst_length,
long src);
@ -193,8 +205,8 @@ public static native void memcpy(long dst, byte[] src, int src_offset,
av_register_all();
avcodec_init();
PIX_FMT_RGB32 = getRGB32Format(); /* for decoding */
PIX_FMT_RGBA = getRGBAFormat(); /* for encoding */
PIX_FMT_RGB24 = getRGB24Format();
PIX_FMT_RGBA = getRGBAFormat();
PIX_FMT_YUV420P = getYUV420PFormat();
}
}

@ -28,14 +28,36 @@ public class SwScaler
* Supported input formats.
*/
private final Format[] supportedInputFormats = new Format[] {
new RGBFormat(null, -1, Format.byteArray, -1.0f, 32, -1, -1, -1)
new RGBFormat(null, -1, Format.byteArray, -1.0f, 32, -1, -1, -1),
new RGBFormat(null, -1, Format.intArray, -1.0f, 32, -1, -1, -1),
new RGBFormat(null, -1, Format.shortArray, -1.0f, 32, -1, -1, -1),
new RGBFormat(null, -1, Format.byteArray, -1.0f, 24, -1, -1, -1),
new RGBFormat(null, -1, Format.intArray, -1.0f, 24, -1, -1, -1),
new RGBFormat(null, -1, Format.shortArray, -1.0f, 24, -1, -1, -1),
new YUVFormat(null, -1, Format.byteArray, -1.0f, YUVFormat.YUV_420,
-1, -1, 0, -1, -1),
new YUVFormat(null, -1, Format.intArray, -1.0f, YUVFormat.YUV_420,
-1, -1, 0, -1, -1),
new YUVFormat(null, -1, Format.shortArray, -1.0f, YUVFormat.YUV_420,
-1, -1, 0, -1, -1),
};
/**
* Supported output formats.
*/
private Format[] supportedOutputFormats = new Format[] {
new YUVFormat(null, -1, Format.byteArray, -1.0f, YUVFormat.YUV_420, -1, -1, 0, -1, -1)
new YUVFormat(null, -1, Format.byteArray, -1.0f, YUVFormat.YUV_420,
-1, -1, 0, -1, -1),
new YUVFormat(null, -1, Format.intArray, -1.0f, YUVFormat.YUV_420,
-1, -1, 0, -1, -1),
new YUVFormat(null, -1, Format.shortArray, -1.0f, YUVFormat.YUV_420,
-1, -1, 0, -1, -1),
new RGBFormat(null, -1, Format.byteArray, -1.0f, 32, -1, -1, -1),
new RGBFormat(null, -1, Format.intArray, -1.0f, 32, -1, -1, -1),
new RGBFormat(null, -1, Format.shortArray, -1.0f, 32, -1, -1, -1),
new RGBFormat(null, -1, Format.byteArray, -1.0f, 24, -1, -1, -1),
new RGBFormat(null, -1, Format.intArray, -1.0f, 24, -1, -1, -1),
new RGBFormat(null, -1, Format.shortArray, -1.0f, 24, -1, -1, -1),
};
/**
@ -50,8 +72,24 @@ public void setOutputSize(Dimension size)
size = new Dimension(640, 480);
}
Format newFormat = new YUVFormat(size, -1, Format.byteArray, -1.0f, YUVFormat.YUV_420, -1, -1, 0, -1, -1);
supportedOutputFormats[0] = newFormat;
supportedOutputFormats[0] = new YUVFormat(size, -1, Format.byteArray,
-1.0f, YUVFormat.YUV_420, -1, -1, 0, -1, -1);
supportedOutputFormats[1] = new YUVFormat(size, -1, Format.intArray,
-1.0f, YUVFormat.YUV_420, -1, -1, 0, -1, -1);
supportedOutputFormats[2] = new YUVFormat(size, -1, Format.shortArray,
-1.0f, YUVFormat.YUV_420, -1, -1, 0, -1, -1);
supportedOutputFormats[3] = new RGBFormat(size, -1, Format.byteArray,
-1.0f, 32, -1, -1, -1);
supportedOutputFormats[4] = new RGBFormat(size, -1, Format.intArray,
-1.0f, 32, -1, -1, -1);
supportedOutputFormats[5] = new RGBFormat(size, -1, Format.shortArray,
-1.0f, 32, -1, -1, -1);
supportedOutputFormats[6] = new RGBFormat(size, -1, Format.byteArray,
-1.0f, 24, -1, -1, -1);
supportedOutputFormats[7] = new RGBFormat(size, -1, Format.intArray,
-1.0f, 24, -1, -1, -1);
supportedOutputFormats[8] = new RGBFormat(size, -1, Format.shortArray,
-1.0f, 24, -1, -1, -1);
}
/**
@ -74,18 +112,49 @@ public Format[] getSupportedInputFormats()
@Override
public Format[] getSupportedOutputFormats(Format input)
{
Dimension size = null;
if(input == null)
{
return supportedOutputFormats;
}
/* if size is set for element 0 (YUVFormat), it is also set
* for element 1 (RGBFormat) and so on...
*/
size = ((VideoFormat)supportedOutputFormats[0]).getSize();
//System.out.println("input: " + ((VideoFormat)input).getSize());
if(((VideoFormat)supportedOutputFormats[0]).getSize() != null)
if(size != null)
{
return supportedOutputFormats;
}
return new Format[] { new YUVFormat(((VideoFormat)input).getSize(), -1, Format.byteArray, -1.0f, YUVFormat.YUV_420, -1, -1, 0, -1, -1)};
/* no specified size set so return the same size as input
* in output format supported
*/
size = ((VideoFormat)input).getSize();
return new Format[] {
new YUVFormat(size, -1, Format.byteArray, -1.0f,
YUVFormat.YUV_420, -1, -1, 0, -1, -1),
new YUVFormat(size, -1, Format.intArray, -1.0f,
YUVFormat.YUV_420, -1, -1, 0, -1, -1),
new YUVFormat(size, -1, Format.shortArray, -1.0f,
YUVFormat.YUV_420, -1, -1, 0, -1, -1),
new RGBFormat(size, -1, Format.byteArray, -1.0f,
32, -1, -1, -1),
new RGBFormat(size, -1, Format.intArray, -1.0f,
32, -1, -1, -1),
new RGBFormat(size, -1, Format.shortArray, -1.0f,
32, -1, -1, -1),
new RGBFormat(size, -1, Format.byteArray, -1.0f,
24, -1, -1, -1),
new RGBFormat(size, -1, Format.intArray, -1.0f,
24, -1, -1, -1),
new RGBFormat(size, -1, Format.shortArray, -1.0f,
24, -1, -1, -1),
};
}
/**
@ -135,14 +204,27 @@ public int process(Buffer input, Buffer output)
VideoFormat voutput = (VideoFormat)output.getFormat();
int inputWidth = (int)vinput.getSize().getWidth();
int inputHeight = (int)vinput.getSize().getHeight();
int outputWidth = (int)voutput.getSize().getWidth();
int outputHeight = (int)voutput.getSize().getHeight();
byte src[] = (byte[])input.getData();
byte dst[] = (byte[])output.getData();
/* input's data type can be byte[], int[] or short[]
* so we used Object type to store it
*/
Object src = input.getData();
Object dst = output.getData();
int outputSize = 0;
int outputWidth = 0;
int outputHeight = 0;
int infmt = 0;
int outfmt = 0;
/* first buffer has no output format set */
if(voutput == null)
{
voutput = (VideoFormat)outputFormat;
return BUFFER_PROCESSED_FAILED;
}
outputWidth = (int)voutput.getSize().getWidth();
outputHeight = (int)voutput.getSize().getHeight();
if (!checkInputBuffer(input))
{
return BUFFER_PROCESSED_FAILED;
@ -164,7 +246,14 @@ public int process(Buffer input, Buffer output)
else /* RGB format */
{
outputSize = (outputWidth * outputHeight * 4);
outfmt = FFMPEG.PIX_FMT_RGBA;
if(((RGBFormat)voutput).getBitsPerPixel() == 32)
{
outfmt = FFMPEG.PIX_FMT_RGBA;
}
else
{
outfmt = FFMPEG.PIX_FMT_RGB24;
}
}
/* determine input format */
@ -174,20 +263,59 @@ public int process(Buffer input, Buffer output)
}
else /* RGBFormat */
{
infmt = FFMPEG.PIX_FMT_RGBA;
if(((RGBFormat)vinput).getBitsPerPixel() == 32)
{
infmt = FFMPEG.PIX_FMT_RGBA;
}
else
{
infmt = FFMPEG.PIX_FMT_RGB24;
}
}
if(voutput.getDataType() == Format.byteArray)
{
if(dst == null || ((byte[])dst).length < outputSize)
{
dst = new byte[outputSize];
}
}
else if(voutput.getDataType() == Format.intArray)
{
/* Java int is always 4 bytes */
outputSize = (outputSize % 4) + outputSize / 4;
if(dst == null || ((int[])dst).length < outputSize)
{
dst = new int[outputSize];
}
}
else if(voutput.getDataType() == Format.shortArray)
{
/* Java short is always 2 bytes */
outputSize = (outputSize % 2) + outputSize / 2;
if(dst == null || ((short[])dst).length < outputSize)
{
dst = new short[outputSize];
}
}
else
{
System.out.println("Unknown data type!");
return BUFFER_PROCESSED_FAILED;
}
if(dst == null || dst.length < outputSize)
synchronized(src)
{
dst = new byte[outputSize];
/* conversion! */
FFMPEG.img_convert(dst, outfmt, src, infmt, inputWidth, inputHeight,
outputWidth, outputHeight);
}
/* conversion! */
//System.out.println("Convert: " + inputWidth + "x" + inputHeight + " to " + outputWidth + "x" + outputHeight);
FFMPEG.img_convert(dst, outfmt, src, infmt, inputWidth, inputHeight, outputWidth, outputHeight);
//System.out.println("Converted: " + inputWidth + "x" + inputHeight +
//" to " + outputWidth + "x" + outputHeight);
output.setData(dst);
output.setLength(dst.length);
output.setLength(outputSize);
output.setOffset(0);
return BUFFER_PROCESSED_OK;

@ -267,15 +267,15 @@ else if (!parser.pushRTPInput(inputBuffer))
// convert the picture in RGB Format
int numBytes =
FFMPEG.avpicture_get_size(FFMPEG.PIX_FMT_RGB32, avctxWidth,
FFMPEG.avpicture_get_size(FFMPEG.PIX_FMT_RGBA, avctxWidth,
avctxHeight);
long buffer = FFMPEG.av_malloc(numBytes);
FFMPEG.avpicture_fill(frameRGB, buffer, FFMPEG.PIX_FMT_RGB32,
FFMPEG.avpicture_fill(frameRGB, buffer, FFMPEG.PIX_FMT_RGBA,
avctxWidth, avctxHeight);
// Convert the image from its native format to RGB
FFMPEG.img_convert(frameRGB, FFMPEG.PIX_FMT_RGB32, avframe, FFMPEG
FFMPEG.img_convert(frameRGB, FFMPEG.PIX_FMT_RGBA, avframe, FFMPEG
.avcodeccontext_get_pix_fmt(avcontext), avctxWidth, avctxHeight);
Object outData = outputBuffer.getData();

Loading…
Cancel
Save