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 "NvUtils.h"
00030 #include <errno.h>
00031 #include <fstream>
00032 #include <iostream>
00033 #include <malloc.h>
00034 #include <string.h>
00035 #include <unistd.h>
00036
00037 #include "jpeg_encode.h"
00038
00039 #define TEST_ERROR(cond, str, label) if(cond) { \
00040 cerr << str << endl; \
00041 error = 1; \
00042 goto label; }
00043
00044 using namespace std;
00045
00046 static void
00047 abort(context_t * ctx)
00048 {
00049 ctx->got_error = true;
00050 ctx->conv->abort();
00051 }
00052
00053 static bool
00054 conv_capture_dqbuf_thread_callback(struct v4l2_buffer *v4l2_buf,
00055 NvBuffer * buffer, NvBuffer * shared_buffer,
00056 void *arg)
00057 {
00058 context_t *ctx = (context_t *) arg;
00059 unsigned long out_buf_size = ctx->in_width * ctx->in_height * 3 / 2;
00060 unsigned char *out_buf = new unsigned char[out_buf_size];
00061
00062 if (!v4l2_buf)
00063 {
00064 cerr << "Failed to dequeue buffer from conv capture plane" << endl;
00065 abort(ctx);
00066 delete[] out_buf;
00067 return false;
00068 }
00069
00070 if (v4l2_buf->m.planes[0].bytesused > 0)
00071 {
00072 if (ctx->jpegenc->encodeFromFd(buffer->planes[0].fd, JCS_YCbCr, &out_buf,
00073 out_buf_size) < 0)
00074 {
00075 cerr << "Error while encoding from fd" << endl;
00076 ctx->got_error = true;
00077 }
00078 else
00079 {
00080 ctx->out_file->write((char *) out_buf, out_buf_size);
00081 }
00082 }
00083
00084 delete[] out_buf;
00085
00086 return false;
00087 }
00088
00089 static void
00090 set_defaults(context_t * ctx)
00091 {
00092 memset(ctx, 0, sizeof(context_t));
00093 ctx->use_fd = true;
00094 ctx->in_pixfmt = V4L2_PIX_FMT_YUV420M;
00095 }
00096
00097 int
00098 main(int argc, char *argv[])
00099 {
00100 context_t ctx;
00101 int ret = 0;
00102 int error = 0;
00103
00104 set_defaults(&ctx);
00105
00106 ret = parse_csv_args(&ctx, argc, argv);
00107 TEST_ERROR(ret < 0, "Error parsing commandline arguments", cleanup);
00108
00109 ctx.in_file = new ifstream(ctx.in_file_path);
00110 TEST_ERROR(!ctx.in_file->is_open(), "Could not open input file", cleanup);
00111
00112 ctx.out_file = new ofstream(ctx.out_file_path);
00113 TEST_ERROR(!ctx.out_file->is_open(), "Could not open output file", cleanup);
00114
00115 ctx.jpegenc = NvJPEGEncoder::createJPEGEncoder("jpenenc");
00116 TEST_ERROR(!ctx.jpegenc, "Could not create Jpeg Encoder", cleanup);
00117
00118 ctx.jpegenc->setCropRect(ctx.crop_left, ctx.crop_top,
00119 ctx.crop_width, ctx.crop_height);
00120
00121 if (!ctx.use_fd)
00122 {
00123 unsigned long out_buf_size = ctx.in_width * ctx.in_height * 3 / 2;
00124 unsigned char *out_buf = new unsigned char[out_buf_size];
00125
00126 NvBuffer buffer(V4L2_PIX_FMT_YUV420M, ctx.in_width,
00127 ctx.in_height, 0);
00128
00129 buffer.allocateMemory();
00130
00131 ret = read_video_frame(ctx.in_file, buffer);
00132 TEST_ERROR(ret < 0, "Could not read a complete frame from file",
00133 cleanup);
00134
00135 ret = ctx.jpegenc->encodeFromBuffer(buffer, JCS_YCbCr, &out_buf,
00136 out_buf_size);
00137 TEST_ERROR(ret < 0, "Error while encoding from buffer", cleanup);
00138
00139 ctx.out_file->write((char *) out_buf, out_buf_size);
00140 delete[] out_buf;
00141
00142 goto cleanup;
00143 }
00144
00145 ctx.conv = NvVideoConverter::createVideoConverter("conv");
00146 TEST_ERROR(!ctx.conv, "Could not create Video Converter", cleanup);
00147
00148
00149 ret =
00150 ctx.conv->setOutputPlaneFormat(V4L2_PIX_FMT_YUV420M, ctx.in_width,
00151 ctx.in_height,
00152 V4L2_NV_BUFFER_LAYOUT_PITCH);
00153 TEST_ERROR(ret < 0, "Could not set output plane format for conv", cleanup);
00154
00155
00156 ret =
00157 ctx.conv->setCapturePlaneFormat(ctx.in_pixfmt, ctx.in_width,
00158 ctx.in_height,
00159 V4L2_NV_BUFFER_LAYOUT_BLOCKLINEAR);
00160 TEST_ERROR(ret < 0, "Could not set capture plane format for conv", cleanup);
00161
00162
00163 ret = ctx.conv->output_plane.setupPlane(V4L2_MEMORY_MMAP, 1, true, false);
00164 TEST_ERROR(ret < 0, "Error while setting up output plane for conv",
00165 cleanup);
00166
00167
00168
00169
00170 ret =
00171 ctx.conv->capture_plane.setupPlane(V4L2_MEMORY_MMAP, 1,
00172 !ctx.use_fd, false);
00173 TEST_ERROR(ret < 0, "Error while setting up capture plane for conv",
00174 cleanup);
00175
00176
00177 ret = ctx.conv->output_plane.setStreamStatus(true);
00178 TEST_ERROR(ret < 0, "Error in output plane streamon for conv", cleanup);
00179
00180
00181 ret = ctx.conv->capture_plane.setStreamStatus(true);
00182 TEST_ERROR(ret < 0, "Error in capture plane streamon for conv", cleanup);
00183
00184 ctx.conv->
00185 capture_plane.setDQThreadCallback(conv_capture_dqbuf_thread_callback);
00186
00187
00188 ctx.conv->capture_plane.startDQThread(&ctx);
00189
00190
00191 for (uint32_t i = 0; i < ctx.conv->capture_plane.getNumBuffers(); i++)
00192 {
00193 struct v4l2_buffer v4l2_buf;
00194 struct v4l2_plane planes[MAX_PLANES];
00195
00196 memset(&v4l2_buf, 0, sizeof(v4l2_buf));
00197 memset(planes, 0, MAX_PLANES * sizeof(struct v4l2_plane));
00198
00199 v4l2_buf.index = i;
00200 v4l2_buf.m.planes = planes;
00201
00202 ret = ctx.conv->capture_plane.qBuffer(v4l2_buf, NULL);
00203 if (ret < 0)
00204 {
00205 cerr << "Error while queueing buffer at conv capture plane" << endl;
00206 abort(&ctx);
00207 goto cleanup;
00208 }
00209 }
00210
00211 {
00212 struct v4l2_buffer v4l2_buf;
00213 struct v4l2_plane planes[MAX_PLANES];
00214 NvBuffer *buffer = ctx.conv->output_plane.getNthBuffer(0);
00215
00216 memset(&v4l2_buf, 0, sizeof(v4l2_buf));
00217 memset(planes, 0, MAX_PLANES * sizeof(struct v4l2_plane));
00218
00219 v4l2_buf.index = 0;
00220 v4l2_buf.m.planes = planes;
00221
00222 if (read_video_frame(ctx.in_file, *buffer) < 0)
00223 {
00224 cerr << "Could not read a complete frame from file" << endl;
00225 v4l2_buf.m.planes[0].bytesused = 0;
00226 }
00227
00228 ret = ctx.conv->output_plane.qBuffer(v4l2_buf, NULL);
00229 if (ret < 0)
00230 {
00231 cerr << "Error while queueing buffer at conv output plane" << endl;
00232 abort(&ctx);
00233 goto cleanup;
00234 }
00235 }
00236
00237
00238 ctx.conv->capture_plane.waitForDQThread(2000);
00239
00240 cleanup:
00241 if (ctx.conv && ctx.conv->isInError())
00242 {
00243 cerr << "VideoConverter is in error" << endl;
00244 error = 1;
00245 }
00246
00247 if (ctx.got_error)
00248 {
00249 error = 1;
00250 }
00251
00252 delete ctx.in_file;
00253 delete ctx.out_file;
00254
00255
00256 delete ctx.conv;
00257 delete ctx.jpegenc;
00258
00259 free(ctx.in_file_path);
00260 free(ctx.out_file_path);
00261
00262 if (error)
00263 {
00264 cout << "App run failed" << endl;
00265 }
00266 else
00267 {
00268 cout << "App run was successful" << endl;
00269 }
00270 return -error;
00271 }