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_decode.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
00060 if (!v4l2_buf)
00061 {
00062 cerr << "Failed to dequeue buffer from conv capture plane" << endl;
00063 abort(ctx);
00064 return false;
00065 }
00066
00067 write_video_frame(ctx->out_file, *buffer);
00068 return false;
00069 }
00070
00071 static uint64_t
00072 get_file_size(ifstream * stream)
00073 {
00074 uint64_t size = 0;
00075 streampos current_pos = stream->tellg();
00076 stream->seekg(0, stream->end);
00077 size = stream->tellg();
00078 stream->seekg(current_pos, stream->beg);
00079 return size;
00080 }
00081
00082 static void
00083 set_defaults(context_t * ctx)
00084 {
00085 memset(ctx, 0, sizeof(context_t));
00086 ctx->use_fd = true;
00087 }
00088
00089 int
00090 main(int argc, char *argv[])
00091 {
00092 context_t ctx;
00093 int ret = 0;
00094 int error = 0;
00095 int fd;
00096 uint32_t width, height, pixfmt;
00097
00098 set_defaults(&ctx);
00099
00100 ret = parse_csv_args(&ctx, argc, argv);
00101 TEST_ERROR(ret < 0, "Error parsing commandline arguments", cleanup);
00102
00103 ctx.in_file = new ifstream(ctx.in_file_path);
00104 TEST_ERROR(!ctx.in_file->is_open(), "Could not open input file", cleanup);
00105
00106 ctx.out_file = new ofstream(ctx.out_file_path);
00107 TEST_ERROR(!ctx.out_file->is_open(), "Could not open output file", cleanup);
00108
00109 ctx.jpegdec = NvJPEGDecoder::createJPEGDecoder("jpegdec");
00110 TEST_ERROR(!ctx.jpegdec, "Could not create Jpeg Decoder", cleanup);
00111
00112 ctx.in_file_size = get_file_size(ctx.in_file);
00113 ctx.in_buffer = new unsigned char[ctx.in_file_size];
00114 ctx.in_file->read((char *) ctx.in_buffer, ctx.in_file_size);
00115
00116 if (!ctx.use_fd)
00117 {
00118 NvBuffer *buffer;
00119 ret = ctx.jpegdec->decodeToBuffer(&buffer, ctx.in_buffer,
00120 ctx.in_file_size, &pixfmt, &width, &height);
00121 TEST_ERROR(ret < 0, "Could not decode image", cleanup);
00122 cout << "Image Resolution - " << width << " x " << height << endl;
00123 write_video_frame(ctx.out_file, *buffer);
00124 delete buffer;
00125 goto cleanup;
00126 }
00127
00128 ctx.conv = NvVideoConverter::createVideoConverter("conv");
00129 TEST_ERROR(!ctx.conv, "Could not create Video Converter", cleanup);
00130
00131 ret = ctx.jpegdec->decodeToFd(fd, ctx.in_buffer, ctx.in_file_size, pixfmt,
00132 width, height);
00133 TEST_ERROR(ret < 0, "Could not decode image", cleanup);
00134 cout << "Image Resolution - " << width << " x " << height << endl;
00135
00136 ret = ctx.conv->setCropRect(0, 0, width, height);
00137 TEST_ERROR(ret < 0, "Could not set crop rect for conv0", cleanup);
00138
00139
00140 ret =
00141 ctx.conv->setOutputPlaneFormat(pixfmt, width,
00142 height, V4L2_NV_BUFFER_LAYOUT_PITCH);
00143 TEST_ERROR(ret < 0, "Could not set output plane format for conv", cleanup);
00144
00145
00146 ret =
00147 ctx.conv->setCapturePlaneFormat(pixfmt, width,
00148 height,
00149 V4L2_NV_BUFFER_LAYOUT_PITCH);
00150 TEST_ERROR(ret < 0, "Could not set capture plane format for conv", cleanup);
00151
00152
00153 ret = ctx.conv->output_plane.setupPlane(V4L2_MEMORY_DMABUF, 1, false, false);
00154 TEST_ERROR(ret < 0, "Error while setting up output plane for conv",
00155 cleanup);
00156
00157
00158
00159
00160 ret =
00161 ctx.conv->capture_plane.setupPlane(V4L2_MEMORY_MMAP, 1,
00162 true, false);
00163 TEST_ERROR(ret < 0, "Error while setting up capture plane for conv",
00164 cleanup);
00165
00166
00167 ret = ctx.conv->output_plane.setStreamStatus(true);
00168 TEST_ERROR(ret < 0, "Error in output plane streamon for conv", cleanup);
00169
00170
00171 ret = ctx.conv->capture_plane.setStreamStatus(true);
00172 TEST_ERROR(ret < 0, "Error in capture plane streamon for conv", cleanup);
00173
00174 ctx.conv->
00175 capture_plane.setDQThreadCallback(conv_capture_dqbuf_thread_callback);
00176
00177
00178 ctx.conv->capture_plane.startDQThread(&ctx);
00179
00180
00181 for (uint32_t i = 0; i < ctx.conv->capture_plane.getNumBuffers(); i++)
00182 {
00183 struct v4l2_buffer v4l2_buf;
00184 struct v4l2_plane planes[MAX_PLANES];
00185
00186 memset(&v4l2_buf, 0, sizeof(v4l2_buf));
00187 memset(planes, 0, MAX_PLANES * sizeof(struct v4l2_plane));
00188
00189 v4l2_buf.index = i;
00190 v4l2_buf.m.planes = planes;
00191
00192 ret = ctx.conv->capture_plane.qBuffer(v4l2_buf, NULL);
00193 if (ret < 0)
00194 {
00195 cerr << "Error while queueing buffer at conv capture plane" << endl;
00196 abort(&ctx);
00197 goto cleanup;
00198 }
00199 }
00200
00201 {
00202 struct v4l2_buffer v4l2_buf;
00203 struct v4l2_plane planes[MAX_PLANES];
00204
00205 memset(&v4l2_buf, 0, sizeof(v4l2_buf));
00206 memset(planes, 0, MAX_PLANES * sizeof(struct v4l2_plane));
00207
00208 v4l2_buf.index = 0;
00209 v4l2_buf.m.planes = planes;
00210 planes[0].m.fd = fd;
00211 planes[0].bytesused = 1234;
00212
00213 ret = ctx.conv->output_plane.qBuffer(v4l2_buf, NULL);
00214 if (ret < 0)
00215 {
00216 cerr << "Error while queueing buffer at conv output plane" << endl;
00217 abort(&ctx);
00218 goto cleanup;
00219 }
00220 }
00221
00222
00223 ctx.conv->capture_plane.waitForDQThread(2000);
00224
00225 cleanup:
00226 if (ctx.conv && ctx.conv->isInError())
00227 {
00228 cerr << "VideoConverter is in error" << endl;
00229 error = 1;
00230 }
00231
00232 if (ctx.got_error)
00233 {
00234 error = 1;
00235 }
00236
00237 delete ctx.in_file;
00238 delete ctx.out_file;
00239
00240
00241 delete ctx.conv;
00242 delete ctx.jpegdec;
00243 delete[] ctx.in_buffer;
00244
00245 free(ctx.in_file_path);
00246 free(ctx.out_file_path);
00247
00248 if (error)
00249 {
00250 cout << "App run failed" << endl;
00251 }
00252 else
00253 {
00254 cout << "App run was successful" << endl;
00255 }
00256 return -error;
00257 }