Fixes submitted by Lieven de Cock:
[Fobs.git] / jmf / stand_alone_codec.cpp.orig
blobef80f21d2bbbf5221d693e09bbcb99291059ecc4
1 /******************************************************************************
2 * FOBS Java JMF Native PlugIn 
3 * This file contain the native implementation of the stand-alone codec that
4 * allows to use all the JMF internals along with ffmpeg. This file is included
5 * as of version 0.3 to provide support for custom DataSources. Some issues has
6 * been detected using this classes. See documentation for further details.
8 * Copyright (c) 2004 Omnividea Multimedia S.L
9 * Coded by JosĀŽ San Pedro Wandelmer
11 *    This file is part of FOBS.
13 *    FOBS is free software; you can redistribute it and/or modify
14 *    it under the terms of the GNU Lesser General Public License as
15 *    published by the Free Software Foundation; either version 2.1 
16 *    of the License, or (at your option) any later version.
18 *    FOBS is distributed in the hope that it will be useful,
19 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
20 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
21 *    GNU Lesser General Public License for more details.
23 *    You should have received a copy of the GNU Lesser General Public
24 *    License along with FOBS; if not, write to the Free Software
25 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
26 ******************************************************************************/
28 extern "C"
30 #include <stdio.h>
31 #include <stdlib.h>
32 #include <string.h>
33 //#include <libavformat/avformat.h>
34 #include "avformat.h"
35 //#include <libavcodec/avcodec.h>
36 #include "avcodec.h"
37 #define MKTAG(a,b,c,d) (a | (b << 8) | (c << 16) | (d << 24))
38 #include "avi.h"
40 #define __TAGS
41 #include "_tags.h"
42 #undef __TAGS
45 #include <jni.h>
47 #include "com_omnividea_media_codec_video_JavaDecoder.h"
48 #include "com_omnividea_media_codec_audio_JavaDecoder.h"
49 jboolean convertAudio
50   (JNIEnv *env, jobject obj, jint peer,
51    jobject jinBuffer, jlong inBytes, jint inOffset,
52    jobject joutBuffer, jlong outBytes, jlong size, jdouble dts);
55  * Wrapper structure that holds relevant data per codec instance.
56  */
57 typedef struct {
58         AVCodec *codec;
59     //AVCodecParserContext *parser_context;
60         AVCodecContext *codec_context;
61         //AVFrame *picture;
62     AVPicture picture;
63     AVPicture rgbPicture;
64     uint8_t *rgbBuf;
66     uint8_t *frameBuf;
67     int frameBufSize;
68     
69     int width;
70     int height;
72         /* temporary buffer used for encoding h263/rtp ONLY (i.e. not
73          * for encoding plain old h263). NULL during decode */
74         void *encode_buf;
75         int encode_buf_size;
76     
77     //Audio
78     int lastAudioSize;
79 } FFMPEGWrapper;
83 CodecID getCodecId(char *t)
85     CodecID id = CODEC_ID_NONE;
86     int iTag = MKTAG(t[0], t[1], t[2], t[3]);
88     id = codec_get_id(codec_bmp_tags, iTag);
89     if(id != CODEC_ID_NONE) return id;    
90     id = codec_get_id(mov_video_tags, iTag);
91     if(id != CODEC_ID_NONE) return id;    
92     id = codec_get_id(nsv_codec_video_tags, iTag);
93     if(id != CODEC_ID_NONE) return id;    
94     
95     id = codec_get_id(codec_wav_tags, iTag);
96     if(id != CODEC_ID_NONE) return id;    
97     id = codec_get_id(mov_audio_tags, iTag);
98     if(id != CODEC_ID_NONE) return id;    
99     id = codec_get_id(nsv_codec_audio_tags, iTag);
100     if(id != CODEC_ID_NONE) return id;    
105 CodecID _getCodecId(char *tag)
107     if(!strcasecmp(tag, "iv31") ||
108         !strcasecmp(tag, "iv32"))
109     {
110         return CODEC_ID_INDEO3;
111     }
112     /*
113     else if(!strcasecmp(tag, "msvc") ||
114         !strcasecmp(tag, "cram") ||
115         !strcasecmp(tag, "wham"))
116     {
117         return CODEC_ID_MSVIDEO1;
118     }*/
119     else if(!strcasecmp(tag, "wmv1"))
120     {
121         return CODEC_ID_WMV1;
122     }
123     else if(!strcasecmp(tag, "wmv2"))
124     {
125         return CODEC_ID_WMV2;
126     }
127     else if(!strcasecmp(tag, "mpeg") ||
128         !strcasecmp(tag, "mpg1") ||
129         !strcasecmp(tag, "pim1") ||
130         !strcasecmp(tag, "vcr2") ||
131         !strcasecmp(tag, "mpg2"))
132     {
133         return CODEC_ID_MPEG1VIDEO;
134     }
135     else if(!strcasecmp(tag, "mjpa") ||
136         !strcasecmp(tag, "mjpb") ||
137         !strcasecmp(tag, "mjpg") ||
138         !strcasecmp(tag, "ljpg") ||
139         !strcasecmp(tag, "avdj") ||
140         !strcasecmp(tag, "jpgl"))
141     {
142         return CODEC_ID_MJPEG;
143     }
144     else if(!strcasecmp(tag, "svq1") ||
145         !strcasecmp(tag, "svqi"))
146     {
147         return CODEC_ID_SVQ1;
148     }
149     else if(!strcasecmp(tag, "sv31"))
150     {
151         return CODEC_ID_SVQ3;
152     }
153     else if(!strcasecmp(tag, "mp4v") ||
154         !strcasecmp(tag, "divx") ||
155         !strcasecmp(tag, "dx50") ||
156         !strcasecmp(tag, "xvid") ||
157         !strcasecmp(tag, "mp4s") ||
158         !strcasecmp(tag, "div1") ||
159         !strcasecmp(tag, "blz0") ||
160         !strcasecmp(tag, "ump4") ||
161         !strcasecmp(tag, "m4s2"))
162     {
163         return CODEC_ID_MPEG4;
164     }
165     else if(!strcasecmp(tag, "h264"))
166     {
167         return CODEC_ID_H264;
168     }        
169     else if(!strcasecmp(tag, "h263"))
170     {
171         return CODEC_ID_H263;
172     }        
173     else if(!strcasecmp(tag, "u263") ||
174         !strcasecmp(tag, "viv1"))
175     {
176         return CODEC_ID_H263P;
177     }
178 /*    else if(!strcasecmp(tag, "i263"))
179     {
180         return CODEC_ID_I263;
181     }  */
182     else if(!strcasecmp(tag, "dvc") ||
183         !strcasecmp(tag, "dvcp") ||
184         !strcasecmp(tag, "dvsd") ||
185         !strcasecmp(tag, "dvhs") ||
186         !strcasecmp(tag, "dvs1") ||
187         !strcasecmp(tag, "dv25"))
188     {
189         return CODEC_ID_DVVIDEO;
190     }
191     else if(!strcasecmp(tag, "vp31"))
192     {
193         return CODEC_ID_VP3;
194     }  
195     /*else if(!strcasecmp(tag, "rpza"))
196     {
197         return CODEC_ID_RPZA;
198     }  
199     else if(!strcasecmp(tag, "cvid"))
200     {
201         return CODEC_ID_CINEPAK;
202     }  
203     else if(!strcasecmp(tag, "smc"))
204     {
205         return CODEC_ID_SMC;
206     }*/         
207     else if(!strcasecmp(tag, "mp42")||
208         !strcasecmp(tag, "div2"))
209     {
210         return CODEC_ID_MSMPEG4V2;
211     }
212     else if(!strcasecmp(tag, "mpg4"))
213     {
214         return CODEC_ID_MSMPEG4V1;
215     }       
216     else if(!strcasecmp(tag, "div3") ||
217         !strcasecmp(tag, "mp43") ||
218         !strcasecmp(tag, "mpg3") ||
219         !strcasecmp(tag, "div5") ||
220         !strcasecmp(tag, "div6") ||
221         !strcasecmp(tag, "div4") ||
222         !strcasecmp(tag, "ap41") ||
223         !strcasecmp(tag, "col1") ||
224         !strcasecmp(tag, "col0"))
225     {
226         return CODEC_ID_MSMPEG4V3;
227     }
228     return CODEC_ID_NONE;
231 bool isBigEndianSA()
233     int tmp = 0x12345678;
234     char *buf = (char*)(&tmp);
235     //printf("%x %x %x %x\n", (int)buf[0], (int)buf[1], (int)buf[2], (int)buf[3]);
236     if(buf[0]==0x78) return (jboolean)0;
237     else return (jboolean)1;
242  * Class:     com_omnividea_media_codec_video_JavaDecoder
243  * Method:    isBigEndian
244  * Signature: ()Z
245  */
246 JNIEXPORT jboolean JNICALL Java_com_omnividea_media_codec_video_JavaDecoder_isBigEndian
247   (JNIEnv *env, jclass cl)
249     return (jboolean)isBigEndianSA();
252 int FFMPEG_init = 0;
254 static void setOutputDone(JNIEnv *env, jobject obj, int done) {
255     jclass clazz = env->GetObjectClass(obj);
256     jfieldID fid = env->GetFieldID(clazz, "outputDone", "Z");
257     env->SetIntField(obj, fid, (jboolean)done);
262  * Class:     com_omnividea_media_codec_video_JavaDecoder
263  * Method:    init
264  * Signature: ()V
265  */
266 JNIEXPORT void JNICALL Java_com_omnividea_media_codec_video_JavaDecoder_init
267   (JNIEnv *env, jobject obj)
269     FFMPEGWrapper *wrapper;
271     if(!FFMPEG_init) {
272         avcodec_init();
273         avcodec_register_all();
274         FFMPEG_init = 1;
275     }
278     jclass clazz = env->GetObjectClass(obj);
279     jfieldID fidPeer = env->GetFieldID(clazz, "peer", "I");   
280     jint peerVal = env->GetIntField(obj, fidPeer);
281     if (peerVal != 0)
282         return;
283     
285     wrapper = (FFMPEGWrapper *) av_malloc( sizeof(FFMPEGWrapper) );
286     if(!wrapper)
287         return;
289     memset(wrapper,0,sizeof(FFMPEGWrapper));
291     env->SetIntField(obj, fidPeer, (jint)wrapper);
292 #ifdef DEBUG
293     av_log(NULL, AV_LOG_INFO, "obj initialized.\n");
294 #endif
295     return;
300  * Class:     com_omnividea_media_codec_video_JavaDecoder
301  * Method:    open_codec
302  * Signature: (ILjava/lang/String;)Z
303  */
304 JNIEXPORT jboolean JNICALL Java_com_omnividea_media_codec_video_JavaDecoder_open_1codec
305   (JNIEnv *env, jobject obj, jint peer, jstring codec_name)
307     FFMPEGWrapper *wrapper;    
308     enum CodecID codec_required;
310     if (peer == 0)
311         return (jboolean) 0;
313     wrapper = (FFMPEGWrapper *) peer;
315     // Find matching ffmpeg codec using the codec_name passed in
316     const char *str = env->GetStringUTFChars(codec_name, 0);
317 #ifdef DEBUG
318         av_log(NULL, AV_LOG_INFO, "open_codec called for %s\n", str);
319 #endif
320     av_log(NULL, AV_LOG_INFO, "Encoding: %s\n", str);
322     //codec_required = getCodecId((char*)str);
323     codec_required = getCodecId((char*)str);
324     env->ReleaseStringUTFChars(codec_name, str);
325     if (codec_required == CODEC_ID_NONE)
326     {
327         av_log(NULL, AV_LOG_INFO, "Codec NOT Found!\n");
328         return (jboolean) 0;
329     }
330     av_log(NULL, AV_LOG_INFO, "Codec Found: %d\n", codec_required);
333     /* find the video decoder */
334     wrapper->codec = avcodec_find_decoder(codec_required);
335     if (!wrapper->codec ) {
336         //fprintf(stderr, "codec not found\n");
337         return (jboolean) 0;
338     }
340         // Allocate and zero the codec context and frame. Remember
341         // them in the wrapper structure.
342         AVCodecContext *context = avcodec_alloc_context();
343         wrapper->codec_context  = context;
344     
345     //try to alloc some extradata space, just in case
346     context->extradata = (uint8_t*) av_malloc(200); //solve some issues with SVQ3 codec (and maybe others)
347     context->time_base.num = 1;
348     context->time_base.num = 30000;
349     context->sample_aspect_ratio.num = 1;
350     context->sample_aspect_ratio.den = 1;
351     //wrapper->codec_context->bit_rate = 0;
352     //wrapper->codec_context->codec_tag = (str[3] << 24)|(str[2] << 16)|(str[1] << 8)|str[0];
353     //wrapper->codec_context->frame_rate_base = 1001;
354     //wrapper->codec_context->frame_rate *= 1001;
355         //wrapper->picture        = avcodec_alloc_frame();
356     //context->flags |= CODEC_FLAG_EMU_EDGE;
357     //context->flags |= CODEC_FLAG_TRUNCATED;
359     /* for some codecs, such as msmpeg4 and mpeg4, width and height
360        MUST be initialized there because these info are not available
361        in the bitstream */
362     if(wrapper->codec_context->width ==0)
363         wrapper->codec_context->width = wrapper->width;
364     if(wrapper->codec_context->height == 0)
365         wrapper->codec_context->height = wrapper->height;
367     /* open it */
368     wrapper->codec_context->codec_id = codec_required;
369     if (avcodec_open(wrapper->codec_context, wrapper->codec) < 0) {
370         //fprintf(stderr, "could not open codec\n");
371         return (jboolean) 0;
372     }    
373     //wrapper->parser_context = av_parser_init(codec_required);
374     
375     av_log(NULL, AV_LOG_INFO, "Codec opened...W=%d H=%d\n", wrapper->codec_context->width, wrapper->codec_context->height);
376 #ifdef DEBUG
377     av_log(NULL, AV_LOG_INFO, "open_codec successful!\n");
378 #endif
380     return (jboolean) 1;
386 unsigned char* getRGB(AVPicture *decodedPicture, FFMPEGWrapper *wrapper, int *outBuf)//, int sizeOutBuf)
388    int ret;
389    int w = 0, h = 0;
390    unsigned offset = 0;
391    AVPicture *tmpPicture;
392    enum PixelFormat pix_fmt=PIX_FMT_RGB24;
393    AVCodecContext *dec = wrapper->codec_context;
394    
395    /* convert pixel format if needed */
396    if(pix_fmt == dec->pix_fmt) 
397    {
398     av_log(NULL, AV_LOG_INFO, "Same PIXFMT!\n");
399       tmpPicture = decodedPicture;
400    }
401    else
402    {
403       /* create temporary picture */
404       if(wrapper->rgbBuf == NULL)
405       {
406          int size = avpicture_get_size(pix_fmt, dec->width, dec->height);
407          wrapper->rgbBuf = (uint8_t *)av_malloc(size);
408          if (!wrapper->rgbBuf)
409          {
410             return NULL;
411          }
412          avpicture_fill(&(wrapper->rgbPicture), wrapper->rgbBuf, pix_fmt, dec->width, dec->height);
413       }
414       /*
415       int size = avpicture_get_size(pix_fmt, dec->width, dec->height);
416       if(size > sizeOutBuf)
417       {
418         printf("FFMPEG PLUGIN: Not enough buffer(%d, %d)!!!!\n", size, sizeOutBuf);
419         return NULL;
420       }
421       avpicture_fill(&(wrapper->rgbPicture), outBuf, pix_fmt, dec->width, dec->height);*/
422       ret = img_convert(&(wrapper->rgbPicture), pix_fmt, 
423                        decodedPicture, dec->pix_fmt, 
424                        dec->width, dec->height);
425       if(ret < 0) 
426       {
427          return NULL;
428       }
429       
430       tmpPicture = &(wrapper->rgbPicture);
431    }
432    return (unsigned char *)tmpPicture->data[0];
438  * Class:     com_omnividea_media_codec_video_JavaDecoder
439  * Method:    init_decoding
440  * Signature: (III)V
441  */
442 JNIEXPORT void JNICALL Java_com_omnividea_media_codec_video_JavaDecoder_init_1decoding
443   (JNIEnv *env, jobject obj, jint peer, jint width, jint height)
445     FFMPEGWrapper *wrapper;    
446     int got_picture, len, inBuf_size;
448         if (peer == 0)
449                 return;
450     av_log(NULL, AV_LOG_INFO, "Setting size - %dx%d\n", width, height);
451     wrapper = (FFMPEGWrapper *) peer;
452     wrapper->width = width;
453     wrapper->height = height;
454     
455     //if(wrapper->frameBuf != NULL) free(wrapper->frameBuf);
456     //wrapper->frameBuf = NULL;// (unsigned char*)malloc(width * height * 3);
461  * Class:     com_omnividea_media_codec_video_JavaDecoder
462  * Method:    convert
463  * Signature: (ILjava/lang/Object;JILjava/lang/Object;JJD)Z
464  */
465 JNIEXPORT jboolean JNICALL Java_com_omnividea_media_codec_video_JavaDecoder_convert
466   (JNIEnv *env, jobject obj, jint peer,
467    jobject jinBuffer, jlong inBytes, jint inOffset,
468    jobject joutBuffer, jlong outBytes, jlong size, jdouble dts)
470     static int counter = 0;
471         unsigned char *inBuf  = (unsigned char *) inBytes;
472         int *outBuf = (int *) outBytes;
473     unsigned char *inBuf_ptr = NULL;
474         int outputDone = 0; // false by default
475     FFMPEGWrapper *wrapper;    
476     int got_picture, len, inBuf_size;
477     AVCodecContext *c;
478 //    int64_t ffDts = dts * 1000000;
479     jlong outBufferSize = outBytes;
481         if (peer == 0)
482                 return (jboolean) 0;
484     wrapper = (FFMPEGWrapper *) peer;
485     c = wrapper->codec_context;
486     
487     //if(c->codec_type == CODEC_TYPE_AUDIO) return convertAudio(env, obj, peer, jinBuffer, inBytes, inOffset, joutBuffer, outBytes, size, dts);
489     //printf("OutputBuffer Size: %ld\n", (long)outBytes);
490     if(c->width == 0 && c->height == 0)
491     {
492         //printf("Setting W%H in codec context:%dx%d\n",wrapper->width, wrapper->height);
493         c->width = wrapper->width;
494         c->height = wrapper-> height;
495     }
496     
497     if (inBytes == 0)
498         inBuf = (unsigned char *) env->GetByteArrayElements((jbyteArray) jinBuffer, NULL);
500     if (dts > 0 && outBytes == 0)
501     {
502         outBuf = (int *) env->GetIntArrayElements((jintArray) joutBuffer, NULL);
503         //outBufferSize = env->GetArrayLength((jbyteArray)joutBuffer);
504     } else if(dts < 0) {
505         outBuf = (int *) env->GetDirectBufferAddress(joutBuffer);
506     }
508     inBuf_ptr = inBuf;
509         inBuf_size = size;
511     //printf("DTS: %lf %ld\n", dts, ffDts);
513     inBuf_ptr += inOffset;
514     got_picture = 0;
515     while (inBuf_size > 0) {
516 //        unsigned long pts, dts;
517 //        printf("Trace 0: %p %p %p %p\n", wrapper->parser_context, wrapper->parser_context->parser, wrapper->codec, wrapper->frameBuf);
518         //len = av_parser_parse(wrapper->parser_context, wrapper->codec_context, &(wrapper->frameBuf), &(wrapper->frameBufSize), inBuf_ptr, inBuf_size, ffDts, ffDts*1000);
519         //inBuf_size -= len;
520         //inBuf_ptr += len;        
521         //printf("avdecode: len=%d bSize=%d frameBufSize=%d\n", len, inBuf_size, wrapper->frameBufSize);
522         //if(wrapper->frameBufSize <= 0) continue;
523         AVFrame big_picture;
524         //len = avcodec_decode_video(c, wrapper->picture, &got_picture,  wrapper->frameBuf, wrapper->frameBufSize);
525         len = avcodec_decode_video(c, &big_picture, &got_picture,  inBuf_ptr, inBuf_size);
526         /*if(len != inBuf_size)
527         {
528         }*/
529         inBuf_size -= len;
530         inBuf_ptr += len;  
531         inBuf_size = 0; //FIX 0.4.1      
532         //printf("avdecode: len=%d bSize=%d frameBufSize=%d\n", len, inBuf_size, wrapper->frameBufSize);
533         
534         /*if (len < 0) {
535             //fprintf(stderr, "Error while decoding frame \n");
536             return (jboolean) 0;
537         }*/
538         if (len >= 0 && got_picture) {
539             wrapper->picture = *(AVPicture*)&big_picture;
540             //printf("Hey...there's a frame!!");
541             unsigned int rgbSize = wrapper->codec_context->width * wrapper->codec_context->height;
542             
543             
544             //Code for wrapper->getRGBA((char*)outBuf);
545             int ret;
546             enum PixelFormat pix_fmt=PIX_FMT_RGBA32;
547             AVPicture tmpPicture;
548             avpicture_fill(&tmpPicture, (uint8_t *)outBuf, pix_fmt, c->width, c->height);    
549             ret = img_convert(&tmpPicture, pix_fmt, 
550                                &(wrapper->picture), c->pix_fmt, 
551                                c->width, c->height);
552             if(ret < 0) 
553             {
554                  av_log(NULL, AV_LOG_INFO, "Error Converting into RGBA\n");
555             }
558             
559             
560             /*
561             unsigned char *buffer = getRGB(&(wrapper->picture), wrapper, outBuf);//, outBufferSize);
562             if(buffer == NULL)
563             {
564                 av_log(NULL, AV_LOG_INFO, "Error converting into RGB\n");
565                 return (jboolean)0;
566             }
567             //JpegLib::rgb2jpeg(buffer, wrapper->codec_context->width, wrapper->codec_context->height, (String("frame_")+String::intToStr(counter++)+String(".jpg")).c_str());
568             unsigned int i = 0, offset = 0, offsetRGB = 0, w = 0, h = 0;
569             offsetRGB = 0;
570             *outBuf = 0;
572             int* dst = outBuf;//(int*)(((char *)outBuf)+1);
573             unsigned char* src = (unsigned char*)buffer;
574             bool flag = isBigEndianSA();
575             if(flag)
576             {
577                 for(; i < rgbSize; i++)
578                 {
579                     memcpy(((char*)dst)+1, src, 3);
580                     dst++;
581                     src+=3;
582                     
583                     //*dst = (*src)<<16 | (*(++src))<<8 | (*(++src));
584                     //src++;
586                 }
587             }
588             else
589             {
590                 for(; i < rgbSize; i++)
591                 {
592                     
593                     //memcpy(((char*)dst)+1, src, 3);
594                     //dst++;
595                     //src+=3;
596                     
597                     *dst = (*src)<<16 | (*(src+1))<<8 | (*(src+2));
598                     src+=3;
599                     dst++;
601                 }            
602             }*/
604             outputDone = 1;
605         }
606     }
607         // export the outputDone variable to tell JMF when the output buffer has
608         // been filled with data.
609         setOutputDone(env, obj, outputDone);
611     if (outBytes == 0)
612         if(dts > 0)env->ReleaseIntArrayElements((jintArray) joutBuffer, (jint *) outBuf, 0);
613     if (inBytes == 0)
614         env->ReleaseByteArrayElements((jbyteArray) jinBuffer, (jbyte *) inBuf, JNI_ABORT);
616     jboolean retCode = len >=0;
617     return retCode; 
620 jboolean convertAudio
621   (JNIEnv *env, jobject obj, jint peer,
622    jobject jinBuffer, jlong inBytes, jint inOffset,
623    jobject joutBuffer, jlong outBytes, jlong size, jdouble dts)
625     static int counter = 0;
626         unsigned char *inBuf  = (unsigned char *) inBytes;
627         int *outBuf = (int *) outBytes;
628     unsigned char *inBuf_ptr = NULL;
629         int outputDone = 0; // false by default
630     FFMPEGWrapper *wrapper;    
631     int got_picture, len, inBuf_size;
632     AVCodecContext *c;
633     int64_t ffDts = (int64_t) (dts * 1000000);
634     jlong outBufferSize = outBytes;
636         if (peer == 0)
637                 return (jboolean) 0;
639     wrapper = (FFMPEGWrapper *) peer;
640     c = wrapper->codec_context;
641     
642     if (inBytes == 0)
643         inBuf = (unsigned char *) env->GetByteArrayElements((jbyteArray) jinBuffer, NULL);
645     if (outBytes == 0)
646     {
647         outBuf = (int *) env->GetIntArrayElements((jintArray) joutBuffer, NULL);
648         //outBufferSize = env->GetArrayLength((jbyteArray)joutBuffer);
649     }
651     inBuf_ptr = inBuf;
652         inBuf_size = size;
654     //printf("DTS: %lf %ld\n", dts, ffDts);
656     inBuf_ptr += inOffset;
657     got_picture = 0;
658     while (inBuf_size > 0) {
659         //short decodedSamples[AVCODEC_MAX_AUDIO_FRAME_SIZE];
660         int data_size = 0;
662         len = avcodec_decode_audio(c, (int16_t*)outBuf, &data_size, inBuf_ptr, inBuf_size);
663         wrapper->lastAudioSize = data_size;
665         inBuf_size -= len;
666         inBuf_ptr += len;        
667         //printf("avdecode: len=%d bSize=%d frameBufSize=%d\n", len, inBuf_size, wrapper->frameBufSize);
668         
669         if (len < 0) {
670             //fprintf(stderr, "Error while decoding frame \n");
671             return (jboolean) 0;
672         }
673         if (data_size>0) {
675             outputDone = 1;
676         }
677     }
678         // export the outputDone variable to tell JMF when the output buffer has
679         // been filled with data.
680         setOutputDone(env, obj, outputDone);
682     if (outBytes == 0)
683         env->ReleaseIntArrayElements((jintArray) joutBuffer, (jint *) outBuf, 0);
684     if (inBytes == 0)
685         env->ReleaseByteArrayElements((jbyteArray) jinBuffer, (jbyte *) inBuf, JNI_ABORT);
687     return (jboolean) 1; 
691  * Class:     com_omnividea_media_codec_video_JavaDecoder
692  * Method:    close_codec
693  * Signature: (I)Z
694  */
695 JNIEXPORT jboolean JNICALL Java_com_omnividea_media_codec_video_JavaDecoder_close_1codec
696   (JNIEnv *env, jobject obj, jint peer)
698         FFMPEGWrapper *wrapper;    
700         if (peer == 0)
701                 return (jboolean) 0;
703         wrapper = (FFMPEGWrapper *) peer;
705     //av_parser_close(wrapper->parser_context);
706     if(wrapper->codec_context)
707     {
708         av_free(wrapper->codec_context->extradata); //solve some issues with SVQ3 codec (and maybe others)
709         avcodec_close(wrapper->codec_context);
710         av_free(wrapper->codec_context);
711     }
712     /*
713     if(wrapper->parser_context)
714     {
715         free(wrapper->parser_context);
716     }*/
718         //free(wrapper->picture);
719     if(wrapper->rgbBuf) av_free(wrapper->rgbBuf);
720     //if(wrapper->frameBuf)free(wrapper->frameBuf);
721         if(wrapper) av_free(wrapper);
722     wrapper = NULL;
724         // Make sure the "peer" variable is zeroed in java class
725     jclass clazz = env->GetObjectClass(obj);
726     jfieldID fidPeer = env->GetFieldID(clazz, "peer", "I");
727     env->SetIntField(obj, fidPeer, (jint)0);
729 #ifdef DEBUG
730         av_log(NULL, AV_LOG_INFO, "close_codec finished\n");
731 #endif
732         return (jboolean) 1; 
740 /* Inaccessible static: bigEndian */
742  * Class:     com_omnividea_media_codec_audio_JavaDecoder
743  * Method:    isBigEndian
744  * Signature: ()Z
745  */
746 JNIEXPORT jboolean JNICALL Java_com_omnividea_media_codec_audio_JavaDecoder_isBigEndian
747   (JNIEnv *env , jclass cl)
749     return Java_com_omnividea_media_codec_video_JavaDecoder_isBigEndian(env , cl);
753  * Class:     com_omnividea_media_codec_audio_JavaDecoder
754  * Method:    init
755  * Signature: ()V
756  */
757 JNIEXPORT void JNICALL Java_com_omnividea_media_codec_audio_JavaDecoder_init
758   (JNIEnv *env, jobject obj)
760     return Java_com_omnividea_media_codec_video_JavaDecoder_init(env, obj);
764  * Class:     com_omnividea_media_codec_audio_JavaDecoder
765  * Method:    open_codec
766  * Signature: (ILjava/lang/String;)Z
767  */
768 JNIEXPORT jboolean JNICALL Java_com_omnividea_media_codec_audio_JavaDecoder_open_1codec
769   (JNIEnv *env, jobject obj, jint peer, jstring codec_name)
771     return Java_com_omnividea_media_codec_video_JavaDecoder_open_1codec(env, obj, peer, codec_name);
775  * Class:     com_omnividea_media_codec_audio_JavaDecoder
776  * Method:    close_codec
777  * Signature: (I)Z
778  */
779 JNIEXPORT jboolean JNICALL Java_com_omnividea_media_codec_audio_JavaDecoder_close_1codec
780   (JNIEnv *env, jobject obj, jint peer)
782     return Java_com_omnividea_media_codec_video_JavaDecoder_close_1codec(env, obj, peer);
786  * Class:     com_omnividea_media_codec_audio_JavaDecoder
787  * Method:    init_decoding
788  * Signature: (III)V
789  */
790 JNIEXPORT void JNICALL Java_com_omnividea_media_codec_audio_JavaDecoder_init_1decoding
791   (JNIEnv *env, jobject obj, jint peer, jint width, jint height)
792   {
793     return Java_com_omnividea_media_codec_video_JavaDecoder_init_1decoding(env, obj, peer, width,  height);
794   }
797  * Class:     com_omnividea_media_codec_audio_JavaDecoder
798  * Method:    convert
799  * Signature: (ILjava/lang/Object;JILjava/lang/Object;JJD)Z
800  */
801 JNIEXPORT jboolean JNICALL Java_com_omnividea_media_codec_audio_JavaDecoder_convert
802   (JNIEnv *env, jobject obj, jint peer,
803    jobject jinBuffer, jlong inBytes, jint inOffset,
804    jobject joutBuffer, jlong outBytes, jlong size, jdouble dts) 
806     return convertAudio(env,  obj,  peer, jinBuffer,  inBytes,  inOffset,
807              joutBuffer, outBytes, size, dts);
812  * Class:     com_omnividea_media_codec_audio_JavaDecoder
813  * Method:    lastAudioSize
814  * Signature: (I)I
815  */
816 JNIEXPORT jint JNICALL Java_com_omnividea_media_codec_audio_JavaDecoder_lastAudioSize
817   (JNIEnv *env, jobject obj, jint peer)
819     FFMPEGWrapper *wrapper;    
820         if (peer == 0)
821                 return -1;
822     wrapper = (FFMPEGWrapper *) peer;
823     return wrapper->lastAudioSize;