author | kasin.li <kasin.li@amlogic.com> | 2011-11-05 09:42:47 (GMT) |
---|---|---|
committer | kasin.li <kasin.li@amlogic.com> | 2011-11-05 09:42:47 (GMT) |
commit | e54d9f7959454b3b401c629fbb7a6dfc40fd4c06 (patch) | |
tree | f0a52504978c883c77d337d36fb4793926dc39ad | |
parent | bf9afca891accea7aacc9efbd7d5d4cff8908e62 (diff) | |
download | camera-e54d9f7959454b3b401c629fbb7a6dfc40fd4c06.zip camera-e54d9f7959454b3b401c629fbb7a6dfc40fd4c06.tar.gz camera-e54d9f7959454b3b401c629fbb7a6dfc40fd4c06.tar.bz2 |
update camera encoder with turbojpeg encoder.
-rwxr-xr-x | Android.mk | 5 | ||||
-rwxr-xr-x | V4L2/V4L2Camera.cpp | 4 | ||||
-rwxr-xr-x | jpegenc/amljpeg_enc.c | 274 | ||||
-rwxr-xr-x | jpegenc/amljpeg_enc.h | 3 |
4 files changed, 192 insertions, 94 deletions
@@ -11,7 +11,7 @@ LOCAL_SHARED_LIBRARIES := \ libcamera_client \ libbinder \ libjpeg \ - libexif + libexif ifeq ($(BOARD_HAVE_FRONT_CAM),true) LOCAL_CFLAGS += -DAMLOGIC_FRONT_CAMERA_SUPPORT @@ -34,7 +34,8 @@ ifeq ($(BOARD_HAVE_FLASHLIGHT),true) endif endif -#LOCAL_C_INCLUDES += $ANDROID_BUILD_TOP/kernel/include/ +LOCAL_C_INCLUDES += \ + external/jpeg #USE V4L2 Camera LOCAL_SRC_FILES += jpegenc/amljpeg_enc.c diff --git a/V4L2/V4L2Camera.cpp b/V4L2/V4L2Camera.cpp index 3c6d530..1872f8f 100755 --- a/V4L2/V4L2Camera.cpp +++ b/V4L2/V4L2Camera.cpp @@ -515,7 +515,7 @@ int V4L2Camera::GenExif(unsigned char** pExif,int* exifLen,uint8_t* framebuf) enc.obuff_size = thumbnailwidth*thumbnailheight*3; enc.data_in_app1 = 0; enc.app1_data_size = 0; - thumbnailsize = encode_jpeg(&enc); + thumbnailsize = encode_jpeg2(&enc); delete rgbdata; // LOGD("after add thumbnail %d,%d len %d",thumbnailwidth,thumbnailheight,thumbnailsize); @@ -564,7 +564,7 @@ status_t V4L2Camera::GetJpegFrame(uint8_t* framebuf,int* jpegsize) GenExif(&(exifcontent),&(enc.app1_data_size),(unsigned char*)pV4L2Frames[m_iPicIdx]); #endif enc.data_in_app1=exifcontent+2; - *jpegsize = encode_jpeg(&enc); + *jpegsize = encode_jpeg2(&enc); if(exifcontent!=0) free(exifcontent); } diff --git a/jpegenc/amljpeg_enc.c b/jpegenc/amljpeg_enc.c index d982d6b..f8a1e2c 100755 --- a/jpegenc/amljpeg_enc.c +++ b/jpegenc/amljpeg_enc.c @@ -16,108 +16,141 @@ #include <fcntl.h>
#include <string.h>
#include <errno.h>
-#include "jpeglib.h" +#include "jpeglib.h"
#include "jconfig.h"
-#include <setjmp.h> -#include "amljpeg_enc.h" -typedef struct { - struct jpeg_destination_mgr pub; /* public fields */ - - char* obuf; - int buf_size; - int data_size; -} aml_destination_mgr; - -typedef aml_destination_mgr * aml_dest_ptr; - -static void init_destination (j_compress_ptr cinfo) -{ - aml_dest_ptr dest = (aml_dest_ptr) cinfo->dest; - - dest->pub.next_output_byte = dest->obuf; - dest->pub.free_in_buffer = dest->buf_size; -} - -static boolean empty_output_buffer (j_compress_ptr cinfo) -{ - aml_dest_ptr dest = (aml_dest_ptr) cinfo->dest; - - /* error handling, input buffer too small. */ - /* maybe you need not use jpeg encoder. */ - - return FALSE; -} - -static void term_destination (j_compress_ptr cinfo) -{ - aml_dest_ptr dest = (aml_dest_ptr) cinfo->dest; - size_t datacount = dest->buf_size - dest->pub.free_in_buffer; - - dest->data_size = datacount; -} - -int encode_jpeg(jpeg_enc_t* enc) -{ - - /* create compress. information data. */ - struct jpeg_compress_struct cinfo; - struct jpeg_error_mgr jerr; - aml_destination_mgr dest; - - JSAMPROW row_pointer[1]; /* pointer to JSAMPLE row[s] */ - int row_stride; /* physical row width in image buffer */ - cinfo.err = jpeg_std_error(&jerr); - jpeg_create_compress(&cinfo); - //jpeg_stdio_dest(&cinfo, outfile); - cinfo.dest=(struct jpeg_destination_mgr *)&dest; - dest.pub.init_destination = init_destination; - dest.pub.empty_output_buffer = empty_output_buffer; - dest.pub.term_destination = term_destination; - - dest.obuf = enc->odata; - dest.buf_size = enc->obuff_size; - - /* set parameters. */ - cinfo.image_width = enc->width; - cinfo.image_height = enc->height; - cinfo.input_components = 3; - cinfo.in_color_space = JCS_RGB; - jpeg_set_defaults(&cinfo); - if(enc->quality==0) - enc->quality=75; - jpeg_set_quality(&cinfo, enc->quality, TRUE); - - jpeg_start_compress(&cinfo, TRUE); - +#include <setjmp.h>
+#include "amljpeg_enc.h"
+#include <cutils/log.h>
+
+#include <tjutil.h>
+#include <turbojpeg.h>
+
+typedef struct {
+ struct jpeg_destination_mgr pub; /* public fields */
+
+ char* obuf;
+ int buf_size;
+ int data_size;
+} aml_destination_mgr;
+
+typedef aml_destination_mgr * aml_dest_ptr;
+
+static void init_destination (j_compress_ptr cinfo)
+{
+ aml_dest_ptr dest = (aml_dest_ptr) cinfo->dest;
+
+ dest->pub.next_output_byte = dest->obuf;
+ dest->pub.free_in_buffer = dest->buf_size;
+}
+
+static boolean empty_output_buffer (j_compress_ptr cinfo)
+{
+ aml_dest_ptr dest = (aml_dest_ptr) cinfo->dest;
+
+ /* error handling, input buffer too small. */
+ /* maybe you need not use jpeg encoder. */
+
+ return FALSE;
+}
+
+static void term_destination (j_compress_ptr cinfo)
+{
+ aml_dest_ptr dest = (aml_dest_ptr) cinfo->dest;
+ size_t datacount = dest->buf_size - dest->pub.free_in_buffer;
+
+ dest->data_size = datacount;
+}
+
+int encode_jpeg(jpeg_enc_t* enc)
+{
+
+ /* create compress. information data. */
+ struct jpeg_compress_struct cinfo;
+ struct jpeg_error_mgr jerr;
+ aml_destination_mgr dest;
+
+ JSAMPROW row_pointer[1]; /* pointer to JSAMPLE row[s] */
+ int row_stride; /* physical row width in image buffer */
+ cinfo.err = jpeg_std_error(&jerr);
+ jpeg_create_compress(&cinfo);
+ //jpeg_stdio_dest(&cinfo, outfile);
+ cinfo.dest=(struct jpeg_destination_mgr *)&dest;
+ dest.pub.init_destination = init_destination;
+ dest.pub.empty_output_buffer = empty_output_buffer;
+ dest.pub.term_destination = term_destination;
+
+ dest.obuf = enc->odata;
+ dest.buf_size = enc->obuff_size;
+
+ /* set parameters. */
+ cinfo.image_width = enc->width;
+ cinfo.image_height = enc->height;
+ cinfo.input_components = 3;
+ cinfo.in_color_space = JCS_RGB;
+ jpeg_set_defaults(&cinfo);
+ if(enc->quality==0)
+ enc->quality=75;
+ jpeg_set_quality(&cinfo, enc->quality, TRUE);
+
+ jpeg_start_compress(&cinfo, TRUE);
+
if(enc->data_in_app1)
jpeg_write_marker(&cinfo,0xe1,enc->data_in_app1,enc->app1_data_size);
- row_stride = enc->width * 3; - - /* processing. */ - while (cinfo.next_scanline < cinfo.image_height) { - row_pointer[0] = & enc->idata[cinfo.next_scanline * row_stride]; - (void) jpeg_write_scanlines(&cinfo, row_pointer, 1); - } - - jpeg_finish_compress(&cinfo); - jpeg_destroy_compress(&cinfo); - return dest.data_size; -} + row_stride = enc->width * 3;
+
+ /* processing. */
+ while (cinfo.next_scanline < cinfo.image_height) {
+ row_pointer[0] = & enc->idata[cinfo.next_scanline * row_stride];
+ (void) jpeg_write_scanlines(&cinfo, row_pointer, 1);
+ }
+
+ jpeg_finish_compress(&cinfo);
+ jpeg_destroy_compress(&cinfo);
+ return dest.data_size;
+}
+
+#define _throwtj() {LOGD("TurboJPEG ERROR:\n%s\n", tjGetErrorStr()); \
+ enc->obuff_size=0;goto exit;}
+#define _tj(f) {if((f)==-1) _throwtj();}
+#define _throw(m) {LOGD("ERROR: %s\n", m); enc->obuff_size=0; goto exit;}
+
+int encode_jpeg2(jpeg_enc_t* enc)
+{
+ tjhandle handle=NULL;
+
+ if(enc->quality==0)
+ enc->quality=75;
+
+ if((handle=tjInitCompress())==NULL) _throwtj();
+ _tj(tjCompressRGB2YUV420WithMark(handle, enc->idata, enc->width, enc->height, &enc->odata,
+ &enc->obuff_size, enc->quality, enc->data_in_app1,enc->app1_data_size));
+
+exit:
+ if(handle) tjDestroy(handle);
+ return enc->obuff_size;
+}
/* example. */
#ifdef ENC_TEST
-#define iwidth 1280
-#define iheight 720
+#define iwidth 3000
+#define iheight 2000
#define buf_size (iwidth*iheight)
char jpeg_dat[buf_size*3];
+char jpeg_out[buf_size*3];
int main() {
FILE* fp;
int data_size,i;
jpeg_enc_t enc;
+ struct timeval start;
+ struct timeval end;
+ float time_use=0;
+
+ memset(&enc,0,sizeof(jpeg_enc_t));
+
enc.width=iwidth;
enc.height=iheight;
enc.quality=75;
@@ -128,17 +161,80 @@ int main() { fp=fopen("test1.jpeg","wb");
if(!fp) {
- printf(" open error\n");
+ LOGD(" open error\n");
exit(1);
}
- for(i=0;i<buf_size*3;i+=3) {
+ for(i=0;i<buf_size;i+=3) {
jpeg_dat[i]=0;
jpeg_dat[i+1]=0;
jpeg_dat[i+2]=0xff;
}
- data_size=encode_jpeg(&enc);
+ for(i=buf_size;i<buf_size*2;i+=3) {
+ jpeg_dat[i]=0;
+ jpeg_dat[i+1]=0xff;
+ jpeg_dat[i+2]=0;
+ }
+ for(i=buf_size*2;i<buf_size*3;i+=3) {
+ jpeg_dat[i]=0xff;
+ jpeg_dat[i+1]=0;
+ jpeg_dat[i+2]=0;
+ }
+ gettimeofday(&start,NULL);
+ for(i=0;i<20;i++) {
+ enc.obuff_size = buf_size*3;
+ data_size=encode_jpeg(&enc);
+ }
+ gettimeofday(&end,NULL);
+ time_use=(end.tv_sec-start.tv_sec)*1000000+(end.tv_usec-start.tv_usec);
+ LOGD("time_use in libjpeg2 %f\n",time_use/20);
fwrite(jpeg_dat,1,data_size,fp);
fclose(fp);
+
+/*******************************************/
+ LOGD("start decoder2\n");
+ memset(&enc,0,sizeof(jpeg_enc_t));
+ enc.width=iwidth;
+ enc.height=iheight;
+ enc.quality=75;
+ enc.idata = jpeg_dat;
+ enc.ibuff_size = buf_size*3;
+ enc.odata = jpeg_out;
+ enc.obuff_size = buf_size*3;
+
+ fp=fopen("test2.jpeg","wb");
+ if(!fp) {
+ LOGD(" open error\n");
+ exit(1);
+ }
+ for(i=0;i<buf_size;i+=3) {
+ jpeg_dat[i]=0;
+ jpeg_dat[i+1]=0;
+ jpeg_dat[i+2]=0xff;
+ }
+ for(i=buf_size;i<buf_size*2;i+=3) {
+ jpeg_dat[i]=0;
+ jpeg_dat[i+1]=0xff;
+ jpeg_dat[i+2]=0;
+ }
+ for(i=buf_size*2;i<buf_size*3;i+=3) {
+ jpeg_dat[i]=0xff;
+ jpeg_dat[i+1]=0;
+ jpeg_dat[i+2]=0;
+ }
+ gettimeofday(&start,NULL);
+ for(i=0;i<20;i++) {
+ enc.obuff_size = buf_size*3;
+ data_size=encode_jpeg2(&enc);
+ }
+ gettimeofday(&end,NULL);
+ time_use=(end.tv_sec-start.tv_sec)*1000000+(end.tv_usec-start.tv_usec);
+ LOGD("time_use in turbojpeg2 %f\n",time_use/20);
+ if(data_size)
+ fwrite(jpeg_out,1,data_size,fp);
+ else
+ LOGD("fucking error\n");
+ fclose(fp);
+
return 0;
}
#endif
diff --git a/jpegenc/amljpeg_enc.h b/jpegenc/amljpeg_enc.h index 3f90e6e..23a9bf3 100755 --- a/jpegenc/amljpeg_enc.h +++ b/jpegenc/amljpeg_enc.h @@ -19,8 +19,9 @@ extern "C" {
#endif
int encode_jpeg(jpeg_enc_t* enc);
+int encode_jpeg2(jpeg_enc_t* enc);
#ifdef __cplusplus
}
#endif
-#endif /* AM_JPEG_ENCODER_9908049 */
\ No newline at end of file +#endif /* AM_JPEG_ENCODER_9908049 */
|