--- Jubler-3.9.6/resources/ffdecode/decodeframe.c 2008-08-10 20:15:55.000000000 +0300 +++ jubler/resources/ffdecode/decodeframe.c 2008-10-29 06:46:11.000000000 +0200 @@ -39,19 +39,23 @@ #include "defaults.h" #include "utilities.h" +#define MAXSIZE 16383 + + AVPicture *decodeFrame(JNIEnv * env, jobject this, const char *input_filename, jlong timepos, jint *width, jint *height, jfloat resize); int file_info(JNIEnv * env, jobject this, char *input_filename); +void storenumb (jbyte * data, int number); static int sws_flags = SWS_BICUBIC; -JNIEXPORT jintArray JNICALL Java_com_panayotis_jubler_media_preview_decoders_FFMPEG_grabFrame(JNIEnv * env, jobject this, jstring video, jlong time, jfloat resize) { +JNIEXPORT jbyteArray JNICALL Java_com_panayotis_jubler_media_preview_decoders_FFMPEG_grabFrame(JNIEnv * env, jobject this, jstring video, jlong time, jfloat resize) { /* Pointers for c-like strings */ const char *video_c; /* Here we'll store the frame for java */ - jintArray matrix = NULL; - jint* matrixdata = NULL; + jbyteArray matrix = NULL; + jbyte* matrixdata = NULL; /* Frame raw data */ AVPicture* pict; @@ -65,18 +69,20 @@ if (pict) { // make array - matrix = (*env)->NewIntArray(env, width*height+2); // 4 bytes per pixel (int) plus picture information + matrix = (*env)->NewByteArray(env, width*height*3+4); // 3 bytes per pixel + picture width information (2*2) if (matrix) { /* Find pointer for matrix size */ - matrixdata = (*env)->GetIntArrayElements(env, matrix, 0); + matrixdata = (*env)->GetByteArrayElements(env, matrix, 0); - /* This is a trick: the first 2 elements are not video data but the size of the video */ - matrixdata[0] = width; - matrixdata[1] = height; - memcpy(matrixdata+2, pict->data[0], 4*width*height); + /* This is a trick: the first 4 bytes are not video data but the size of the video */ + storenumb(matrixdata, width); + storenumb(matrixdata+2, height); + + /* Copy the actual color map to picture buffer */ + memcpy(matrixdata+4, pict->data[0], 3*width*height); /* Release the matrix data pointer */ - (*env)->ReleaseIntArrayElements(env, matrix, matrixdata, 0); + (*env)->ReleaseByteArrayElements(env, matrix, matrixdata, 0); } else { DEBUG(env, this, "grabFrame", "Can not create array into memory."); } @@ -206,14 +212,24 @@ av_free_packet(&pkt); } if (retflag != FALSE) { - *width = (ccx->width) * resize; - *height = (ccx->height) * resize; + /* Calculating new picture size and keep aspect ratio */ + *width = (ccx->width) * resize; + *height = (ccx->height) * resize; + if (*width > MAXSIZE ) { + *height = ( (*height) * MAXSIZE) / (*width); + *width = MAXSIZE; + } + if (*height > MAXSIZE) { + *width = ( (*width) * MAXSIZE) / (*height); + *height = MAXSIZE; + } + DEBUG(env, this, "decodeFrame", "Resampling from (%i,%i) with resize factor %f to (%i,%i)",ccx->width, ccx->height, resize,*width, *height); // Allocate an AVPicture - avpicture_alloc(pict, PIX_FMT_RGBA32, *width, *height); + avpicture_alloc(pict, PIX_FMT_RGB24, *width, *height); swsContext = sws_getCachedContext(swsContext, ccx->width, ccx->height, ccx->pix_fmt, - *width, *height, PIX_FMT_RGBA32, + *width, *height, PIX_FMT_RGB24, sws_flags, NULL, NULL, NULL); if (swsContext == NULL) { DEBUG(env, this, "decodeFrame", "swscale context initialization failed."); @@ -264,5 +280,8 @@ return 0; } - +void storenumb (jbyte * data, int number) { + data[0] = number/128; + data[1] = number % 128; +} --- Jubler-3.9.6/src/com/panayotis/jubler/media/preview/decoders/FFMPEG.java 2008-09-08 18:22:10.000000000 +0300 +++ jubler/src/com/panayotis/jubler/media/preview/decoders/FFMPEG.java 2008-10-29 06:46:03.000000000 +0200 @@ -56,23 +56,8 @@ public final class FFMPEG extends NativeDecoder { private static boolean library_is_present = false; - private static final int[] bitmasks; - private static final ColorModel cmodel; - - static { library_is_present = SystemFileFinder.loadLibrary("ffdecode"); - - int[] LE_BITMASKS = {0xff0000, 0xff00, 0xff, 0xff000000}; - int[] BE_BITMASKS = {0xff00, 0xff0000, 0xff000000, 0xff}; - - if (ByteOrder.nativeOrder() == ByteOrder.LITTLE_ENDIAN) { - bitmasks = LE_BITMASKS; - cmodel = ColorModel.getRGBdefault(); - } else { - bitmasks = BE_BITMASKS; - cmodel = new DirectColorModel(32, bitmasks[0], bitmasks[1], bitmasks[2], bitmasks[3]); - } } /** Creates a new instance of FFMPEG */ @@ -82,13 +67,16 @@ if ( vfile==null || (!isDecoderValid()) ) return null; time *= 1000000; - int[] frame = grabFrame(vfile.getPath(), (long)time, resize); - if (frame==null) return null; - - SinglePixelPackedSampleModel model = new SinglePixelPackedSampleModel(DataBuffer.TYPE_INT,frame[0], frame[1], bitmasks); - DataBufferInt buffer = new DataBufferInt(frame, frame[0]*frame[1], 2); - WritableRaster ras = Raster.createWritableRaster(model, buffer, null); - BufferedImage image = new BufferedImage(cmodel, ras, true, null); + byte[] data = grabFrame(vfile.getPath(), (long)time, resize); + if (data==null) return null; + + byte[] frame = new byte[data.length-4]; + int X = data[0] * 128 + data[1]; + int Y = data[2] * 128 + data[3]; + System.arraycopy(data, 4, frame, 0, frame.length); + BufferedImage image = new BufferedImage(X, Y, BufferedImage.TYPE_3BYTE_BGR); + WritableRaster raster = image.getRaster(); + raster.setDataElements(0, 0, X, Y, frame); return image; } @@ -152,7 +140,7 @@ } /* Get the image for this timestamp */ - private native int[] grabFrame(String video, long time, float resize); + private native byte[] grabFrame(String video, long time, float resize); /* Create a wav file from the specified time stamps */ private native boolean createClip(String audio, String wav, long from, long to);