00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029 #include "NvJpegDecoder.h"
00030 #include "NvLogging.h"
00031 #include <string.h>
00032 #include <malloc.h>
00033 #include "unistd.h"
00034 #include "stdlib.h"
00035
00036 #define MAX(a, b) ((a) > (b) ? (a) : (b))
00037 #define ROUND_UP_4(num) (((num) + 3) & ~3)
00038
00039 #define CAT_NAME "JpegDecoder"
00040
00041 NvJPEGDecoder::NvJPEGDecoder(const char *comp_name)
00042 :NvElement(comp_name, valid_fields)
00043 {
00044 memset(&cinfo, 0, sizeof(cinfo));
00045 memset(&jerr, 0, sizeof(jerr));
00046 cinfo.err = jpeg_std_error(&jerr);
00047
00048 jpeg_create_decompress(&cinfo);
00049 }
00050
00051 NvJPEGDecoder *
00052 NvJPEGDecoder::createJPEGDecoder(const char *comp_name)
00053 {
00054 NvJPEGDecoder *jpegdec = new NvJPEGDecoder(comp_name);
00055 if (jpegdec->isInError())
00056 {
00057 delete jpegdec;
00058 return NULL;
00059 }
00060 return jpegdec;
00061 }
00062
00063 NvJPEGDecoder::~NvJPEGDecoder()
00064 {
00065 jpeg_destroy_decompress(&cinfo);
00066 CAT_DEBUG_MSG(comp_name << " (" << this << ") destroyed");
00067 }
00068
00069 int
00070 NvJPEGDecoder::decodeToFd(int &fd, unsigned char * in_buf,
00071 unsigned long in_buf_size, uint32_t &pixfmt, uint32_t &width,
00072 uint32_t &height)
00073 {
00074 uint32_t pixel_format = 0;
00075 uint32_t buffer_id;
00076
00077 if (in_buf == NULL || in_buf_size == 0)
00078 {
00079 COMP_ERROR_MSG("Not decoding because input buffer = NULL or size = 0");
00080 return -1;
00081 }
00082
00083 buffer_id = profiler.startProcessing();
00084
00085 cinfo.out_color_space = JCS_YCbCr;
00086
00087 jpeg_mem_src(&cinfo, in_buf, in_buf_size);
00088
00089 cinfo.out_color_space = JCS_YCbCr;
00090
00091
00092 (void) jpeg_read_header(&cinfo, TRUE);
00093
00094 cinfo.out_color_space = JCS_YCbCr;
00095 cinfo.IsVendorbuf = TRUE;
00096
00097 if (cinfo.comp_info[0].h_samp_factor == 2)
00098 {
00099 if (cinfo.comp_info[0].v_samp_factor == 2)
00100 {
00101 pixel_format = V4L2_PIX_FMT_YUV420M;
00102 }
00103 else
00104 {
00105 pixel_format = V4L2_PIX_FMT_YUV422M;
00106 }
00107 }
00108 else
00109 {
00110 if (cinfo.comp_info[0].v_samp_factor == 1)
00111 {
00112 pixel_format = V4L2_PIX_FMT_YUV444M;
00113 }
00114 else
00115 {
00116 pixel_format = V4L2_PIX_FMT_YUV422RM;
00117 }
00118 }
00119
00120 jpeg_start_decompress (&cinfo);
00121 jpeg_read_raw_data (&cinfo, NULL, cinfo.comp_info[0].v_samp_factor * DCTSIZE);
00122 jpeg_finish_decompress(&cinfo);
00123
00124 width = cinfo.image_width;
00125 height = cinfo.image_height;
00126 pixfmt = pixel_format;
00127 fd = cinfo.fd;
00128
00129 COMP_DEBUG_MSG("Succesfully decoded Buffer fd=" << fd);
00130
00131 profiler.finishProcessing(buffer_id, false);
00132 return 0;
00133 }
00134
00135 int
00136 NvJPEGDecoder::decodeToBuffer(NvBuffer ** buffer, unsigned char * in_buf,
00137 unsigned long in_buf_size, uint32_t *pixfmt, uint32_t * width,
00138 uint32_t * height)
00139 {
00140 unsigned char **line[3];
00141 unsigned char *y[4 * DCTSIZE] = { NULL, };
00142 unsigned char *u[4 * DCTSIZE] = { NULL, };
00143 unsigned char *v[4 * DCTSIZE] = { NULL, };
00144 int i, j;
00145 int lines, v_samp[3];
00146 unsigned char *base[3], *last[3];
00147 int stride[3];
00148 NvBuffer *out_buf = NULL;
00149 uint32_t pixel_format = 0;
00150 uint32_t buffer_id;
00151
00152 if (buffer == NULL)
00153 {
00154 COMP_ERROR_MSG("Not decoding because buffer = NULL");
00155 return -1;
00156 }
00157
00158 if (in_buf == NULL || in_buf_size == 0)
00159 {
00160 COMP_ERROR_MSG("Not decoding because input buffer = NULL or size = 0");
00161 return -1;
00162 }
00163
00164 buffer_id = profiler.startProcessing();
00165
00166 cinfo.out_color_space = JCS_YCbCr;
00167 jpeg_mem_src(&cinfo, in_buf, in_buf_size);
00168 cinfo.out_color_space = JCS_YCbCr;
00169
00170 (void) jpeg_read_header(&cinfo, TRUE);
00171
00172 cinfo.out_color_space = JCS_YCbCr;
00173
00174 if (cinfo.comp_info[0].h_samp_factor == 2)
00175 {
00176 if (cinfo.comp_info[0].v_samp_factor == 2)
00177 {
00178 pixel_format = V4L2_PIX_FMT_YUV420M;
00179 }
00180 else
00181 {
00182 pixel_format = V4L2_PIX_FMT_YUV422M;
00183 }
00184 }
00185 else
00186 {
00187 if (cinfo.comp_info[0].v_samp_factor == 1)
00188 {
00189 pixel_format = V4L2_PIX_FMT_YUV444M;
00190 }
00191 else
00192 {
00193 pixel_format = V4L2_PIX_FMT_YUV422RM;
00194 }
00195 }
00196
00197 out_buf = new NvBuffer(pixel_format, cinfo.image_width,
00198 cinfo.image_height, 0);
00199 out_buf->allocateMemory();
00200
00201 jpeg_start_decompress (&cinfo);
00202
00203 line[0] = y;
00204 line[1] = u;
00205 line[2] = v;
00206
00207 for (i = 0; i < 3; i++)
00208 {
00209 v_samp[i] = cinfo.comp_info[i].v_samp_factor;
00210 stride[i] = out_buf->planes[i].fmt.width;
00211 base[i] = out_buf->planes[i].data;
00212 last[i] = base[i] + (stride[i] * (out_buf->planes[i].fmt.height - 1));
00213 }
00214
00215 for (i = 0; i < (int) cinfo.image_height; i += v_samp[0] * DCTSIZE)
00216 {
00217 for (j = 0; j < (v_samp[0] * DCTSIZE); ++j)
00218 {
00219
00220 line[0][j] = base[0] + (i + j) * stride[0];
00221
00222
00223 if (pixel_format == V4L2_PIX_FMT_YUV420M)
00224 {
00225
00226 line[0][j] = base[0] + (i + j) * stride[0];
00227 if ((line[0][j] > last[0]))
00228 line[0][j] = last[0];
00229
00230 if (v_samp[1] == v_samp[0]) {
00231 line[1][j] = base[1] + ((i + j) / 2) * stride[1];
00232 } else if (j < (v_samp[1] * DCTSIZE)) {
00233 line[1][j] = base[1] + ((i / 2) + j) * stride[1];
00234 }
00235 if ((line[1][j] > last[1]))
00236 line[1][j] = last[1];
00237
00238 if (v_samp[2] == v_samp[0]) {
00239 line[2][j] = base[2] + ((i + j) / 2) * stride[2];
00240 } else if (j < (v_samp[2] * DCTSIZE)) {
00241 line[2][j] = base[2] + ((i / 2) + j) * stride[2];
00242 }
00243 if ((line[2][j] > last[2]))
00244 line[2][j] = last[2];
00245 }
00246 else
00247 {
00248 line[1][j] = base[1] + (i + j) * stride[1];
00249 line[2][j] = base[2] + (i + j) * stride[2];
00250 }
00251 }
00252
00253 lines = jpeg_read_raw_data (&cinfo, line, v_samp[0] * DCTSIZE);
00254 if ((!lines))
00255 {
00256 COMP_DEBUG_MSG( "jpeg_read_raw_data() returned 0\n");
00257 }
00258 }
00259
00260 jpeg_finish_decompress(&cinfo);
00261 if (width)
00262 {
00263 *width= cinfo.image_width;
00264 }
00265 if (height)
00266 {
00267 *height= cinfo.image_height;
00268 }
00269 if (pixfmt)
00270 {
00271 *pixfmt = pixel_format;
00272 }
00273 *buffer = out_buf;
00274
00275 COMP_DEBUG_MSG("Succesfully decoded Buffer " << buffer);
00276
00277 profiler.finishProcessing(buffer_id, false);
00278
00279 return 0;
00280 }