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 <errno.h>
00030 #include <fstream>
00031 #include <iostream>
00032 #include <linux/videodev2.h>
00033 #include <malloc.h>
00034 #include <pthread.h>
00035 #include <string.h>
00036 #include <unistd.h>
00037 #include <sys/prctl.h>
00038
00039 #include "NvUtils.h"
00040 #include "NvCudaProc.h"
00041 #include "nvbuf_utils.h"
00042 #include "video_dec_gie.h"
00043 #include "gie_inference.h"
00044
00045 #define USE_CPU_FOR_INTFLOAT_CONVERSION 0
00046
00047 #define TEST_ERROR(cond, str, label) if(cond) { \
00048 cerr << str << endl; \
00049 error = 1; \
00050 goto label; }
00051
00052 #define CHUNK_SIZE 4000000
00053
00054 #define IS_NAL_UNIT_START(buffer_ptr) \
00055 (!buffer_ptr[0] && !buffer_ptr[1] && \
00056 !buffer_ptr[2] && (buffer_ptr[3] == 1))
00057
00058 const char *GOOGLE_NET_DEPLOY_NAME =
00059 "../../data/model/GoogleNet-modified.prototxt";
00060 const char *GOOGLE_NET_MODEL_NAME =
00061 "../../data/model/GoogleNet-modified-online_iter_30000.caffemodel";
00062
00063 using namespace std;
00064 using namespace nvinfer1;
00065 using namespace nvcaffeparser1;
00066
00067 static void
00068 abort(context_t *ctx)
00069 {
00070 ctx->got_error = true;
00071 ctx->dec->abort();
00072 if (ctx->conv)
00073 {
00074 ctx->conv->abort();
00075 pthread_cond_broadcast(&ctx->queue_cond);
00076 }
00077 }
00078
00079 static int
00080 read_decoder_input_chunk(ifstream * stream, NvBuffer * buffer)
00081 {
00082
00083 streamsize bytes_to_read = MIN(CHUNK_SIZE, buffer->planes[0].length);
00084
00085 stream->read((char *) buffer->planes[0].data, bytes_to_read);
00086
00087
00088
00089 buffer->planes[0].bytesused = stream->gcount();
00090 return 0;
00091 }
00092
00093 static int
00094 sendEOStoConverter(context_t *ctx)
00095 {
00096
00097 if (ctx->conv->output_plane.getStreamStatus())
00098 {
00099 NvBuffer *conv_buffer;
00100 struct v4l2_buffer v4l2_buf;
00101 struct v4l2_plane planes[MAX_PLANES];
00102
00103 memset(&v4l2_buf, 0, sizeof(v4l2_buf));
00104 memset(&planes, 0, sizeof(planes));
00105
00106 v4l2_buf.m.planes = planes;
00107 pthread_mutex_lock(&ctx->queue_lock);
00108 while (ctx->conv_output_plane_buf_queue->empty())
00109 {
00110 pthread_cond_wait(&ctx->queue_cond, &ctx->queue_lock);
00111 }
00112 conv_buffer = ctx->conv_output_plane_buf_queue->front();
00113 ctx->conv_output_plane_buf_queue->pop();
00114 pthread_mutex_unlock(&ctx->queue_lock);
00115
00116 v4l2_buf.index = conv_buffer->index;
00117
00118
00119 return ctx->conv->output_plane.qBuffer(v4l2_buf, NULL);
00120 }
00121 return 0;
00122 }
00123
00124 static bool
00125 initConv(context_t * ctx)
00126 {
00127 int ret = 0;
00128 struct v4l2_format format;
00129
00130 ret = ctx->dec->capture_plane.getFormat(format);
00131 if (ret < 0)
00132 {
00133 cerr << "Error: Could not get format from decoder capture plane" << endl;
00134 return false;
00135 }
00136
00137 ret = ctx->conv->setOutputPlaneFormat(format.fmt.pix_mp.pixelformat,
00138 format.fmt.pix_mp.width,
00139 format.fmt.pix_mp.height,
00140 V4L2_NV_BUFFER_LAYOUT_BLOCKLINEAR);
00141 if(ret < 0)
00142 {
00143 cerr << "Error in converter output plane set format" << endl;
00144 return false;
00145 }
00146
00147
00148
00149
00150 ret = ctx->conv->setCapturePlaneFormat(V4L2_PIX_FMT_ABGR32,
00151 ctx->gie_ctx->getNetWidth(),
00152 ctx->gie_ctx->getNetHeight(),
00153 V4L2_NV_BUFFER_LAYOUT_PITCH);
00154 if (ret < 0)
00155 {
00156 cerr << "Error in converter capture plane set format" << endl;
00157 return false;
00158 }
00159
00160 ret = ctx->conv->setCropRect(0, 0, ctx->dec_width, ctx->dec_height);
00161 if (ret < 0)
00162 {
00163 cerr << "Error while setting crop rect" << endl;
00164 return false;
00165 }
00166
00167 ret = ctx->conv->output_plane.setupPlane(V4L2_MEMORY_DMABUF,
00168 ctx->dec->capture_plane.getNumBuffers(),
00169 false,
00170 false);
00171 if (ret < 0)
00172 {
00173 cerr << "Error in converter output plane setup" << endl;
00174 return false;
00175 }
00176
00177 ret = ctx->conv->capture_plane.setupPlane(V4L2_MEMORY_MMAP,
00178 ctx->dec->capture_plane.getNumBuffers(),
00179 true,
00180 false);
00181 if (ret < 0)
00182 {
00183 cerr << "Error in converter capture plane setup" << endl;
00184 return false;
00185 }
00186
00187 ret = ctx->conv->output_plane.setStreamStatus(true);
00188 if (ret < 0)
00189 {
00190 cerr << "Error in converter output plane streamon" << endl;
00191 return false;
00192 }
00193
00194 ret = ctx->conv->capture_plane.setStreamStatus(true);
00195 if (ret < 0)
00196 {
00197 cerr << "Error in converter output plane streamoff" << endl;
00198 return false;
00199 }
00200
00201
00202 for (uint32_t i = 0; i < ctx->conv->output_plane.getNumBuffers(); i++)
00203 {
00204 ctx->conv_output_plane_buf_queue->push(ctx->conv->output_plane.
00205 getNthBuffer(i));
00206 }
00207
00208 for (uint32_t i = 0; i < ctx->conv->capture_plane.getNumBuffers(); i++)
00209 {
00210 struct v4l2_buffer v4l2_buf;
00211 struct v4l2_plane planes[MAX_PLANES];
00212
00213 memset(&v4l2_buf, 0, sizeof(v4l2_buf));
00214 memset(planes, 0, sizeof(planes));
00215
00216 v4l2_buf.index = i;
00217 v4l2_buf.m.planes = planes;
00218 ret = ctx->conv->capture_plane.qBuffer(v4l2_buf, NULL);
00219 if (ret < 0)
00220 {
00221 cerr << "Error Qing buffer at converter capture plane" << endl;
00222 return false;
00223 }
00224 }
00225 ctx->conv->output_plane.startDQThread(ctx);
00226 ctx->conv->capture_plane.startDQThread(ctx);
00227
00228 return true;
00229 }
00230
00231 static bool
00232 deinitConv(context_t * ctx)
00233 {
00234 int ret;
00235
00236 ret = sendEOStoConverter(ctx);
00237 if (ret < 0)
00238 {
00239 cerr << "Error while queueing EOS buffer on converter output" << endl;
00240 return false;
00241 }
00242
00243 ctx->conv->capture_plane.waitForDQThread(2000);
00244
00245 ctx->conv->output_plane.deinitPlane();
00246 ctx->conv->capture_plane.deinitPlane();
00247
00248 while(!ctx->conv_output_plane_buf_queue->empty())
00249 {
00250 ctx->conv_output_plane_buf_queue->pop();
00251 }
00252 return true;
00253 }
00254
00255 static void
00256 resChange(context_t * ctx)
00257 {
00258 NvVideoDecoder *dec = ctx->dec;
00259 struct v4l2_format format;
00260 struct v4l2_crop crop;
00261 int32_t min_dec_capture_buffers;
00262 int ret = 0;
00263 int error = 0;
00264
00265
00266
00267 ret = dec->capture_plane.getFormat(format);
00268 TEST_ERROR(ret < 0,
00269 "Error: Could not get format from decoder capture plane", error);
00270
00271
00272 ret = dec->capture_plane.getCrop(crop);
00273 TEST_ERROR(ret < 0,
00274 "Error: Could not get crop from decoder capture plane", error);
00275 ctx->dec_width = crop.c.width;
00276 ctx->dec_height = crop.c.height;
00277
00278 cout << "Video Resolution: " << ctx->dec_width << "x" << ctx->dec_height << endl;
00279
00280
00281
00282
00283 ret = deinitConv(ctx);
00284
00285
00286 dec->capture_plane.deinitPlane();
00287
00288
00289
00290 ret = dec->setCapturePlaneFormat(format.fmt.pix_mp.pixelformat,
00291 format.fmt.pix_mp.width,
00292 format.fmt.pix_mp.height);
00293 TEST_ERROR(ret < 0, "Error in setting decoder capture plane format", error);
00294
00295
00296 ret = dec->getMinimumCapturePlaneBuffers(min_dec_capture_buffers);
00297 TEST_ERROR(ret < 0,
00298 "Error while getting value of minimum capture plane buffers",
00299 error);
00300
00301
00302 ret = dec->capture_plane.setupPlane(V4L2_MEMORY_MMAP,
00303 min_dec_capture_buffers,
00304 false,
00305 false);
00306 TEST_ERROR(ret < 0, "Error in decoder capture plane setup", error);
00307
00308 if (ctx->conv)
00309 {
00310 ret = initConv(ctx);
00311 TEST_ERROR(ret == false, "initConv failed", error);
00312 }
00313
00314
00315 ret = dec->capture_plane.setStreamStatus(true);
00316 TEST_ERROR(ret < 0, "Error in decoder capture plane streamon", error);
00317
00318
00319 for (uint32_t i = 0; i < dec->capture_plane.getNumBuffers(); i++)
00320 {
00321 struct v4l2_buffer v4l2_buf;
00322 struct v4l2_plane planes[MAX_PLANES];
00323
00324 memset(&v4l2_buf, 0, sizeof(v4l2_buf));
00325 memset(planes, 0, sizeof(planes));
00326
00327 v4l2_buf.index = i;
00328 v4l2_buf.m.planes = planes;
00329 ret = dec->capture_plane.qBuffer(v4l2_buf, NULL);
00330 TEST_ERROR(ret < 0, "Error Qing buffer at output plane", error);
00331 }
00332
00333 cout << "Resolution change successful" << endl;
00334 return;
00335
00336 error:
00337 if (error)
00338 {
00339 abort(ctx);
00340 cerr << "Error in " << __func__ << endl;
00341 }
00342 }
00343
00344
00345 static bool
00346 decFillBufConv(context_t *ctx, NvBuffer *dec_buf)
00347 {
00348 NvBuffer *conv_buffer;
00349 struct v4l2_buffer conv_output_buffer;
00350 struct v4l2_plane conv_planes[MAX_PLANES];
00351
00352 memset(&conv_output_buffer, 0, sizeof(conv_output_buffer));
00353 memset(conv_planes, 0, sizeof(conv_planes));
00354 conv_output_buffer.m.planes = conv_planes;
00355
00356
00357 pthread_mutex_lock(&ctx->queue_lock);
00358 while (ctx->conv_output_plane_buf_queue->empty())
00359 {
00360 pthread_cond_wait(&ctx->queue_cond, &ctx->queue_lock);
00361 }
00362 conv_buffer = ctx->conv_output_plane_buf_queue->front();
00363 ctx->conv_output_plane_buf_queue->pop();
00364 pthread_mutex_unlock(&ctx->queue_lock);
00365
00366 conv_output_buffer.index = conv_buffer->index;
00367
00368 if (ctx->conv->output_plane.qBuffer(conv_output_buffer, dec_buf) < 0)
00369 {
00370 abort(ctx);
00371 cerr << "Error while queueing buffer at converter output plane"
00372 << endl;
00373 return false;
00374 }
00375 return true;
00376 }
00377
00378 static void*
00379 decCaptureLoop(void *arg)
00380 {
00381 context_t *ctx = (context_t *) arg;
00382 NvVideoDecoder *dec = ctx->dec;
00383 struct v4l2_event ev;
00384 int ret;
00385
00386 cout << "Starting decoder capture loop thread" << endl;
00387 prctl (PR_SET_NAME, "decCap", 0, 0, 0);
00388
00389
00390
00391
00392 do
00393 {
00394 ret = dec->dqEvent(ev, -1);
00395 if (ret < 0)
00396 {
00397 if (errno == EAGAIN)
00398 {
00399 cerr << "Timed out waiting for first V4L2_EVENT_RESOLUTION_CHANGE"
00400 << endl;
00401 }
00402 else
00403 {
00404 cerr << "Error in dequeueing decoder event" << endl;
00405 }
00406 abort(ctx);
00407 break;
00408 }
00409 }
00410 while (ev.type != V4L2_EVENT_RESOLUTION_CHANGE);
00411
00412
00413 if (!ctx->got_error)
00414 resChange(ctx);
00415
00416
00417 while (!(ctx->got_error || dec->isInError() || ctx->got_eos))
00418 {
00419 NvBuffer *dec_buffer;
00420
00421
00422 ret = dec->dqEvent(ev, false);
00423 if (ret == 0)
00424 {
00425 switch (ev.type)
00426 {
00427 case V4L2_EVENT_RESOLUTION_CHANGE:
00428 resChange(ctx);
00429 continue;
00430 }
00431 }
00432
00433 struct v4l2_buffer v4l2_buf;
00434 struct v4l2_plane planes[MAX_PLANES];
00435 memset(&v4l2_buf, 0, sizeof(v4l2_buf));
00436 memset(planes, 0, sizeof(planes));
00437 v4l2_buf.m.planes = planes;
00438
00439
00440 if (dec->capture_plane.dqBuffer(v4l2_buf, &dec_buffer, NULL, 0))
00441 {
00442 if (errno == EAGAIN)
00443 {
00444 usleep(1000);
00445 }
00446 else
00447 {
00448 abort(ctx);
00449 cerr << "Error while calling dequeue at capture plane"
00450 << endl;
00451 }
00452 continue;
00453 }
00454
00455
00456 if (ctx->conv)
00457 {
00458 if (!decFillBufConv(ctx, dec_buffer))
00459 continue;
00460 }
00461 }
00462
00463 cout << "Exiting decoder capture loop thread" << endl;
00464 return NULL;
00465 }
00466
00467 static void*
00468 gieThread(void *arg)
00469 {
00470 int buf_num = 0;
00471 EGLImageKHR egl_image = NULL;
00472 struct v4l2_buffer *v4l2_buf;
00473 NvBuffer *buffer;
00474 NvBuffer *shared_buffer;
00475 context_t *ctx = (context_t *)arg;
00476 int process_last_batch = 0;
00477 float *gie_inputbuf = ctx->gie_ctx->getInputBuf();
00478 prctl (PR_SET_NAME, "gieThread", 0, 0, 0);
00479
00480
00481 ctx->egl_display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
00482 if (ctx->egl_display == EGL_NO_DISPLAY)
00483 {
00484 cerr << "Error while get EGL display connection" << endl;
00485 return NULL;
00486 }
00487
00488
00489 if (!eglInitialize(ctx->egl_display, NULL, NULL))
00490 {
00491 cerr << "Erro while initialize EGL display connection" << endl;
00492 return NULL;
00493 }
00494
00495 while (1)
00496 {
00497
00498 Shared_Buffer gie_buffer;
00499 pthread_mutex_lock(&ctx->gie_lock);
00500 if(ctx->gie_buf_queue->empty())
00501 {
00502 if (ctx->gie_stop && buf_num == 0)
00503 {
00504 pthread_mutex_unlock(&ctx->gie_lock);
00505 break;
00506 }
00507 else if (!ctx->gie_stop)
00508 {
00509
00510 struct timespec timeout;
00511 long time_in_ms = 50;
00512 timeout.tv_sec = time(0);
00513 timeout.tv_nsec = time_in_ms * 1000000;
00514 int ret =
00515 pthread_cond_timedwait(&ctx->gie_cond, &ctx->gie_lock, &timeout);
00516 if (ret != 0)
00517 {
00518 pthread_mutex_unlock(&ctx->gie_lock);
00519 continue;
00520 }
00521 }
00522 }
00523 if (ctx->gie_buf_queue->size() != 0)
00524 {
00525 gie_buffer = ctx->gie_buf_queue->front();
00526 ctx->gie_buf_queue->pop();
00527 }
00528 else
00529 {
00530 process_last_batch = 1;
00531 }
00532 pthread_mutex_unlock(&ctx->gie_lock);
00533
00534
00535 if (process_last_batch == 0)
00536 {
00537 v4l2_buf = &gie_buffer.v4l2_buf;
00538 buffer = gie_buffer.buffer;
00539 shared_buffer = gie_buffer.shared_buffer;
00540 ctx = (context_t *)gie_buffer.arg;
00541
00542 int batch_offset = buf_num * ctx->gie_ctx->getNetWidth() *
00543 ctx->gie_ctx->getNetHeight() * ctx->gie_ctx->getChannel();
00544 #if USE_CPU_FOR_INTFLOAT_CONVERSION
00545
00546
00547
00548 unsigned char *data = buffer->planes[0].data;
00549 int channel_offset = ctx->gie_ctx->getNetWidth() *
00550 ctx->gie_ctx->getNetHeight();
00551
00552 for (int i = 0; i < ctx->gie_ctx->getChannel(); i++)
00553 {
00554 for (int j = 0; j < ctx->gie_ctx->getNetHeight(); j++)
00555 {
00556 for (int k = 0; k < ctx->gie_ctx->getNetWidth(); k++)
00557 {
00558 int total_offset = batch_offset + channel_offset * i +
00559 j * ctx->gie_ctx->getNetWidth() + k;
00560 gie_inputbuf[total_offset] =
00561 (float)(*(data + j * buffer->planes[0].fmt.stride
00562 + k * 4 + 3 - i - 1));
00563 }
00564 }
00565 }
00566 #else
00567
00568
00569 egl_image = NvEGLImageFromFd(ctx->egl_display, buffer->planes[0].fd);
00570 if (egl_image == NULL)
00571 {
00572 cerr << "Error while mapping dmabuf fd ("
00573 << buffer->planes[0].fd << ") to EGLImage"
00574 << endl;
00575 return NULL;
00576 }
00577
00578 void *cuda_buf = ctx->gie_ctx->getBuffer(0);
00579
00580
00581 mapEGLImage2Float(&egl_image, ctx->gie_ctx->getNetWidth(),
00582 ctx->gie_ctx->getNetHeight(),
00583 (char *)cuda_buf + batch_offset * sizeof(float));
00584
00585
00586 NvDestroyEGLImage(ctx->egl_display, egl_image);
00587 egl_image = NULL;
00588 #endif
00589 buf_num++;
00590
00591
00592 if (ctx->conv->capture_plane.qBuffer(*v4l2_buf, NULL) < 0)
00593 {
00594 cout<<"conv queue buffer error"<<endl;
00595 }
00596
00597
00598 if (buf_num < ctx->gie_ctx->getBatchSize() && !ctx->gie_stop)
00599 {
00600 continue;
00601 }
00602 }
00603 else if(buf_num == 0)
00604 {
00605 break;
00606 }
00607
00608
00609 buf_num = 0;
00610 queue<vector<cv::Rect>> rectList_queue;
00611 #if USE_CPU_FOR_INTFLOAT_CONVERSION
00612 ctx->gie_ctx->doInference(
00613 rectList_queue, gie_inputbuf);
00614 #else
00615 ctx->gie_ctx->doInference(
00616 rectList_queue);
00617 #endif
00618 while(!rectList_queue.empty())
00619 {
00620 vector<cv::Rect> rectList = rectList_queue.front();
00621 rectList_queue.pop();
00622
00623 for (int i = 0; i < rectList.size(); i++)
00624 {
00625 cv::Rect &r = rectList[i];
00626 cout <<" x "<< r.x <<" y: " << r.y
00627 <<" width "<< r.width <<" height "<< r.height
00628 << endl;
00629 }
00630 }
00631 if (process_last_batch == 1)
00632 {
00633 break;
00634 }
00635 }
00636
00637
00638 if (ctx->egl_display)
00639 {
00640 if (!eglTerminate(ctx->egl_display))
00641 {
00642 cerr << "Error while terminate EGL display connection\n" << endl;
00643 return NULL;
00644 }
00645 }
00646 return NULL;
00647 }
00648
00649 static bool
00650 conv0_outputDqbufThreadCallback(struct v4l2_buffer *v4l2_buf,
00651 NvBuffer * buffer,
00652 NvBuffer * shared_buffer,
00653 void *arg)
00654 {
00655 context_t *ctx = (context_t *) arg;
00656 struct v4l2_buffer dec_capture_ret_buffer;
00657 struct v4l2_plane planes[MAX_PLANES];
00658
00659 if (!v4l2_buf)
00660 {
00661 cerr << "Failed to dequeue buffer from conv0 output plane" << endl;
00662 abort(ctx);
00663 return false;
00664 }
00665
00666 if (v4l2_buf->m.planes[0].bytesused == 0)
00667 {
00668 return false;
00669 }
00670
00671 memset(&dec_capture_ret_buffer, 0, sizeof(dec_capture_ret_buffer));
00672 memset(planes, 0, sizeof(planes));
00673
00674 dec_capture_ret_buffer.index = shared_buffer->index;
00675 dec_capture_ret_buffer.m.planes = planes;
00676
00677 pthread_mutex_lock(&ctx->queue_lock);
00678 ctx->conv_output_plane_buf_queue->push(buffer);
00679
00680
00681
00682 if (ctx->dec->capture_plane.qBuffer(dec_capture_ret_buffer, NULL) < 0)
00683 {
00684 abort(ctx);
00685 return false;
00686 }
00687
00688 pthread_cond_broadcast(&ctx->queue_cond);
00689 pthread_mutex_unlock(&ctx->queue_lock);
00690
00691 return true;
00692 }
00693
00694 static bool
00695 conv0_captureDqbufThreadCallback(struct v4l2_buffer *v4l2_buf,
00696 NvBuffer *buffer,
00697 NvBuffer *shared_buffer,
00698 void *arg)
00699 {
00700 context_t * ctx = (context_t*) arg;
00701
00702 if (!v4l2_buf)
00703 {
00704 cerr << "Failed to dequeue buffer from conv0 output plane" << endl;
00705 abort(ctx);
00706 return false;
00707 }
00708 if (v4l2_buf->m.planes[0].bytesused == 0)
00709 {
00710 return false;
00711 }
00712
00713
00714 Shared_Buffer gie_buffer;
00715
00716
00717
00718
00719 memcpy(&gie_buffer.v4l2_buf, v4l2_buf, sizeof(v4l2_buffer));
00720
00721 gie_buffer.buffer = buffer;
00722 gie_buffer.shared_buffer = shared_buffer;
00723 gie_buffer.arg = arg;
00724 pthread_mutex_lock(&ctx->gie_lock);
00725 ctx->gie_buf_queue->push(gie_buffer);
00726 pthread_cond_broadcast(&ctx->gie_cond);
00727 pthread_mutex_unlock(&ctx->gie_lock);
00728
00729 return true;
00730 }
00731
00732 static void
00733 setDefaults(context_t * ctx)
00734 {
00735 memset(ctx, 0, sizeof(context_t));
00736 ctx->deployfile = GOOGLE_NET_DEPLOY_NAME;
00737 ctx->modelfile = GOOGLE_NET_MODEL_NAME;
00738 ctx->gie_ctx = new GIE_Context;
00739 ctx->gie_ctx->setDumpResult(true);
00740 ctx->gie_buf_queue = new queue<Shared_Buffer>;
00741
00742 ctx->conv_output_plane_buf_queue = new queue < NvBuffer * >;
00743 pthread_mutex_init(&ctx->queue_lock, NULL);
00744 pthread_cond_init(&ctx->queue_cond, NULL);
00745 }
00746
00747 int
00748 main(int argc, char *argv[])
00749 {
00750 context_t ctx;
00751 int ret = 0;
00752 int error = 0;
00753 uint32_t i;
00754 bool eos = false;
00755 char *nalu_parse_buffer = NULL;
00756
00757 setDefaults(&ctx);
00758
00759 if (parseCsvArgs(&ctx, ctx.gie_ctx, argc, argv))
00760 {
00761 cerr << "Error parsing commandline arguments." << endl;
00762 return -1;
00763 }
00764
00765 ctx.in_file = new ifstream(ctx.in_file_path);
00766 TEST_ERROR(!ctx.in_file->is_open(), "Error opening input file", cleanup);
00767
00768
00769 ctx.dec = NvVideoDecoder::createVideoDecoder("dec0");
00770 TEST_ERROR(!ctx.dec, "Could not create decoder", cleanup);
00771
00772
00773 ret = ctx.dec->subscribeEvent(V4L2_EVENT_RESOLUTION_CHANGE, 0, 0);
00774 TEST_ERROR(ret < 0, "Could not subscribe to V4L2_EVENT_RESOLUTION_CHANGE", cleanup);
00775
00776
00777
00778
00779
00780 ret = ctx.dec->disableCompleteFrameInputBuffer();
00781 TEST_ERROR(ret < 0, "Error in decoder disableCompleteFrameInputBuffer", cleanup);
00782
00783
00784 ret = ctx.dec->setOutputPlaneFormat(ctx.decoder_pixfmt, 2 * 1024 * 1024);
00785 TEST_ERROR(ret < 0, "Could not set output plane format", cleanup);
00786
00787
00788
00789 if (ctx.disable_dpb)
00790 {
00791 ret = ctx.dec->disableDPB();
00792 TEST_ERROR(ret < 0, "Error in disableDPB", cleanup);
00793 }
00794
00795
00796
00797 ret = ctx.dec->output_plane.setupPlane(V4L2_MEMORY_MMAP, 10, true, false);
00798 TEST_ERROR(ret < 0, "Error while setting up output plane", cleanup);
00799
00800
00801
00802
00803 ctx.conv = NvVideoConverter::createVideoConverter("conv0");
00804 TEST_ERROR(!ctx.conv, "Could not create video converter", cleanup);
00805 ctx.conv->output_plane.setDQThreadCallback(conv0_outputDqbufThreadCallback);
00806 ctx.conv->capture_plane.setDQThreadCallback(conv0_captureDqbufThreadCallback);
00807
00808
00809 ctx.gie_ctx->buildGieContext(ctx.deployfile, ctx.modelfile);
00810 pthread_create(&ctx.gie_thread_handle, NULL, gieThread, &ctx);
00811
00812
00813 ret = ctx.dec->output_plane.setStreamStatus(true);
00814 TEST_ERROR(ret < 0, "Error in output plane stream on", cleanup);
00815 pthread_create(&ctx.dec_capture_loop, NULL, decCaptureLoop, &ctx);
00816
00817
00818
00819
00820 i = 0;
00821 while (!eos && !ctx.got_error && !ctx.dec->isInError() &&
00822 i < ctx.dec->output_plane.getNumBuffers())
00823 {
00824 struct v4l2_buffer v4l2_buf;
00825 struct v4l2_plane planes[MAX_PLANES];
00826 NvBuffer *buffer;
00827
00828 memset(&v4l2_buf, 0, sizeof(v4l2_buf));
00829 memset(planes, 0, sizeof(planes));
00830
00831 buffer = ctx.dec->output_plane.getNthBuffer(i);
00832 read_decoder_input_chunk(ctx.in_file, buffer);
00833
00834 v4l2_buf.index = i;
00835 v4l2_buf.m.planes = planes;
00836 v4l2_buf.m.planes[0].bytesused = buffer->planes[0].bytesused;
00837
00838
00839
00840 ret = ctx.dec->output_plane.qBuffer(v4l2_buf, NULL);
00841 if (ret < 0)
00842 {
00843 cerr << "Error Qing buffer at output plane" << endl;
00844 abort(&ctx);
00845 break;
00846 }
00847 if (v4l2_buf.m.planes[0].bytesused == 0)
00848 {
00849 eos = true;
00850 cout << "Input file read complete" << endl;
00851 break;
00852 }
00853 i++;
00854 }
00855
00856
00857
00858
00859 while (!eos && !ctx.got_error && !ctx.dec->isInError())
00860 {
00861 struct v4l2_buffer v4l2_buf;
00862 struct v4l2_plane planes[MAX_PLANES];
00863 NvBuffer *buffer;
00864
00865 memset(&v4l2_buf, 0, sizeof(v4l2_buf));
00866 memset(planes, 0, sizeof(planes));
00867
00868 v4l2_buf.m.planes = planes;
00869
00870 ret = ctx.dec->output_plane.dqBuffer(v4l2_buf, &buffer, NULL, -1);
00871 if (ret < 0)
00872 {
00873 cerr << "Error DQing buffer at output plane" << endl;
00874 abort(&ctx);
00875 break;
00876 }
00877
00878 read_decoder_input_chunk(ctx.in_file, buffer);
00879
00880 v4l2_buf.m.planes[0].bytesused = buffer->planes[0].bytesused;
00881 ret = ctx.dec->output_plane.qBuffer(v4l2_buf, NULL);
00882 if (ret < 0)
00883 {
00884 cerr << "Error Qing buffer at output plane" << endl;
00885 abort(&ctx);
00886 break;
00887 }
00888 if (v4l2_buf.m.planes[0].bytesused == 0)
00889 {
00890 eos = true;
00891 cout << "Input file read complete" << endl;
00892 break;
00893 }
00894 }
00895
00896
00897
00898
00899 while (ctx.dec->output_plane.getNumQueuedBuffers() > 0 &&
00900 !ctx.got_error && !ctx.dec->isInError())
00901 {
00902 struct v4l2_buffer v4l2_buf;
00903 struct v4l2_plane planes[MAX_PLANES];
00904
00905 memset(&v4l2_buf, 0, sizeof(v4l2_buf));
00906 memset(planes, 0, sizeof(planes));
00907
00908 v4l2_buf.m.planes = planes;
00909 ret = ctx.dec->output_plane.dqBuffer(v4l2_buf, NULL, NULL, -1);
00910 if (ret < 0)
00911 {
00912 cerr << "Error DQing buffer at output plane" << endl;
00913 abort(&ctx);
00914 break;
00915 }
00916 }
00917
00918 cleanup:
00919
00920 ctx.got_eos = true;
00921 if (ctx.dec_capture_loop)
00922 {
00923 pthread_join(ctx.dec_capture_loop, NULL);
00924 }
00925
00926 if (ctx.gie_stop == 0)
00927 {
00928 ctx.gie_stop = 1;
00929 pthread_cond_broadcast(&ctx.gie_cond);
00930 pthread_join(ctx.gie_thread_handle, NULL);
00931 }
00932
00933
00934 if (ctx.conv)
00935 {
00936 if (sendEOStoConverter(&ctx) < 0)
00937 {
00938 cerr << "Error while queueing EOS buffer on converter output"
00939 << endl;
00940 }
00941 ctx.conv->capture_plane.waitForDQThread(-1);
00942 }
00943
00944 if (ctx.dec && ctx.dec->isInError())
00945 {
00946 cerr << "Decoder is in error" << endl;
00947 error = 1;
00948 }
00949 if (ctx.got_error)
00950 {
00951 error = 1;
00952 }
00953
00954
00955
00956
00957 delete ctx.dec;
00958 delete ctx.conv;
00959
00960
00961
00962 delete ctx.in_file;
00963 delete ctx.conv_output_plane_buf_queue;
00964 delete []nalu_parse_buffer;
00965
00966 free(ctx.in_file_path);
00967
00968 delete ctx.gie_buf_queue;
00969 ctx.gie_ctx->destroyGieContext();
00970 delete ctx.gie_ctx;
00971
00972 if (error)
00973 {
00974 cout << "App run failed" << endl;
00975 }
00976 else
00977 {
00978 cout << "App run was successful" << endl;
00979 }
00980 return -error;
00981 }