video_decode_main.cpp 75 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186
  1. /*
  2. * Copyright (c) 2016-2020, NVIDIA CORPORATION. All rights reserved.
  3. *
  4. * Redistribution and use in source and binary forms, with or without
  5. * modification, are permitted provided that the following conditions
  6. * are met:
  7. * * Redistributions of source code must retain the above copyright
  8. * notice, this list of conditions and the following disclaimer.
  9. * * Redistributions in binary form must reproduce the above copyright
  10. * notice, this list of conditions and the following disclaimer in the
  11. * documentation and/or other materials provided with the distribution.
  12. * * Neither the name of NVIDIA CORPORATION nor the names of its
  13. * contributors may be used to endorse or promote products derived
  14. * from this software without specific prior written permission.
  15. *
  16. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
  17. * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  18. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
  19. * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
  20. * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
  21. * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
  22. * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
  23. * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
  24. * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  25. * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  26. * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  27. */
  28. #include "NvApplicationProfiler.h"
  29. #include "NvUtils.h"
  30. #include <errno.h>
  31. #include <fstream>
  32. #include <iostream>
  33. #include <linux/videodev2.h>
  34. #include <malloc.h>
  35. #include <pthread.h>
  36. #include <string.h>
  37. #include <unistd.h>
  38. #include <fcntl.h>
  39. #include <poll.h>
  40. #include <nvbuf_utils.h>
  41. #include "video_decode.h"
  42. #include "nvbuf_utils.h"
  43. #define TEST_ERROR(cond, str, label) if(cond) { \
  44. cerr << str << endl; \
  45. error = 1; \
  46. goto label; }
  47. #define MICROSECOND_UNIT 1000000
  48. #define CHUNK_SIZE 4000000
  49. #define MIN(a,b) (((a) < (b)) ? (a) : (b))
  50. #define IS_NAL_UNIT_START(buffer_ptr) (!buffer_ptr[0] && !buffer_ptr[1] && \
  51. !buffer_ptr[2] && (buffer_ptr[3] == 1))
  52. #define IS_NAL_UNIT_START1(buffer_ptr) (!buffer_ptr[0] && !buffer_ptr[1] && \
  53. (buffer_ptr[2] == 1))
  54. #define H264_NAL_UNIT_CODED_SLICE 1
  55. #define H264_NAL_UNIT_CODED_SLICE_IDR 5
  56. #define HEVC_NUT_TRAIL_N 0
  57. #define HEVC_NUT_RASL_R 9
  58. #define HEVC_NUT_BLA_W_LP 16
  59. #define HEVC_NUT_CRA_NUT 21
  60. #define IVF_FILE_HDR_SIZE 32
  61. #define IVF_FRAME_HDR_SIZE 12
  62. #define IS_H264_NAL_CODED_SLICE(buffer_ptr) ((buffer_ptr[0] & 0x1F) == H264_NAL_UNIT_CODED_SLICE)
  63. #define IS_H264_NAL_CODED_SLICE_IDR(buffer_ptr) ((buffer_ptr[0] & 0x1F) == H264_NAL_UNIT_CODED_SLICE_IDR)
  64. #define GET_H265_NAL_UNIT_TYPE(buffer_ptr) ((buffer_ptr[0] & 0x7E) >> 1)
  65. using namespace std;
  66. /**
  67. * Read the input NAL unit for h264/H265/Mpeg2/Mpeg4 decoder.
  68. *
  69. * @param stream : Input stream
  70. * @param buffer : NvBuffer pointer
  71. * @param parse_buffer : parse buffer pointer
  72. * @param parse_buffer_size : chunk size
  73. * @param ctx : Decoder context
  74. */
  75. static int
  76. read_decoder_input_nalu(ifstream * stream, NvBuffer * buffer,
  77. char *parse_buffer, streamsize parse_buffer_size, context_t * ctx)
  78. {
  79. /* Length is the size of the buffer in bytes. */
  80. char *buffer_ptr = (char *) buffer->planes[0].data;
  81. int h265_nal_unit_type;
  82. char *stream_ptr;
  83. bool nalu_found = false;
  84. streamsize bytes_read;
  85. streamsize stream_initial_pos = stream->tellg();
  86. stream->read(parse_buffer, parse_buffer_size);
  87. bytes_read = stream->gcount();
  88. if (bytes_read == 0)
  89. {
  90. return buffer->planes[0].bytesused = 0;
  91. }
  92. /* Find the first NAL unit in the buffer. */
  93. stream_ptr = parse_buffer;
  94. while ((stream_ptr - parse_buffer) < (bytes_read - 3))
  95. {
  96. nalu_found = IS_NAL_UNIT_START(stream_ptr) ||
  97. IS_NAL_UNIT_START1(stream_ptr);
  98. if (nalu_found)
  99. {
  100. break;
  101. }
  102. stream_ptr++;
  103. }
  104. /* Reached end of buffer but could not find NAL unit. */
  105. if (!nalu_found)
  106. {
  107. cerr << "Could not read nal unit from file. EOF or file corrupted"
  108. << endl;
  109. return -1;
  110. }
  111. memcpy(buffer_ptr, stream_ptr, 4);
  112. buffer_ptr += 4;
  113. buffer->planes[0].bytesused = 4;
  114. stream_ptr += 4;
  115. if (ctx->copy_timestamp)
  116. {
  117. if (ctx->decoder_pixfmt == V4L2_PIX_FMT_H264) {
  118. if ((IS_H264_NAL_CODED_SLICE(stream_ptr)) ||
  119. (IS_H264_NAL_CODED_SLICE_IDR(stream_ptr)))
  120. ctx->flag_copyts = true;
  121. else
  122. ctx->flag_copyts = false;
  123. } else if (ctx->decoder_pixfmt == V4L2_PIX_FMT_H265) {
  124. h265_nal_unit_type = GET_H265_NAL_UNIT_TYPE(stream_ptr);
  125. if ((h265_nal_unit_type >= HEVC_NUT_TRAIL_N && h265_nal_unit_type <= HEVC_NUT_RASL_R) ||
  126. (h265_nal_unit_type >= HEVC_NUT_BLA_W_LP && h265_nal_unit_type <= HEVC_NUT_CRA_NUT))
  127. ctx->flag_copyts = true;
  128. else
  129. ctx->flag_copyts = false;
  130. }
  131. }
  132. /* Copy bytes till the next NAL unit is found. */
  133. while ((stream_ptr - parse_buffer) < (bytes_read - 3))
  134. {
  135. if (IS_NAL_UNIT_START(stream_ptr) || IS_NAL_UNIT_START1(stream_ptr))
  136. {
  137. streamsize seekto = stream_initial_pos +
  138. (stream_ptr - parse_buffer);
  139. if(stream->eof())
  140. {
  141. stream->clear();
  142. }
  143. stream->seekg(seekto, stream->beg);
  144. return 0;
  145. }
  146. *buffer_ptr = *stream_ptr;
  147. buffer_ptr++;
  148. stream_ptr++;
  149. buffer->planes[0].bytesused++;
  150. }
  151. /* Reached end of buffer but could not find NAL unit. */
  152. cerr << "Could not read nal unit from file. EOF or file corrupted"
  153. << endl;
  154. return -1;
  155. }
  156. /**
  157. * Read the input chunks for h264/H265/Mpeg2/Mpeg4 decoder.
  158. *
  159. * @param stream : Input stream
  160. * @param buffer : NvBuffer pointer
  161. */
  162. static int
  163. read_decoder_input_chunk(ifstream * stream, NvBuffer * buffer)
  164. {
  165. /* Length is the size of the buffer in bytes */
  166. streamsize bytes_to_read = MIN(CHUNK_SIZE, buffer->planes[0].length);
  167. stream->read((char *) buffer->planes[0].data, bytes_to_read);
  168. /* NOTE: It is necessary to set bytesused properly, so that decoder knows how
  169. many bytes in the buffer are valid. */
  170. buffer->planes[0].bytesused = stream->gcount();
  171. if(buffer->planes[0].bytesused == 0)
  172. {
  173. stream->clear();
  174. stream->seekg(0,stream->beg);
  175. }
  176. return 0;
  177. }
  178. /**
  179. * Read the input chunks for Vp8/Vp9 decoder.
  180. *
  181. * @param ctx : Decoder context
  182. * @param buffer : NvBuffer pointer
  183. */
  184. static int
  185. read_vpx_decoder_input_chunk(context_t *ctx, NvBuffer * buffer)
  186. {
  187. ifstream *stream = ctx->in_file[0];
  188. int Framesize;
  189. unsigned char *bitstreambuffer = (unsigned char *)buffer->planes[0].data;
  190. if (ctx->vp9_file_header_flag == 0)
  191. {
  192. stream->read((char *) buffer->planes[0].data, IVF_FILE_HDR_SIZE);
  193. if (stream->gcount() != IVF_FILE_HDR_SIZE)
  194. {
  195. cerr << "Couldn't read IVF FILE HEADER" << endl;
  196. return -1;
  197. }
  198. if (!((bitstreambuffer[0] == 'D') && (bitstreambuffer[1] == 'K') &&
  199. (bitstreambuffer[2] == 'I') && (bitstreambuffer[3] == 'F')))
  200. {
  201. cerr << "It's not a valid IVF file \n" << endl;
  202. return -1;
  203. }
  204. cout << "It's a valid IVF file" << endl;
  205. ctx->vp9_file_header_flag = 1;
  206. }
  207. stream->read((char *) buffer->planes[0].data, IVF_FRAME_HDR_SIZE);
  208. if (!stream->gcount())
  209. {
  210. cout << "End of stream" << endl;
  211. return 0;
  212. }
  213. if (stream->gcount() != IVF_FRAME_HDR_SIZE)
  214. {
  215. cerr << "Couldn't read IVF FRAME HEADER" << endl;
  216. return -1;
  217. }
  218. Framesize = (bitstreambuffer[3]<<24) + (bitstreambuffer[2]<<16) +
  219. (bitstreambuffer[1]<<8) + bitstreambuffer[0];
  220. buffer->planes[0].bytesused = Framesize;
  221. stream->read((char *) buffer->planes[0].data, Framesize);
  222. if (stream->gcount() != Framesize)
  223. {
  224. cerr << "Couldn't read Framesize" << endl;
  225. return -1;
  226. }
  227. return 0;
  228. }
  229. /**
  230. * Exit on error.
  231. *
  232. * @param ctx : Decoder context
  233. */
  234. static void
  235. abort(context_t *ctx)
  236. {
  237. ctx->got_error = true;
  238. ctx->dec->abort();
  239. #ifndef USE_NVBUF_TRANSFORM_API
  240. if (ctx->conv)
  241. {
  242. ctx->conv->abort();
  243. pthread_cond_broadcast(&ctx->queue_cond);
  244. }
  245. #endif
  246. }
  247. #ifndef USE_NVBUF_TRANSFORM_API
  248. /**
  249. * converter output-plane deque buffer callback function.
  250. *
  251. * @param v4l2_buf : v4l2 buffer
  252. * @param buffer : NvBuffer pointer
  253. * @param shared_buffer : shared NvBuffer pointer
  254. * @param ctx : Decoder context
  255. * @param arg : context pointer
  256. */
  257. static bool
  258. conv0_output_dqbuf_thread_callback(struct v4l2_buffer *v4l2_buf,
  259. NvBuffer * buffer, NvBuffer * shared_buffer,
  260. void *arg)
  261. {
  262. context_t *ctx = (context_t *) arg;
  263. struct v4l2_buffer dec_capture_ret_buffer;
  264. struct v4l2_plane planes[MAX_PLANES];
  265. if (!v4l2_buf)
  266. {
  267. cerr << "Error while dequeueing conv output plane buffer" << endl;
  268. abort(ctx);
  269. return false;
  270. }
  271. if (v4l2_buf->m.planes[0].bytesused == 0)
  272. {
  273. return false;
  274. }
  275. memset(&dec_capture_ret_buffer, 0, sizeof(dec_capture_ret_buffer));
  276. memset(planes, 0, sizeof(planes));
  277. dec_capture_ret_buffer.index = shared_buffer->index;
  278. dec_capture_ret_buffer.m.planes = planes;
  279. if (ctx->capture_plane_mem_type == V4L2_MEMORY_DMABUF)
  280. dec_capture_ret_buffer.m.planes[0].m.fd =
  281. ctx->dmabuff_fd[shared_buffer->index];
  282. pthread_mutex_lock(&ctx->queue_lock);
  283. ctx->conv_output_plane_buf_queue->push(buffer);
  284. /* Return the buffer dequeued from converter output plane
  285. back to decoder capture plane. */
  286. if (ctx->dec->capture_plane.qBuffer(dec_capture_ret_buffer, NULL) < 0)
  287. {
  288. abort(ctx);
  289. return false;
  290. }
  291. pthread_cond_broadcast(&ctx->queue_cond);
  292. pthread_mutex_unlock(&ctx->queue_lock);
  293. return true;
  294. }
  295. /**
  296. * converter capture-plane deque buffer callback function.
  297. *
  298. * @param v4l2_buf : v4l2 buffer
  299. * @param buffer : NvBuffer
  300. * @param shared_buffer : shared NvBuffer
  301. * @param arg : context pointer
  302. */
  303. static bool
  304. conv0_capture_dqbuf_thread_callback(struct v4l2_buffer *v4l2_buf,
  305. NvBuffer * buffer, NvBuffer * shared_buffer,
  306. void *arg)
  307. {
  308. context_t *ctx = (context_t *) arg;
  309. if (!v4l2_buf)
  310. {
  311. cerr << "Error while dequeueing conv capture plane buffer" << endl;
  312. abort(ctx);
  313. return false;
  314. }
  315. if (v4l2_buf->m.planes[0].bytesused == 0)
  316. {
  317. return false;
  318. }
  319. /* Write raw video frame to file. */
  320. if (!ctx->stats && ctx->out_file)
  321. {
  322. write_video_frame(ctx->out_file, *buffer);
  323. }
  324. /* Render converted video. */
  325. if (!ctx->stats && !ctx->disable_rendering)
  326. {
  327. ctx->renderer->render(buffer->planes[0].fd);
  328. }
  329. /* Return the buffer to converter capture plane. */
  330. if (ctx->conv->capture_plane.qBuffer(*v4l2_buf, NULL) < 0)
  331. {
  332. return false;
  333. }
  334. return true;
  335. }
  336. #endif
  337. /**
  338. * Report decoder input header error metadata.
  339. *
  340. * @param ctx : Decoder context
  341. * @param input_metadata : Pointer to decoder input header error metadata struct
  342. */
  343. static int
  344. report_input_metadata(context_t *ctx, v4l2_ctrl_videodec_inputbuf_metadata *input_metadata)
  345. {
  346. int ret = -1;
  347. uint32_t frame_num = ctx->dec->output_plane.getTotalDequeuedBuffers() - 1;
  348. /* NOTE: Bits represent types of error as defined with v4l2_videodec_input_error_type. */
  349. if (input_metadata->nBitStreamError & V4L2_DEC_ERROR_SPS) {
  350. cout << "Frame " << frame_num << " BitStreamError : ERROR_SPS " << endl;
  351. } else if (input_metadata->nBitStreamError & V4L2_DEC_ERROR_PPS) {
  352. cout << "Frame " << frame_num << " BitStreamError : ERROR_PPS " << endl;
  353. } else if (input_metadata->nBitStreamError & V4L2_DEC_ERROR_SLICE_HDR) {
  354. cout << "Frame " << frame_num << " BitStreamError : ERROR_SLICE_HDR " << endl;
  355. } else if (input_metadata->nBitStreamError & V4L2_DEC_ERROR_MISSING_REF_FRAME) {
  356. cout << "Frame " << frame_num << " BitStreamError : ERROR_MISSING_REF_FRAME " << endl;
  357. } else if (input_metadata->nBitStreamError & V4L2_DEC_ERROR_VPS) {
  358. cout << "Frame " << frame_num << " BitStreamError : ERROR_VPS " << endl;
  359. } else {
  360. cout << "Frame " << frame_num << " BitStreamError : ERROR_None " << endl;
  361. ret = 0;
  362. }
  363. return ret;
  364. }
  365. /**
  366. * Report decoder output metadata.
  367. *
  368. * @param ctx : Decoder context
  369. * @param metadata : Pointer to decoder output metadata struct
  370. */
  371. static void
  372. report_metadata(context_t *ctx, v4l2_ctrl_videodec_outputbuf_metadata *metadata)
  373. {
  374. uint32_t frame_num = ctx->dec->capture_plane.getTotalDequeuedBuffers() - 1;
  375. cout << "Frame " << frame_num << endl;
  376. if (metadata->bValidFrameStatus)
  377. {
  378. if (ctx->decoder_pixfmt == V4L2_PIX_FMT_H264)
  379. {
  380. /* metadata for H264 input stream. */
  381. switch(metadata->CodecParams.H264DecParams.FrameType)
  382. {
  383. case 0:
  384. cout << "FrameType = B" << endl;
  385. break;
  386. case 1:
  387. cout << "FrameType = P" << endl;
  388. break;
  389. case 2:
  390. cout << "FrameType = I";
  391. if (metadata->CodecParams.H264DecParams.dpbInfo.currentFrame.bIdrFrame)
  392. {
  393. cout << " (IDR)";
  394. }
  395. cout << endl;
  396. break;
  397. }
  398. cout << "nActiveRefFrames = " << metadata->CodecParams.H264DecParams.dpbInfo.nActiveRefFrames << endl;
  399. }
  400. if (ctx->decoder_pixfmt == V4L2_PIX_FMT_H265)
  401. {
  402. /* metadata for HEVC input stream. */
  403. switch(metadata->CodecParams.HEVCDecParams.FrameType)
  404. {
  405. case 0:
  406. cout << "FrameType = B" << endl;
  407. break;
  408. case 1:
  409. cout << "FrameType = P" << endl;
  410. break;
  411. case 2:
  412. cout << "FrameType = I";
  413. if (metadata->CodecParams.HEVCDecParams.dpbInfo.currentFrame.bIdrFrame)
  414. {
  415. cout << " (IDR)";
  416. }
  417. cout << endl;
  418. break;
  419. }
  420. cout << "nActiveRefFrames = " << metadata->CodecParams.HEVCDecParams.dpbInfo.nActiveRefFrames << endl;
  421. }
  422. if (metadata->FrameDecStats.DecodeError)
  423. {
  424. /* decoder error status metadata. */
  425. v4l2_ctrl_videodec_statusmetadata *dec_stats =
  426. &metadata->FrameDecStats;
  427. cout << "ErrorType=" << dec_stats->DecodeError << " Decoded MBs=" <<
  428. dec_stats->DecodedMBs << " Concealed MBs=" <<
  429. dec_stats->ConcealedMBs << endl;
  430. }
  431. }
  432. else
  433. {
  434. cout << "No valid metadata for frame" << endl;
  435. }
  436. }
  437. #ifndef USE_NVBUF_TRANSFORM_API
  438. /**
  439. * Send EndOfStream for converter.
  440. *
  441. * @param ctx : Decoder context
  442. */
  443. static int
  444. sendEOStoConverter(context_t *ctx)
  445. {
  446. /* Check if converter is running. */
  447. if (ctx->conv->output_plane.getStreamStatus())
  448. {
  449. NvBuffer *conv_buffer;
  450. struct v4l2_buffer v4l2_buf;
  451. struct v4l2_plane planes[MAX_PLANES];
  452. memset(&v4l2_buf, 0, sizeof(v4l2_buf));
  453. memset(&planes, 0, sizeof(planes));
  454. v4l2_buf.m.planes = planes;
  455. pthread_mutex_lock(&ctx->queue_lock);
  456. /* Wait till converter output buffer queue is empty. */
  457. while (ctx->conv_output_plane_buf_queue->empty())
  458. {
  459. pthread_cond_wait(&ctx->queue_cond, &ctx->queue_lock);
  460. }
  461. conv_buffer = ctx->conv_output_plane_buf_queue->front();
  462. ctx->conv_output_plane_buf_queue->pop();
  463. pthread_mutex_unlock(&ctx->queue_lock);
  464. v4l2_buf.index = conv_buffer->index;
  465. /* Enqueue EOS buffer on converter output plane. */
  466. return ctx->conv->output_plane.qBuffer(v4l2_buf, NULL);
  467. }
  468. return 0;
  469. }
  470. #endif
  471. /**
  472. * Query and Set Capture plane.
  473. *
  474. * @param ctx : Decoder context
  475. */
  476. static void
  477. query_and_set_capture(context_t * ctx)
  478. {
  479. NvVideoDecoder *dec = ctx->dec;
  480. struct v4l2_format format;
  481. struct v4l2_crop crop;
  482. int32_t min_dec_capture_buffers;
  483. int ret = 0;
  484. int error = 0;
  485. uint32_t window_width;
  486. uint32_t window_height;
  487. NvBufferCreateParams input_params = {0};
  488. NvBufferCreateParams cParams = {0};
  489. /* Get capture plane format from the decoder.
  490. This may change after resolution change event.
  491. Refer ioctl VIDIOC_G_FMT */
  492. ret = dec->capture_plane.getFormat(format);
  493. TEST_ERROR(ret < 0,
  494. "Error: Could not get format from decoder capture plane", error);
  495. /* Get the display resolution from the decoder.
  496. Refer ioctl VIDIOC_G_CROP */
  497. ret = dec->capture_plane.getCrop(crop);
  498. TEST_ERROR(ret < 0,
  499. "Error: Could not get crop from decoder capture plane", error);
  500. cout << "Video Resolution: " << crop.c.width << "x" << crop.c.height
  501. << endl;
  502. ctx->display_height = crop.c.height;
  503. ctx->display_width = crop.c.width;
  504. #ifdef USE_NVBUF_TRANSFORM_API
  505. if(ctx->dst_dma_fd != -1)
  506. {
  507. NvBufferDestroy(ctx->dst_dma_fd);
  508. ctx->dst_dma_fd = -1;
  509. }
  510. /* Create PitchLinear output buffer for transform. */
  511. input_params.payloadType = NvBufferPayload_SurfArray;
  512. input_params.width = crop.c.width;
  513. input_params.height = crop.c.height;
  514. input_params.layout = NvBufferLayout_Pitch;
  515. if (ctx->out_pixfmt == 1)
  516. input_params.colorFormat = NvBufferColorFormat_NV12;
  517. else if (ctx->out_pixfmt == 2)
  518. input_params.colorFormat = NvBufferColorFormat_YUV420;
  519. else if (ctx->out_pixfmt == 3)
  520. input_params.colorFormat = NvBufferColorFormat_NV16;
  521. else if (ctx->out_pixfmt == 4)
  522. input_params.colorFormat = NvBufferColorFormat_NV24;
  523. input_params.nvbuf_tag = NvBufferTag_VIDEO_CONVERT;
  524. ret = NvBufferCreateEx (&ctx->dst_dma_fd, &input_params);
  525. TEST_ERROR(ret == -1, "create dmabuf failed", error);
  526. #else
  527. /* For file write, first deinitialize output and capture planes
  528. of video converter and then use the new resolution from
  529. decoder event resolution change. */
  530. if (ctx->conv)
  531. {
  532. ret = sendEOStoConverter(ctx);
  533. TEST_ERROR(ret < 0,
  534. "Error while queueing EOS buffer on converter output",
  535. error);
  536. ctx->conv->capture_plane.waitForDQThread(2000);
  537. ctx->conv->output_plane.deinitPlane();
  538. ctx->conv->capture_plane.deinitPlane();
  539. while(!ctx->conv_output_plane_buf_queue->empty())
  540. {
  541. ctx->conv_output_plane_buf_queue->pop();
  542. }
  543. }
  544. #endif
  545. if (!ctx->disable_rendering)
  546. {
  547. /* Destroy the old instance of renderer as resolution might have changed. */
  548. delete ctx->renderer;
  549. if (ctx->fullscreen)
  550. {
  551. /* Required for fullscreen. */
  552. window_width = window_height = 0;
  553. }
  554. else if (ctx->window_width && ctx->window_height)
  555. {
  556. /* As specified by user on commandline. */
  557. window_width = ctx->window_width;
  558. window_height = ctx->window_height;
  559. }
  560. else
  561. {
  562. /* Resolution got from the decoder. */
  563. window_width = crop.c.width;
  564. window_height = crop.c.height;
  565. }
  566. /* If height or width are set to zero, EglRenderer creates a fullscreen
  567. window for rendering. */
  568. ctx->renderer =
  569. NvEglRenderer::createEglRenderer("renderer0", window_width,
  570. window_height, ctx->window_x,
  571. ctx->window_y);
  572. TEST_ERROR(!ctx->renderer,
  573. "Error in setting up renderer. "
  574. "Check if X is running or run with --disable-rendering",
  575. error);
  576. if (ctx->stats)
  577. {
  578. /* Enable profiling for renderer if stats are requested. */
  579. ctx->renderer->enableProfiling();
  580. }
  581. /* Set fps for rendering. */
  582. ctx->renderer->setFPS(ctx->fps);
  583. }
  584. /* deinitPlane unmaps the buffers and calls REQBUFS with count 0 */
  585. dec->capture_plane.deinitPlane();
  586. if(ctx->capture_plane_mem_type == V4L2_MEMORY_DMABUF)
  587. {
  588. for(int index = 0 ; index < ctx->numCapBuffers ; index++)
  589. {
  590. if(ctx->dmabuff_fd[index] != 0)
  591. {
  592. ret = NvBufferDestroy (ctx->dmabuff_fd[index]);
  593. TEST_ERROR(ret < 0, "Failed to Destroy NvBuffer", error);
  594. }
  595. }
  596. }
  597. /* Not necessary to call VIDIOC_S_FMT on decoder capture plane.
  598. But decoder setCapturePlaneFormat function updates the class variables */
  599. ret = dec->setCapturePlaneFormat(format.fmt.pix_mp.pixelformat,
  600. format.fmt.pix_mp.width,
  601. format.fmt.pix_mp.height);
  602. TEST_ERROR(ret < 0, "Error in setting decoder capture plane format", error);
  603. ctx->video_height = format.fmt.pix_mp.height;
  604. ctx->video_width = format.fmt.pix_mp.width;
  605. /* Get the minimum buffers which have to be requested on the capture plane. */
  606. ret = dec->getMinimumCapturePlaneBuffers(min_dec_capture_buffers);
  607. TEST_ERROR(ret < 0,
  608. "Error while getting value of minimum capture plane buffers",
  609. error);
  610. /* Request (min + extra) buffers, export and map buffers. */
  611. if(ctx->capture_plane_mem_type == V4L2_MEMORY_MMAP)
  612. {
  613. /* Request, Query and export decoder capture plane buffers.
  614. Refer ioctl VIDIOC_REQBUFS, VIDIOC_QUERYBUF and VIDIOC_EXPBUF */
  615. ret =
  616. dec->capture_plane.setupPlane(V4L2_MEMORY_MMAP,
  617. min_dec_capture_buffers + ctx->extra_cap_plane_buffer, false,
  618. false);
  619. TEST_ERROR(ret < 0, "Error in decoder capture plane setup", error);
  620. }
  621. else if(ctx->capture_plane_mem_type == V4L2_MEMORY_DMABUF)
  622. {
  623. /* Set colorformats for relevant colorspaces. */
  624. switch(format.fmt.pix_mp.colorspace)
  625. {
  626. case V4L2_COLORSPACE_SMPTE170M:
  627. if (format.fmt.pix_mp.quantization == V4L2_QUANTIZATION_DEFAULT)
  628. {
  629. cout << "Decoder colorspace ITU-R BT.601 with standard range luma (16-235)" << endl;
  630. cParams.colorFormat = NvBufferColorFormat_NV12;
  631. }
  632. else
  633. {
  634. cout << "Decoder colorspace ITU-R BT.601 with extended range luma (0-255)" << endl;
  635. cParams.colorFormat = NvBufferColorFormat_NV12_ER;
  636. }
  637. break;
  638. case V4L2_COLORSPACE_REC709:
  639. if (format.fmt.pix_mp.quantization == V4L2_QUANTIZATION_DEFAULT)
  640. {
  641. cout << "Decoder colorspace ITU-R BT.709 with standard range luma (16-235)" << endl;
  642. cParams.colorFormat = NvBufferColorFormat_NV12_709;
  643. }
  644. else
  645. {
  646. cout << "Decoder colorspace ITU-R BT.709 with extended range luma (0-255)" << endl;
  647. cParams.colorFormat = NvBufferColorFormat_NV12_709_ER;
  648. }
  649. break;
  650. case V4L2_COLORSPACE_BT2020:
  651. {
  652. cout << "Decoder colorspace ITU-R BT.2020" << endl;
  653. cParams.colorFormat = NvBufferColorFormat_NV12_2020;
  654. }
  655. break;
  656. default:
  657. cout << "supported colorspace details not available, use default" << endl;
  658. if (format.fmt.pix_mp.quantization == V4L2_QUANTIZATION_DEFAULT)
  659. {
  660. cout << "Decoder colorspace ITU-R BT.601 with standard range luma (16-235)" << endl;
  661. cParams.colorFormat = NvBufferColorFormat_NV12;
  662. }
  663. else
  664. {
  665. cout << "Decoder colorspace ITU-R BT.601 with extended range luma (0-255)" << endl;
  666. cParams.colorFormat = NvBufferColorFormat_NV12_ER;
  667. }
  668. break;
  669. }
  670. ctx->numCapBuffers = min_dec_capture_buffers + ctx->extra_cap_plane_buffer;
  671. /* Create decoder capture plane buffers. */
  672. for (int index = 0; index < ctx->numCapBuffers; index++)
  673. {
  674. cParams.width = crop.c.width;
  675. cParams.height = crop.c.height;
  676. cParams.layout = NvBufferLayout_BlockLinear;
  677. cParams.payloadType = NvBufferPayload_SurfArray;
  678. cParams.nvbuf_tag = NvBufferTag_VIDEO_DEC;
  679. ret = NvBufferCreateEx(&ctx->dmabuff_fd[index], &cParams);
  680. TEST_ERROR(ret < 0, "Failed to create buffers", error);
  681. }
  682. /* Request buffers on decoder capture plane.
  683. Refer ioctl VIDIOC_REQBUFS */
  684. ret = dec->capture_plane.reqbufs(V4L2_MEMORY_DMABUF,ctx->numCapBuffers);
  685. TEST_ERROR(ret, "Error in request buffers on capture plane", error);
  686. }
  687. #ifndef USE_NVBUF_TRANSFORM_API
  688. if (ctx->conv)
  689. {
  690. /* Set Converter output plane format.
  691. Refer ioctl VIDIOC_S_FMT */
  692. ret = ctx->conv->setOutputPlaneFormat(format.fmt.pix_mp.pixelformat,
  693. format.fmt.pix_mp.width,
  694. format.fmt.pix_mp.height,
  695. V4L2_NV_BUFFER_LAYOUT_BLOCKLINEAR);
  696. TEST_ERROR(ret < 0, "Error in converter output plane set format",
  697. error);
  698. /* Set Converter capture plane format.
  699. Refer ioctl VIDIOC_S_FMT */
  700. ret = ctx->conv->setCapturePlaneFormat((ctx->out_pixfmt == 1 ?
  701. V4L2_PIX_FMT_NV12M :
  702. V4L2_PIX_FMT_YUV420M),
  703. crop.c.width,
  704. crop.c.height,
  705. V4L2_NV_BUFFER_LAYOUT_PITCH);
  706. TEST_ERROR(ret < 0, "Error in converter capture plane set format",
  707. error);
  708. /* Set Converter crop rectangle. */
  709. ret = ctx->conv->setCropRect(0, 0, crop.c.width, crop.c.height);
  710. TEST_ERROR(ret < 0, "Error while setting crop rect", error);
  711. if (ctx->rescale_method) {
  712. /* Rescale full range [0-255] to limited range [16-235].
  713. Refer V4L2_CID_VIDEO_CONVERT_YUV_RESCALE_METHOD */
  714. ret = ctx->conv->setYUVRescale(ctx->rescale_method);
  715. TEST_ERROR(ret < 0, "Error while setting YUV rescale", error);
  716. }
  717. /* Request buffers on converter output plane.
  718. Refer ioctl VIDIOC_REQBUFS */
  719. ret =
  720. ctx->conv->output_plane.setupPlane(V4L2_MEMORY_DMABUF,
  721. dec->capture_plane.
  722. getNumBuffers(), false, false);
  723. TEST_ERROR(ret < 0, "Error in converter output plane setup", error);
  724. /* Request, Query and export converter capture plane buffers.
  725. Refer ioctl VIDIOC_REQBUFS, VIDIOC_QUERYBUF and VIDIOC_EXPBUF */
  726. ret =
  727. ctx->conv->capture_plane.setupPlane(V4L2_MEMORY_MMAP,
  728. dec->capture_plane.
  729. getNumBuffers(), true, false);
  730. TEST_ERROR(ret < 0, "Error in converter capture plane setup", error);
  731. /* Converter output plane STREAMON.
  732. Refer ioctl VIDIOC_STREAMON */
  733. ret = ctx->conv->output_plane.setStreamStatus(true);
  734. TEST_ERROR(ret < 0, "Error in converter output plane streamon", error);
  735. /* Converter capture plane STREAMON.
  736. Refer ioctl VIDIOC_STREAMON */
  737. ret = ctx->conv->capture_plane.setStreamStatus(true);
  738. TEST_ERROR(ret < 0, "Error in converter output plane streamoff", error);
  739. /* Add all empty conv output plane buffers to conv_output_plane_buf_queue. */
  740. for (uint32_t i = 0; i < ctx->conv->output_plane.getNumBuffers(); i++)
  741. {
  742. ctx->conv_output_plane_buf_queue->push(ctx->conv->output_plane.
  743. getNthBuffer(i));
  744. }
  745. /* Enqueue converter capture plane buffers. */
  746. for (uint32_t i = 0; i < ctx->conv->capture_plane.getNumBuffers(); i++)
  747. {
  748. struct v4l2_buffer v4l2_buf;
  749. struct v4l2_plane planes[MAX_PLANES];
  750. memset(&v4l2_buf, 0, sizeof(v4l2_buf));
  751. memset(planes, 0, sizeof(planes));
  752. v4l2_buf.index = i;
  753. v4l2_buf.m.planes = planes;
  754. ret = ctx->conv->capture_plane.qBuffer(v4l2_buf, NULL);
  755. TEST_ERROR(ret < 0, "Error Qing buffer at converter capture plane",
  756. error);
  757. }
  758. /* Start deque thread for converter output plane. */
  759. ctx->conv->output_plane.startDQThread(ctx);
  760. /* Start deque thread for converter capture plane. */
  761. ctx->conv->capture_plane.startDQThread(ctx);
  762. }
  763. #endif
  764. /* Decoder capture plane STREAMON.
  765. Refer ioctl VIDIOC_STREAMON */
  766. ret = dec->capture_plane.setStreamStatus(true);
  767. TEST_ERROR(ret < 0, "Error in decoder capture plane streamon", error);
  768. /* Enqueue all the empty decoder capture plane buffers. */
  769. for (uint32_t i = 0; i < dec->capture_plane.getNumBuffers(); i++)
  770. {
  771. struct v4l2_buffer v4l2_buf;
  772. struct v4l2_plane planes[MAX_PLANES];
  773. memset(&v4l2_buf, 0, sizeof(v4l2_buf));
  774. memset(planes, 0, sizeof(planes));
  775. v4l2_buf.index = i;
  776. v4l2_buf.m.planes = planes;
  777. v4l2_buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
  778. v4l2_buf.memory = ctx->capture_plane_mem_type;
  779. if(ctx->capture_plane_mem_type == V4L2_MEMORY_DMABUF)
  780. v4l2_buf.m.planes[0].m.fd = ctx->dmabuff_fd[i];
  781. ret = dec->capture_plane.qBuffer(v4l2_buf, NULL);
  782. TEST_ERROR(ret < 0, "Error Qing buffer at output plane", error);
  783. }
  784. cout << "Query and set capture successful" << endl;
  785. return;
  786. error:
  787. if (error)
  788. {
  789. abort(ctx);
  790. cerr << "Error in " << __func__ << endl;
  791. }
  792. }
  793. /**
  794. * Decoder polling thread loop function.
  795. *
  796. * @param args : void arguments
  797. */
  798. static void *decoder_pollthread_fcn(void *arg)
  799. {
  800. context_t *ctx = (context_t *) arg;
  801. v4l2_ctrl_video_device_poll devicepoll;
  802. cout << "Starting Device Poll Thread " << endl;
  803. memset(&devicepoll, 0, sizeof(v4l2_ctrl_video_device_poll));
  804. /* Wait here until you are signalled to issue the Poll call.
  805. Check if the abort status is set , if so exit.
  806. Else issue the Poll on the decoder and block.
  807. When the Poll returns, signal the decoder thread to continue. */
  808. while (!ctx->got_error && !ctx->dec->isInError())
  809. {
  810. /* wait on polling semaphore */
  811. sem_wait(&ctx->pollthread_sema);
  812. if (ctx->got_eos)
  813. {
  814. cout << "Decoder got eos, exiting poll thread \n";
  815. return NULL;
  816. }
  817. devicepoll.req_events = POLLIN | POLLOUT | POLLERR | POLLPRI;
  818. /* This call shall wait in the v4l2 decoder library.
  819. Refer V4L2_CID_MPEG_VIDEO_DEVICE_POLL */
  820. ctx->dec->DevicePoll(&devicepoll);
  821. /* We can check the devicepoll.resp_events bitmask to see
  822. which events are set. */
  823. sem_post(&ctx->decoderthread_sema);
  824. }
  825. return NULL;
  826. }
  827. /**
  828. * Decoder capture thread loop function.
  829. *
  830. * @param args : void arguments
  831. */
  832. static void *
  833. dec_capture_loop_fcn(void *arg)
  834. {
  835. context_t *ctx = (context_t *) arg;
  836. NvVideoDecoder *dec = ctx->dec;
  837. struct v4l2_event ev;
  838. int ret;
  839. cout << "Starting decoder capture loop thread" << endl;
  840. /* Need to wait for the first Resolution change event, so that
  841. the decoder knows the stream resolution and can allocate appropriate
  842. buffers when we call REQBUFS. */
  843. do
  844. {
  845. /* Refer ioctl VIDIOC_DQEVENT */
  846. ret = dec->dqEvent(ev, 50000);
  847. if (ret < 0)
  848. {
  849. if (errno == EAGAIN)
  850. {
  851. cerr <<
  852. "Timed out waiting for first V4L2_EVENT_RESOLUTION_CHANGE"
  853. << endl;
  854. }
  855. else
  856. {
  857. cerr << "Error in dequeueing decoder event" << endl;
  858. }
  859. abort(ctx);
  860. break;
  861. }
  862. }
  863. while ((ev.type != V4L2_EVENT_RESOLUTION_CHANGE) && !ctx->got_error);
  864. /* Received the resolution change event, now can do query_and_set_capture. */
  865. if (!ctx->got_error)
  866. query_and_set_capture(ctx);
  867. /* Exit on error or EOS which is signalled in main() */
  868. while (!(ctx->got_error || dec->isInError() || ctx->got_eos))
  869. {
  870. NvBuffer *dec_buffer;
  871. /* Check for Resolution change again.
  872. Refer ioctl VIDIOC_DQEVENT */
  873. ret = dec->dqEvent(ev, false);
  874. if (ret == 0)
  875. {
  876. switch (ev.type)
  877. {
  878. case V4L2_EVENT_RESOLUTION_CHANGE:
  879. query_and_set_capture(ctx);
  880. continue;
  881. }
  882. }
  883. /* Decoder capture loop */
  884. while (1)
  885. {
  886. struct v4l2_buffer v4l2_buf;
  887. struct v4l2_plane planes[MAX_PLANES];
  888. memset(&v4l2_buf, 0, sizeof(v4l2_buf));
  889. memset(planes, 0, sizeof(planes));
  890. v4l2_buf.m.planes = planes;
  891. /* Dequeue a filled buffer. */
  892. if (dec->capture_plane.dqBuffer(v4l2_buf, &dec_buffer, NULL, 0))
  893. {
  894. if (errno == EAGAIN)
  895. {
  896. usleep(1000);
  897. }
  898. else
  899. {
  900. abort(ctx);
  901. cerr << "Error while calling dequeue at capture plane" <<
  902. endl;
  903. }
  904. break;
  905. }
  906. if (ctx->enable_metadata)
  907. {
  908. v4l2_ctrl_videodec_outputbuf_metadata dec_metadata;
  909. /* Get the decoder output metadata on capture-plane.
  910. Refer V4L2_CID_MPEG_VIDEODEC_METADATA */
  911. ret = dec->getMetadata(v4l2_buf.index, dec_metadata);
  912. if (ret == 0)
  913. {
  914. report_metadata(ctx, &dec_metadata);
  915. }
  916. }
  917. if (ctx->copy_timestamp && ctx->input_nalu && ctx->stats)
  918. {
  919. cout << "[" << v4l2_buf.index << "]" "dec capture plane dqB timestamp [" <<
  920. v4l2_buf.timestamp.tv_sec << "s" << v4l2_buf.timestamp.tv_usec << "us]" << endl;
  921. }
  922. if (!ctx->disable_rendering && ctx->stats)
  923. {
  924. /* EglRenderer requires the fd of the 0th plane to render the buffer. */
  925. if(ctx->capture_plane_mem_type == V4L2_MEMORY_DMABUF)
  926. dec_buffer->planes[0].fd = ctx->dmabuff_fd[v4l2_buf.index];
  927. ctx->renderer->render(dec_buffer->planes[0].fd);
  928. }
  929. /* If we need to write to file or display the buffer, give
  930. the buffer to video converter output plane instead of
  931. returning the buffer back to decoder capture plane. */
  932. if (ctx->out_file || (!ctx->disable_rendering && !ctx->stats))
  933. {
  934. #ifndef USE_NVBUF_TRANSFORM_API
  935. NvBuffer *conv_buffer;
  936. struct v4l2_buffer conv_output_buffer;
  937. struct v4l2_plane conv_planes[MAX_PLANES];
  938. memset(&conv_output_buffer, 0, sizeof(conv_output_buffer));
  939. memset(conv_planes, 0, sizeof(conv_planes));
  940. conv_output_buffer.m.planes = conv_planes;
  941. /* Get an empty conv output plane buffer from conv_output_plane_buf_queue. */
  942. pthread_mutex_lock(&ctx->queue_lock);
  943. while (ctx->conv_output_plane_buf_queue->empty())
  944. {
  945. pthread_cond_wait(&ctx->queue_cond, &ctx->queue_lock);
  946. }
  947. conv_buffer = ctx->conv_output_plane_buf_queue->front();
  948. ctx->conv_output_plane_buf_queue->pop();
  949. pthread_mutex_unlock(&ctx->queue_lock);
  950. conv_output_buffer.index = conv_buffer->index;
  951. if (ctx->capture_plane_mem_type == V4L2_MEMORY_DMABUF)
  952. dec_buffer->planes[0].fd = ctx->dmabuff_fd[v4l2_buf.index];
  953. /* enqueue converter output plane buffer. */
  954. if (ctx->conv->output_plane.
  955. qBuffer(conv_output_buffer, dec_buffer) < 0)
  956. {
  957. abort(ctx);
  958. cerr <<
  959. "Error while queueing buffer at converter output plane"
  960. << endl;
  961. break;
  962. }
  963. #else
  964. /* Clip & Stitch can be done by adjusting rectangle. */
  965. NvBufferRect src_rect, dest_rect;
  966. src_rect.top = 0;
  967. src_rect.left = 0;
  968. src_rect.width = ctx->display_width;
  969. src_rect.height = ctx->display_height;
  970. dest_rect.top = 0;
  971. dest_rect.left = 0;
  972. dest_rect.width = ctx->display_width;
  973. dest_rect.height = ctx->display_height;
  974. NvBufferTransformParams transform_params;
  975. memset(&transform_params,0,sizeof(transform_params));
  976. /* Indicates which of the transform parameters are valid. */
  977. transform_params.transform_flag = NVBUFFER_TRANSFORM_FILTER;
  978. transform_params.transform_flip = NvBufferTransform_None;
  979. transform_params.transform_filter = NvBufferTransform_Filter_Nearest;
  980. transform_params.src_rect = src_rect;
  981. transform_params.dst_rect = dest_rect;
  982. if(ctx->capture_plane_mem_type == V4L2_MEMORY_DMABUF)
  983. dec_buffer->planes[0].fd = ctx->dmabuff_fd[v4l2_buf.index];
  984. /* Perform Blocklinear to PitchLinear conversion. */
  985. ret = NvBufferTransform(dec_buffer->planes[0].fd, ctx->dst_dma_fd, &transform_params);
  986. if (ret == -1)
  987. {
  988. cerr << "Transform failed" << endl;
  989. break;
  990. }
  991. /* Write raw video frame to file. */
  992. if (!ctx->stats && ctx->out_file)
  993. {
  994. /* Dumping two planes for NV12, NV16, NV24 and three for I420 */
  995. dump_dmabuf(ctx->dst_dma_fd, 0, ctx->out_file);
  996. dump_dmabuf(ctx->dst_dma_fd, 1, ctx->out_file);
  997. if (ctx->out_pixfmt == 2)
  998. {
  999. dump_dmabuf(ctx->dst_dma_fd, 2, ctx->out_file);
  1000. }
  1001. }
  1002. if (!ctx->stats && !ctx->disable_rendering)
  1003. {
  1004. ctx->renderer->render(ctx->dst_dma_fd);
  1005. }
  1006. /* If not writing to file, Queue the buffer back once it has been used. */
  1007. if(ctx->capture_plane_mem_type == V4L2_MEMORY_DMABUF)
  1008. v4l2_buf.m.planes[0].m.fd = ctx->dmabuff_fd[v4l2_buf.index];
  1009. if (dec->capture_plane.qBuffer(v4l2_buf, NULL) < 0)
  1010. {
  1011. abort(ctx);
  1012. cerr <<
  1013. "Error while queueing buffer at decoder capture plane"
  1014. << endl;
  1015. break;
  1016. }
  1017. #endif
  1018. }
  1019. else
  1020. {
  1021. /* If not writing to file, Queue the buffer back once it has been used. */
  1022. if(ctx->capture_plane_mem_type == V4L2_MEMORY_DMABUF)
  1023. v4l2_buf.m.planes[0].m.fd = ctx->dmabuff_fd[v4l2_buf.index];
  1024. if (dec->capture_plane.qBuffer(v4l2_buf, NULL) < 0)
  1025. {
  1026. abort(ctx);
  1027. cerr <<
  1028. "Error while queueing buffer at decoder capture plane"
  1029. << endl;
  1030. break;
  1031. }
  1032. }
  1033. }
  1034. }
  1035. #ifndef USE_NVBUF_TRANSFORM_API
  1036. /* Send EOS to converter */
  1037. if (ctx->conv)
  1038. {
  1039. if (sendEOStoConverter(ctx) < 0)
  1040. {
  1041. cerr << "Error while queueing EOS buffer on converter output"
  1042. << endl;
  1043. }
  1044. }
  1045. #endif
  1046. cout << "Exiting decoder capture loop thread" << endl;
  1047. return NULL;
  1048. }
  1049. /**
  1050. * Set the default values for decoder context members.
  1051. *
  1052. * @param ctx : Decoder context
  1053. */
  1054. static void
  1055. set_defaults(context_t * ctx)
  1056. {
  1057. memset(ctx, 0, sizeof(context_t));
  1058. ctx->fullscreen = false;
  1059. ctx->window_height = 360;
  1060. ctx->window_width = 640;
  1061. ctx->window_x = 300;
  1062. ctx->window_y = 0;
  1063. ctx->out_pixfmt = 1;
  1064. ctx->fps = 30;
  1065. ctx->output_plane_mem_type = V4L2_MEMORY_MMAP;
  1066. ctx->capture_plane_mem_type = V4L2_MEMORY_DMABUF;
  1067. ctx->vp9_file_header_flag = 0;
  1068. ctx->vp8_file_header_flag = 0;
  1069. ctx->stress_test = 1;
  1070. ctx->copy_timestamp = false;
  1071. ctx->flag_copyts = false;
  1072. ctx->start_ts = 0;
  1073. ctx->file_count = 1;
  1074. ctx->dec_fps = 30;
  1075. ctx->dst_dma_fd = -1;
  1076. ctx->bLoop = false;
  1077. ctx->bQueue = false;
  1078. ctx->loop_count = 0;
  1079. ctx->max_perf = 0;
  1080. ctx->extra_cap_plane_buffer = 1;
  1081. ctx->blocking_mode = 1;
  1082. #ifndef USE_NVBUF_TRANSFORM_API
  1083. ctx->conv_output_plane_buf_queue = new queue < NvBuffer * >;
  1084. ctx->rescale_method = V4L2_YUV_RESCALE_NONE;
  1085. #endif
  1086. pthread_mutex_init(&ctx->queue_lock, NULL);
  1087. pthread_cond_init(&ctx->queue_cond, NULL);
  1088. }
  1089. /**
  1090. * Decode processing function for non-blocking mode.
  1091. *
  1092. * @param ctx : Decoder context
  1093. * @param eos : end of stream
  1094. * @param current_file : current file
  1095. * @param current_loop : iterator count
  1096. * @param nalu_parse_buffer : input parsed nal unit
  1097. */
  1098. static bool decoder_proc_nonblocking(context_t &ctx, bool eos, uint32_t current_file,
  1099. int current_loop, char *nalu_parse_buffer)
  1100. {
  1101. /* NOTE: In non-blocking mode, we will have this function do below things:
  1102. 1) Issue signal to PollThread so it starts Poll and wait until we are signalled.
  1103. 2) After we are signalled, it means there is something to dequeue, either output plane
  1104. or capture plane or there's an event.
  1105. 3) Try dequeuing from all three and then act appropriately.
  1106. 4) After enqueuing go back to the same loop. */
  1107. /* Since all the output plane buffers have been queued, we first need to
  1108. dequeue a buffer from output plane before we can read new data into it
  1109. and queue it again. */
  1110. int allow_DQ = true;
  1111. int ret = 0;
  1112. struct v4l2_buffer temp_buf;
  1113. struct v4l2_event ev;
  1114. while (!ctx.got_error && !ctx.dec->isInError())
  1115. {
  1116. struct v4l2_buffer v4l2_output_buf;
  1117. struct v4l2_plane output_planes[MAX_PLANES];
  1118. struct v4l2_buffer v4l2_capture_buf;
  1119. struct v4l2_plane capture_planes[MAX_PLANES];
  1120. NvBuffer *output_buffer = NULL;
  1121. NvBuffer *capture_buffer = NULL;
  1122. memset(&v4l2_output_buf, 0, sizeof(v4l2_output_buf));
  1123. memset(output_planes, 0, sizeof(output_planes));
  1124. v4l2_output_buf.m.planes = output_planes;
  1125. memset(&v4l2_capture_buf, 0, sizeof(v4l2_capture_buf));
  1126. memset(capture_planes, 0, sizeof(capture_planes));
  1127. v4l2_capture_buf.m.planes = capture_planes;
  1128. /* Call for SetPollInterrupt.
  1129. Refer V4L2_CID_MPEG_SET_POLL_INTERRUPT */
  1130. ctx.dec->SetPollInterrupt();
  1131. /* Since buffers have been queued, issue a post to start polling and
  1132. then wait here. */
  1133. sem_post(&ctx.pollthread_sema);
  1134. sem_wait(&ctx.decoderthread_sema);
  1135. /* Call for dequeuing an event.
  1136. Refer ioctl VIDIOC_DQEVENT */
  1137. ret = ctx.dec->dqEvent(ev, 0);
  1138. if (ret == 0)
  1139. {
  1140. if (ev.type == V4L2_EVENT_RESOLUTION_CHANGE)
  1141. {
  1142. /* Received the resolution change event, now can do query_and_set_capture. */
  1143. cout << "Got V4L2_EVENT_RESOLUTION_CHANGE EVENT \n";
  1144. query_and_set_capture(&ctx);
  1145. }
  1146. }
  1147. else if (ret < 0 && errno == EINVAL)
  1148. {
  1149. cerr << "Error in dequeueing decoder event" << endl;
  1150. abort(&ctx);
  1151. }
  1152. /* dequeue from the output plane and enqueue back the buffers after reading. */
  1153. while (1)
  1154. {
  1155. if ( (eos) && (ctx.dec->output_plane.getNumQueuedBuffers() == 0) )
  1156. {
  1157. cout << "Done processing all the buffers returning \n";
  1158. return true;
  1159. }
  1160. /* dequeue a buffer for output plane. */
  1161. if (allow_DQ)
  1162. {
  1163. ret = ctx.dec->output_plane.dqBuffer(v4l2_output_buf, &output_buffer, NULL, 0);
  1164. if (ret < 0)
  1165. {
  1166. if (errno == EAGAIN)
  1167. goto check_capture_buffers;
  1168. else
  1169. {
  1170. cerr << "Error DQing buffer at output plane" << endl;
  1171. abort(&ctx);
  1172. break;
  1173. }
  1174. }
  1175. }
  1176. else
  1177. {
  1178. allow_DQ = true;
  1179. memcpy(&v4l2_output_buf,&temp_buf,sizeof(v4l2_buffer));
  1180. output_buffer = ctx.dec->output_plane.getNthBuffer(v4l2_output_buf.index);
  1181. }
  1182. if ((v4l2_output_buf.flags & V4L2_BUF_FLAG_ERROR) && ctx.enable_input_metadata)
  1183. {
  1184. v4l2_ctrl_videodec_inputbuf_metadata dec_input_metadata;
  1185. /* Get the decoder input metadata.
  1186. Refer V4L2_CID_MPEG_VIDEODEC_INPUT_METADATA */
  1187. ret = ctx.dec->getInputMetadata(v4l2_output_buf.index, dec_input_metadata);
  1188. if (ret == 0)
  1189. {
  1190. ret = report_input_metadata(&ctx, &dec_input_metadata);
  1191. if (ret == -1)
  1192. {
  1193. cerr << "Error with input stream header parsing" << endl;
  1194. }
  1195. }
  1196. }
  1197. if (eos)
  1198. {
  1199. /* Got End Of Stream, no more queueing of buffers on OUTPUT plane. */
  1200. goto check_capture_buffers;
  1201. }
  1202. if ((ctx.decoder_pixfmt == V4L2_PIX_FMT_H264) ||
  1203. (ctx.decoder_pixfmt == V4L2_PIX_FMT_H265) ||
  1204. (ctx.decoder_pixfmt == V4L2_PIX_FMT_MPEG2) ||
  1205. (ctx.decoder_pixfmt == V4L2_PIX_FMT_MPEG4))
  1206. {
  1207. if (ctx.input_nalu)
  1208. {
  1209. /* read the input nal unit. */
  1210. read_decoder_input_nalu(ctx.in_file[current_file], output_buffer, nalu_parse_buffer,
  1211. CHUNK_SIZE, &ctx);
  1212. }
  1213. else
  1214. {
  1215. /* read the input chunks. */
  1216. read_decoder_input_chunk(ctx.in_file[current_file], output_buffer);
  1217. }
  1218. }
  1219. if (ctx.decoder_pixfmt == V4L2_PIX_FMT_VP9 || ctx.decoder_pixfmt == V4L2_PIX_FMT_VP8)
  1220. {
  1221. /* read the input chunks. */
  1222. ret = read_vpx_decoder_input_chunk(&ctx, output_buffer);
  1223. if (ret != 0)
  1224. cerr << "Couldn't read chunk" << endl;
  1225. }
  1226. v4l2_output_buf.m.planes[0].bytesused = output_buffer->planes[0].bytesused;
  1227. if (ctx.input_nalu && ctx.copy_timestamp && ctx.flag_copyts)
  1228. {
  1229. /* Update the timestamp. */
  1230. v4l2_output_buf.flags |= V4L2_BUF_FLAG_TIMESTAMP_COPY;
  1231. ctx.timestamp += ctx.timestampincr;
  1232. v4l2_output_buf.timestamp.tv_sec = ctx.timestamp / (MICROSECOND_UNIT);
  1233. v4l2_output_buf.timestamp.tv_usec = ctx.timestamp % (MICROSECOND_UNIT);
  1234. }
  1235. if (v4l2_output_buf.m.planes[0].bytesused == 0)
  1236. {
  1237. if (ctx.bQueue)
  1238. {
  1239. current_file++;
  1240. if(current_file != ctx.file_count)
  1241. {
  1242. allow_DQ = false;
  1243. memcpy(&temp_buf, &v4l2_output_buf, sizeof(v4l2_buffer));
  1244. continue;
  1245. }
  1246. }
  1247. if(ctx.bLoop)
  1248. {
  1249. current_file = current_file % ctx.file_count;
  1250. allow_DQ = false;
  1251. memcpy(&temp_buf, &v4l2_output_buf,sizeof(v4l2_buffer));
  1252. if (ctx.loop_count == 0 || current_loop < ctx.loop_count )
  1253. {
  1254. current_loop++;
  1255. continue;
  1256. }
  1257. }
  1258. }
  1259. /* enqueue a buffer for output plane. */
  1260. ret = ctx.dec->output_plane.qBuffer(v4l2_output_buf, NULL);
  1261. if (ret < 0)
  1262. {
  1263. cerr << "Error Qing buffer at output plane" << endl;
  1264. abort(&ctx);
  1265. break;
  1266. }
  1267. if (v4l2_output_buf.m.planes[0].bytesused == 0)
  1268. {
  1269. eos = true;
  1270. cout << "Input file read complete" << endl;
  1271. goto check_capture_buffers;
  1272. }
  1273. }
  1274. check_capture_buffers:
  1275. /* Dequeue from the capture plane and write them to file and enqueue back. */
  1276. while (1)
  1277. {
  1278. if (!ctx.dec->capture_plane.getStreamStatus())
  1279. {
  1280. cout << "Capture plane not ON, skipping capture plane \n";
  1281. break;
  1282. }
  1283. /* Dequeue a filled buffer. */
  1284. ret = ctx.dec->capture_plane.dqBuffer(v4l2_capture_buf, &capture_buffer, NULL, 0);
  1285. if (ret < 0)
  1286. {
  1287. if (errno == EAGAIN)
  1288. break;
  1289. else
  1290. {
  1291. abort(&ctx);
  1292. cerr << "Error while calling dequeue at capture plane" <<
  1293. endl;
  1294. }
  1295. break;
  1296. }
  1297. if (capture_buffer == NULL)
  1298. {
  1299. cout << "Got CAPTURE BUFFER NULL \n";
  1300. break;
  1301. }
  1302. if (ctx.enable_metadata)
  1303. {
  1304. v4l2_ctrl_videodec_outputbuf_metadata dec_metadata;
  1305. /* Get the decoder output metadata on capture-plane.
  1306. Refer V4L2_CID_MPEG_VIDEODEC_METADATA */
  1307. ret = ctx.dec->getMetadata(v4l2_capture_buf.index, dec_metadata);
  1308. if (ret == 0)
  1309. {
  1310. report_metadata(&ctx, &dec_metadata);
  1311. }
  1312. }
  1313. if (ctx.copy_timestamp && ctx.input_nalu && ctx.stats)
  1314. {
  1315. cout << "[" << v4l2_capture_buf.index << "]" "dec capture plane dqB timestamp [" <<
  1316. v4l2_capture_buf.timestamp.tv_sec << "s" << v4l2_capture_buf.timestamp.tv_usec << "us]" << endl;
  1317. }
  1318. if (!ctx.disable_rendering && ctx.stats)
  1319. {
  1320. /* Rendering the buffer.
  1321. NOTE: EglRenderer requires the fd of the 0th plane to render the buffer. */
  1322. if(ctx.capture_plane_mem_type == V4L2_MEMORY_DMABUF)
  1323. capture_buffer->planes[0].fd = ctx.dmabuff_fd[v4l2_capture_buf.index];
  1324. if (ctx.renderer->render(capture_buffer->planes[0].fd) == -1)
  1325. {
  1326. abort(&ctx);
  1327. cerr << "Error while queueing buffer for rendering "
  1328. << endl;
  1329. break;
  1330. }
  1331. }
  1332. /* Get the decoded buffer data dumped to file. */
  1333. if (ctx.out_file || (!ctx.disable_rendering && !ctx.stats))
  1334. {
  1335. NvBufferRect src_rect, dest_rect;
  1336. src_rect.top = 0;
  1337. src_rect.left = 0;
  1338. src_rect.width = ctx.display_width;
  1339. src_rect.height = ctx.display_height;
  1340. dest_rect.top = 0;
  1341. dest_rect.left = 0;
  1342. dest_rect.width = ctx.display_width;
  1343. dest_rect.height = ctx.display_height;
  1344. NvBufferTransformParams transform_params;
  1345. memset(&transform_params, 0, sizeof(transform_params));
  1346. /* Indicates which of the transform parameters are valid. */
  1347. transform_params.transform_flag = NVBUFFER_TRANSFORM_FILTER;
  1348. transform_params.transform_flip = NvBufferTransform_None;
  1349. transform_params.transform_filter = NvBufferTransform_Filter_Nearest;
  1350. transform_params.src_rect = src_rect;
  1351. transform_params.dst_rect = dest_rect;
  1352. if(ctx.capture_plane_mem_type == V4L2_MEMORY_DMABUF)
  1353. capture_buffer->planes[0].fd = ctx.dmabuff_fd[v4l2_capture_buf.index];
  1354. /* Perform Blocklinear to PitchLinear conversion. */
  1355. ret = NvBufferTransform(capture_buffer->planes[0].fd, ctx.dst_dma_fd, &transform_params);
  1356. if (ret == -1)
  1357. {
  1358. cerr << "Transform failed" << endl;
  1359. break;
  1360. }
  1361. /* Write raw video frame to file. */
  1362. if (!ctx.stats && ctx.out_file)
  1363. {
  1364. /* Dumping two planes for NV12, NV16, NV24 and three for I420 */
  1365. cout << "Writing to file \n";
  1366. dump_dmabuf(ctx.dst_dma_fd, 0, ctx.out_file);
  1367. dump_dmabuf(ctx.dst_dma_fd, 1, ctx.out_file);
  1368. if (ctx.out_pixfmt == 2)
  1369. {
  1370. dump_dmabuf(ctx.dst_dma_fd, 2, ctx.out_file);
  1371. }
  1372. }
  1373. /* Rendering the buffer. */
  1374. if (!ctx.stats && !ctx.disable_rendering)
  1375. {
  1376. ctx.renderer->render(ctx.dst_dma_fd);
  1377. }
  1378. /* Queue the buffer back once it has been used.
  1379. NOTE: If we are not rendering, queue the buffer back here immediately. */
  1380. if(ctx.capture_plane_mem_type == V4L2_MEMORY_DMABUF)
  1381. v4l2_capture_buf.m.planes[0].m.fd = ctx.dmabuff_fd[v4l2_capture_buf.index];
  1382. if (ctx.dec->capture_plane.qBuffer(v4l2_capture_buf, NULL) < 0)
  1383. {
  1384. abort(&ctx);
  1385. cerr << "Error while queueing buffer at decoder capture plane"
  1386. << endl;
  1387. break;
  1388. }
  1389. }
  1390. }
  1391. }
  1392. return eos;
  1393. }
  1394. /**
  1395. * Decode processing function for blocking mode.
  1396. *
  1397. * @param ctx : Decoder context
  1398. * @param eos : end of stream
  1399. * @param current_file : current file
  1400. * @param current_loop : iterator count
  1401. * @param nalu_parse_buffer : input parsed nal unit
  1402. */
  1403. static bool decoder_proc_blocking(context_t &ctx, bool eos, uint32_t current_file,
  1404. int current_loop, char *nalu_parse_buffer)
  1405. {
  1406. int allow_DQ = true;
  1407. int ret = 0;
  1408. struct v4l2_buffer temp_buf;
  1409. /* Since all the output plane buffers have been queued, we first need to
  1410. dequeue a buffer from output plane before we can read new data into it
  1411. and queue it again. */
  1412. while (!eos && !ctx.got_error && !ctx.dec->isInError())
  1413. {
  1414. std::cout<<"oo"<<std::endl;
  1415. struct v4l2_buffer v4l2_buf;
  1416. struct v4l2_plane planes[MAX_PLANES];
  1417. NvBuffer *buffer;
  1418. memset(&v4l2_buf, 0, sizeof(v4l2_buf));
  1419. memset(planes, 0, sizeof(planes));
  1420. v4l2_buf.m.planes = planes;
  1421. /* dequeue a buffer for output plane. */
  1422. if(allow_DQ)
  1423. {
  1424. ret = ctx.dec->output_plane.dqBuffer(v4l2_buf, &buffer, NULL, -1);
  1425. if (ret < 0)
  1426. {
  1427. cerr << "Error DQing buffer at output plane" << endl;
  1428. abort(&ctx);
  1429. break;
  1430. }
  1431. }
  1432. else
  1433. {
  1434. allow_DQ = true;
  1435. memcpy(&v4l2_buf,&temp_buf,sizeof(v4l2_buffer));
  1436. buffer = ctx.dec->output_plane.getNthBuffer(v4l2_buf.index);
  1437. }
  1438. if ((v4l2_buf.flags & V4L2_BUF_FLAG_ERROR) && ctx.enable_input_metadata)
  1439. {
  1440. v4l2_ctrl_videodec_inputbuf_metadata dec_input_metadata;
  1441. /* Get the decoder input metadata.
  1442. Refer V4L2_CID_MPEG_VIDEODEC_INPUT_METADATA */
  1443. ret = ctx.dec->getInputMetadata(v4l2_buf.index, dec_input_metadata);
  1444. if (ret == 0)
  1445. {
  1446. ret = report_input_metadata(&ctx, &dec_input_metadata);
  1447. if (ret == -1)
  1448. {
  1449. cerr << "Error with input stream header parsing" << endl;
  1450. }
  1451. }
  1452. }
  1453. if ((ctx.decoder_pixfmt == V4L2_PIX_FMT_H264) ||
  1454. (ctx.decoder_pixfmt == V4L2_PIX_FMT_H265) ||
  1455. (ctx.decoder_pixfmt == V4L2_PIX_FMT_MPEG2) ||
  1456. (ctx.decoder_pixfmt == V4L2_PIX_FMT_MPEG4))
  1457. {
  1458. if (ctx.input_nalu)
  1459. {
  1460. /* read the input nal unit. */
  1461. read_decoder_input_nalu(ctx.in_file[current_file], buffer, nalu_parse_buffer,
  1462. CHUNK_SIZE, &ctx);
  1463. }
  1464. else
  1465. {
  1466. /* read the input chunks. */
  1467. read_decoder_input_chunk(ctx.in_file[current_file], buffer);
  1468. }
  1469. }
  1470. if (ctx.decoder_pixfmt == V4L2_PIX_FMT_VP9 || ctx.decoder_pixfmt == V4L2_PIX_FMT_VP8)
  1471. {
  1472. /* read the input chunks. */
  1473. ret = read_vpx_decoder_input_chunk(&ctx, buffer);
  1474. if (ret != 0)
  1475. cerr << "Couldn't read chunk" << endl;
  1476. }
  1477. v4l2_buf.m.planes[0].bytesused = buffer->planes[0].bytesused;
  1478. if (ctx.input_nalu && ctx.copy_timestamp && ctx.flag_copyts)
  1479. {
  1480. /* Update the timestamp. */
  1481. v4l2_buf.flags |= V4L2_BUF_FLAG_TIMESTAMP_COPY;
  1482. ctx.timestamp += ctx.timestampincr;
  1483. v4l2_buf.timestamp.tv_sec = ctx.timestamp / (MICROSECOND_UNIT);
  1484. v4l2_buf.timestamp.tv_usec = ctx.timestamp % (MICROSECOND_UNIT);
  1485. }
  1486. if (v4l2_buf.m.planes[0].bytesused == 0)
  1487. {
  1488. if (ctx.bQueue)
  1489. {
  1490. current_file++;
  1491. if(current_file != ctx.file_count)
  1492. {
  1493. allow_DQ = false;
  1494. memcpy(&temp_buf,&v4l2_buf,sizeof(v4l2_buffer));
  1495. continue;
  1496. }
  1497. }
  1498. if(ctx.bLoop)
  1499. {
  1500. current_file = current_file % ctx.file_count;
  1501. allow_DQ = false;
  1502. memcpy(&temp_buf,&v4l2_buf,sizeof(v4l2_buffer));
  1503. }
  1504. }
  1505. /* enqueue a buffer for output plane. */
  1506. ret = ctx.dec->output_plane.qBuffer(v4l2_buf, NULL);
  1507. if (ret < 0)
  1508. {
  1509. cerr << "Error Qing buffer at output plane" << endl;
  1510. abort(&ctx);
  1511. break;
  1512. }
  1513. if (v4l2_buf.m.planes[0].bytesused == 0)
  1514. {
  1515. eos = true;
  1516. cout << "Input file read complete" << endl;
  1517. break;
  1518. }
  1519. }
  1520. return eos;
  1521. }
  1522. /**
  1523. * Decode processing function.
  1524. *
  1525. * @param ctx : Decoder context
  1526. * @param argc : Argument Count
  1527. * @param argv : Argument Vector
  1528. */
  1529. static int
  1530. decode_proc(context_t& ctx, int argc, char *argv[])
  1531. {
  1532. int ret = 0;
  1533. int error = 0;
  1534. uint32_t current_file = 0;
  1535. uint32_t i;
  1536. bool eos = false;
  1537. int current_loop = 0;
  1538. char *nalu_parse_buffer = NULL;
  1539. NvApplicationProfiler &profiler = NvApplicationProfiler::getProfilerInstance();
  1540. /* Set default values for decoder context members. */
  1541. set_defaults(&ctx);
  1542. /* Set thread name for decoder Output Plane thread. */
  1543. pthread_setname_np(pthread_self(), "DecOutPlane");
  1544. /* Parse application command line options. */
  1545. if (parse_csv_args(&ctx, argc, argv))
  1546. {
  1547. fprintf(stderr, "Error parsing commandline arguments\n");
  1548. return -1;
  1549. }
  1550. /* Create NvVideoDecoder object for blocking or non-blocking I/O mode. */
  1551. if (ctx.blocking_mode)
  1552. {
  1553. cout << "Creating decoder in blocking mode \n";
  1554. ctx.dec = NvVideoDecoder::createVideoDecoder("dec0");
  1555. }
  1556. else
  1557. {
  1558. cout << "Creating decoder in non-blocking mode \n";
  1559. ctx.dec = NvVideoDecoder::createVideoDecoder("dec0", O_NONBLOCK);
  1560. }
  1561. TEST_ERROR(!ctx.dec, "Could not create decoder", cleanup);
  1562. /* Open the input file. */
  1563. ctx.in_file = (std::ifstream **)malloc(sizeof(std::ifstream *)*ctx.file_count);
  1564. for (uint32_t i = 0 ; i < ctx.file_count ; i++)
  1565. {
  1566. ctx.in_file[i] = new ifstream(ctx.in_file_path[i]);
  1567. TEST_ERROR(!ctx.in_file[i]->is_open(), "Error opening input file", cleanup);
  1568. }
  1569. /* Open the output file. */
  1570. if (ctx.out_file_path)
  1571. {
  1572. ctx.out_file = new ofstream(ctx.out_file_path);
  1573. TEST_ERROR(!ctx.out_file->is_open(), "Error opening output file",
  1574. cleanup);
  1575. }
  1576. /* Enable profiling for decoder if stats are requested. */
  1577. if (ctx.stats)
  1578. {
  1579. profiler.start(NvApplicationProfiler::DefaultSamplingInterval);
  1580. ctx.dec->enableProfiling();
  1581. }
  1582. /* Subscribe to Resolution change event.
  1583. Refer ioctl VIDIOC_SUBSCRIBE_EVENT */
  1584. ret = ctx.dec->subscribeEvent(V4L2_EVENT_RESOLUTION_CHANGE, 0, 0);
  1585. TEST_ERROR(ret < 0, "Could not subscribe to V4L2_EVENT_RESOLUTION_CHANGE",
  1586. cleanup);
  1587. /* Set format on the output plane.
  1588. Refer ioctl VIDIOC_S_FMT */
  1589. ret = ctx.dec->setOutputPlaneFormat(ctx.decoder_pixfmt, CHUNK_SIZE);
  1590. TEST_ERROR(ret < 0, "Could not set output plane format", cleanup);
  1591. /* Configure for frame input mode for decoder.
  1592. Refer V4L2_CID_MPEG_VIDEO_DISABLE_COMPLETE_FRAME_INPUT */
  1593. if (ctx.input_nalu)
  1594. {
  1595. /* Input to the decoder will be nal units. */
  1596. nalu_parse_buffer = new char[CHUNK_SIZE];
  1597. printf("Setting frame input mode to 0 \n");
  1598. ret = ctx.dec->setFrameInputMode(0);
  1599. TEST_ERROR(ret < 0,
  1600. "Error in decoder setFrameInputMode", cleanup);
  1601. }
  1602. else
  1603. {
  1604. /* Input to the decoder will be a chunk of bytes.
  1605. NOTE: Set V4L2_CID_MPEG_VIDEO_DISABLE_COMPLETE_FRAME_INPUT control to
  1606. false so that application can send chunks of encoded data instead
  1607. of forming complete frames. */
  1608. printf("Setting frame input mode to 1 \n");
  1609. ret = ctx.dec->setFrameInputMode(1);
  1610. TEST_ERROR(ret < 0,
  1611. "Error in decoder setFrameInputMode", cleanup);
  1612. }
  1613. /* Disable decoder DPB management.
  1614. NOTE: V4L2_CID_MPEG_VIDEO_DISABLE_DPB should be set after output plane
  1615. set format */
  1616. if (ctx.disable_dpb)
  1617. {
  1618. ret = ctx.dec->disableDPB();
  1619. TEST_ERROR(ret < 0, "Error in decoder disableDPB", cleanup);
  1620. }
  1621. /* Enable decoder error and metadata reporting.
  1622. Refer V4L2_CID_MPEG_VIDEO_ERROR_REPORTING */
  1623. if (ctx.enable_metadata || ctx.enable_input_metadata)
  1624. {
  1625. ret = ctx.dec->enableMetadataReporting();
  1626. TEST_ERROR(ret < 0, "Error while enabling metadata reporting", cleanup);
  1627. }
  1628. /* Enable max performance mode by using decoder max clock settings.
  1629. Refer V4L2_CID_MPEG_VIDEO_MAX_PERFORMANCE */
  1630. if (ctx.max_perf)
  1631. {
  1632. ret = ctx.dec->setMaxPerfMode(ctx.max_perf);
  1633. TEST_ERROR(ret < 0, "Error while setting decoder to max perf", cleanup);
  1634. }
  1635. /* Set the skip frames property of the decoder.
  1636. Refer V4L2_CID_MPEG_VIDEO_SKIP_FRAMES */
  1637. if (ctx.skip_frames)
  1638. {
  1639. ret = ctx.dec->setSkipFrames(ctx.skip_frames);
  1640. TEST_ERROR(ret < 0, "Error while setting skip frames param", cleanup);
  1641. }
  1642. /* Query, Export and Map the output plane buffers so can read
  1643. encoded data into the buffers. */
  1644. if (ctx.output_plane_mem_type == V4L2_MEMORY_MMAP) {
  1645. /* configure decoder output plane for MMAP io-mode.
  1646. Refer ioctl VIDIOC_REQBUFS, VIDIOC_QUERYBUF and VIDIOC_EXPBUF */
  1647. ret = ctx.dec->output_plane.setupPlane(V4L2_MEMORY_MMAP, 2, true, false);
  1648. } else if (ctx.output_plane_mem_type == V4L2_MEMORY_USERPTR) {
  1649. /* configure decoder output plane for USERPTR io-mode.
  1650. Refer ioctl VIDIOC_REQBUFS */
  1651. ret = ctx.dec->output_plane.setupPlane(V4L2_MEMORY_USERPTR, 10, false, true);
  1652. }
  1653. TEST_ERROR(ret < 0, "Error while setting up output plane", cleanup);
  1654. #ifndef USE_NVBUF_TRANSFORM_API
  1655. if (ctx.out_file || (!ctx.disable_rendering && !ctx.stats))
  1656. {
  1657. /* Create converter object for Block-linear to Pitch-linear
  1658. transform required for writing decoded raw video to file. */
  1659. ctx.conv = NvVideoConverter::createVideoConverter("conv0");
  1660. TEST_ERROR(!ctx.conv, "Could not create video converter", cleanup);
  1661. /* Set dqbuffer thread callback for converter output-plane. */
  1662. ctx.conv->output_plane.
  1663. setDQThreadCallback(conv0_output_dqbuf_thread_callback);
  1664. /* Set dqbuffer thread callback for converter capture-plane. */
  1665. ctx.conv->capture_plane.
  1666. setDQThreadCallback(conv0_capture_dqbuf_thread_callback);
  1667. /* Enable profiling for converter if stats are requested. */
  1668. if (ctx.stats)
  1669. {
  1670. ctx.conv->enableProfiling();
  1671. }
  1672. }
  1673. #endif
  1674. /* Start stream processing on decoder output-plane.
  1675. Refer ioctl VIDIOC_STREAMON */
  1676. ret = ctx.dec->output_plane.setStreamStatus(true);
  1677. TEST_ERROR(ret < 0, "Error in output plane stream on", cleanup);
  1678. /* Enable copy timestamp with start timestamp in seconds for decode fps.
  1679. NOTE: Used to demonstrate how timestamp can be associated with an
  1680. individual H264/H265 frame to achieve video-synchronization. */
  1681. if (ctx.copy_timestamp && ctx.input_nalu) {
  1682. ctx.timestamp = (ctx.start_ts * MICROSECOND_UNIT);
  1683. ctx.timestampincr = (MICROSECOND_UNIT * 16) / ((uint32_t) (ctx.dec_fps * 16));
  1684. }
  1685. /* Read encoded data and enqueue all the output plane buffers.
  1686. Exit loop in case file read is complete. */
  1687. i = 0;
  1688. current_loop = 1;
  1689. while (!eos && !ctx.got_error && !ctx.dec->isInError() &&
  1690. i < ctx.dec->output_plane.getNumBuffers())
  1691. {
  1692. struct v4l2_buffer v4l2_buf;
  1693. struct v4l2_plane planes[MAX_PLANES];
  1694. NvBuffer *buffer;
  1695. memset(&v4l2_buf, 0, sizeof(v4l2_buf));
  1696. memset(planes, 0, sizeof(planes));
  1697. buffer = ctx.dec->output_plane.getNthBuffer(i);
  1698. if ((ctx.decoder_pixfmt == V4L2_PIX_FMT_H264) ||
  1699. (ctx.decoder_pixfmt == V4L2_PIX_FMT_H265) ||
  1700. (ctx.decoder_pixfmt == V4L2_PIX_FMT_MPEG2) ||
  1701. (ctx.decoder_pixfmt == V4L2_PIX_FMT_MPEG4))
  1702. {
  1703. if (ctx.input_nalu)
  1704. {
  1705. /* read the input nal unit. */
  1706. read_decoder_input_nalu(ctx.in_file[current_file], buffer, nalu_parse_buffer,
  1707. CHUNK_SIZE, &ctx);
  1708. }
  1709. else
  1710. {
  1711. /* read the input chunks. */
  1712. read_decoder_input_chunk(ctx.in_file[current_file], buffer);
  1713. }
  1714. }
  1715. if (ctx.decoder_pixfmt == V4L2_PIX_FMT_VP9 || ctx.decoder_pixfmt == V4L2_PIX_FMT_VP8)
  1716. {
  1717. /* read the input chunks. */
  1718. ret = read_vpx_decoder_input_chunk(&ctx, buffer);
  1719. if (ret != 0)
  1720. cerr << "Couldn't read chunk" << endl;
  1721. }
  1722. v4l2_buf.index = i;
  1723. v4l2_buf.m.planes = planes;
  1724. v4l2_buf.m.planes[0].bytesused = buffer->planes[0].bytesused;
  1725. if (ctx.input_nalu && ctx.copy_timestamp && ctx.flag_copyts)
  1726. {
  1727. /* Update the timestamp. */
  1728. v4l2_buf.flags |= V4L2_BUF_FLAG_TIMESTAMP_COPY;
  1729. ctx.timestamp += ctx.timestampincr;
  1730. v4l2_buf.timestamp.tv_sec = ctx.timestamp / (MICROSECOND_UNIT);
  1731. v4l2_buf.timestamp.tv_usec = ctx.timestamp % (MICROSECOND_UNIT);
  1732. }
  1733. if (v4l2_buf.m.planes[0].bytesused == 0)
  1734. {
  1735. if (ctx.bQueue)
  1736. {
  1737. current_file++;
  1738. if(current_file != ctx.file_count)
  1739. {
  1740. continue;
  1741. }
  1742. }
  1743. if(ctx.bLoop)
  1744. {
  1745. current_file = current_file % ctx.file_count;
  1746. if(ctx.loop_count == 0 || current_loop < ctx.loop_count )
  1747. {
  1748. current_loop++;
  1749. continue;
  1750. }
  1751. }
  1752. }
  1753. /* It is necessary to queue an empty buffer to signal EOS to the decoder
  1754. i.e. set v4l2_buf.m.planes[0].bytesused = 0 and queue the buffer. */
  1755. ret = ctx.dec->output_plane.qBuffer(v4l2_buf, NULL);
  1756. if (ret < 0)
  1757. {
  1758. cerr << "Error Qing buffer at output plane" << endl;
  1759. abort(&ctx);
  1760. break;
  1761. }
  1762. if (v4l2_buf.m.planes[0].bytesused == 0)
  1763. {
  1764. eos = true;
  1765. cout << "Input file read complete" << endl;
  1766. break;
  1767. }
  1768. i++;
  1769. }
  1770. /* Create threads for decoder output */
  1771. if (ctx.blocking_mode)
  1772. {
  1773. pthread_create(&ctx.dec_capture_loop, NULL, dec_capture_loop_fcn, &ctx);
  1774. /* Set thread name for decoder Capture Plane thread. */
  1775. pthread_setname_np(ctx.dec_capture_loop, "DecCapPlane");
  1776. }
  1777. else
  1778. {
  1779. sem_init(&ctx.pollthread_sema, 0, 0);
  1780. sem_init(&ctx.decoderthread_sema, 0, 0);
  1781. pthread_create(&ctx.dec_pollthread, NULL, decoder_pollthread_fcn, &ctx);
  1782. cout << "Created the PollThread and Decoder Thread \n";
  1783. /* Set thread name for decoder Poll thread. */
  1784. pthread_setname_np(ctx.dec_pollthread, "DecPollThread");
  1785. }
  1786. if (ctx.blocking_mode)
  1787. eos = decoder_proc_blocking(ctx, eos, current_file, current_loop, nalu_parse_buffer);
  1788. else
  1789. eos = decoder_proc_nonblocking(ctx, eos, current_file, current_loop, nalu_parse_buffer);
  1790. /* After sending EOS, all the buffers from output plane should be dequeued.
  1791. and after that capture plane loop should be signalled to stop. */
  1792. if (ctx.blocking_mode)
  1793. {
  1794. while (ctx.dec->output_plane.getNumQueuedBuffers() > 0 &&
  1795. !ctx.got_error && !ctx.dec->isInError())
  1796. {
  1797. struct v4l2_buffer v4l2_buf;
  1798. struct v4l2_plane planes[MAX_PLANES];
  1799. memset(&v4l2_buf, 0, sizeof(v4l2_buf));
  1800. memset(planes, 0, sizeof(planes));
  1801. v4l2_buf.m.planes = planes;
  1802. ret = ctx.dec->output_plane.dqBuffer(v4l2_buf, NULL, NULL, -1);
  1803. if (ret < 0)
  1804. {
  1805. cerr << "Error DQing buffer at output plane" << endl;
  1806. abort(&ctx);
  1807. break;
  1808. }
  1809. if ((v4l2_buf.flags & V4L2_BUF_FLAG_ERROR) && ctx.enable_input_metadata)
  1810. {
  1811. v4l2_ctrl_videodec_inputbuf_metadata dec_input_metadata;
  1812. /* Get the decoder input metadata.
  1813. Refer V4L2_CID_MPEG_VIDEODEC_INPUT_METADATA */
  1814. ret = ctx.dec->getInputMetadata(v4l2_buf.index, dec_input_metadata);
  1815. if (ret == 0)
  1816. {
  1817. ret = report_input_metadata(&ctx, &dec_input_metadata);
  1818. if (ret == -1)
  1819. {
  1820. cerr << "Error with input stream header parsing" << endl;
  1821. abort(&ctx);
  1822. break;
  1823. }
  1824. }
  1825. }
  1826. }
  1827. }
  1828. /* Signal EOS to the decoder capture loop. */
  1829. ctx.got_eos = true;
  1830. #ifndef USE_NVBUF_TRANSFORM_API
  1831. if (ctx.conv)
  1832. {
  1833. ctx.conv->capture_plane.waitForDQThread(-1);
  1834. }
  1835. #endif
  1836. if (ctx.stats)
  1837. {
  1838. profiler.stop();
  1839. ctx.dec->printProfilingStats(cout);
  1840. #ifndef USE_NVBUF_TRANSFORM_API
  1841. if (ctx.conv)
  1842. {
  1843. ctx.conv->printProfilingStats(cout);
  1844. }
  1845. #endif
  1846. if (ctx.renderer)
  1847. {
  1848. ctx.renderer->printProfilingStats(cout);
  1849. }
  1850. profiler.printProfilerData(cout);
  1851. }
  1852. cleanup:
  1853. if (ctx.blocking_mode && ctx.dec_capture_loop)
  1854. {
  1855. pthread_join(ctx.dec_capture_loop, NULL);
  1856. }
  1857. else if (!ctx.blocking_mode)
  1858. {
  1859. /* Clear the poll interrupt to get the decoder's poll thread out. */
  1860. ctx.dec->ClearPollInterrupt();
  1861. /* If Pollthread is waiting on, signal it to exit the thread. */
  1862. sem_post(&ctx.pollthread_sema);
  1863. pthread_join(ctx.dec_pollthread, NULL);
  1864. }
  1865. if(ctx.capture_plane_mem_type == V4L2_MEMORY_DMABUF)
  1866. {
  1867. for(int index = 0 ; index < ctx.numCapBuffers ; index++)
  1868. {
  1869. if(ctx.dmabuff_fd[index] != 0)
  1870. {
  1871. ret = NvBufferDestroy (ctx.dmabuff_fd[index]);
  1872. if(ret < 0)
  1873. {
  1874. cerr << "Failed to Destroy NvBuffer" << endl;
  1875. }
  1876. }
  1877. }
  1878. }
  1879. #ifndef USE_NVBUF_TRANSFORM_API
  1880. if (ctx.conv && ctx.conv->isInError())
  1881. {
  1882. cerr << "Converter is in error" << endl;
  1883. error = 1;
  1884. }
  1885. #endif
  1886. if (ctx.dec && ctx.dec->isInError())
  1887. {
  1888. cerr << "Decoder is in error" << endl;
  1889. error = 1;
  1890. }
  1891. if (ctx.got_error)
  1892. {
  1893. error = 1;
  1894. }
  1895. /* The decoder destructor does all the cleanup i.e set streamoff on output and
  1896. capture planes, unmap buffers, tell decoder to deallocate buffer (reqbufs
  1897. ioctl with count = 0), and finally call v4l2_close on the fd. */
  1898. delete ctx.dec;
  1899. #ifndef USE_NVBUF_TRANSFORM_API
  1900. delete ctx.conv;
  1901. #endif
  1902. /* Similarly, EglRenderer destructor does all the cleanup. */
  1903. delete ctx.renderer;
  1904. for (uint32_t i = 0 ; i < ctx.file_count ; i++)
  1905. delete ctx.in_file[i];
  1906. delete ctx.out_file;
  1907. #ifndef USE_NVBUF_TRANSFORM_API
  1908. delete ctx.conv_output_plane_buf_queue;
  1909. #else
  1910. if(ctx.dst_dma_fd != -1)
  1911. {
  1912. NvBufferDestroy(ctx.dst_dma_fd);
  1913. ctx.dst_dma_fd = -1;
  1914. }
  1915. #endif
  1916. delete[] nalu_parse_buffer;
  1917. free (ctx.in_file);
  1918. for (uint32_t i = 0 ; i < ctx.file_count ; i++)
  1919. free (ctx.in_file_path[i]);
  1920. free (ctx.in_file_path);
  1921. free(ctx.out_file_path);
  1922. if (!ctx.blocking_mode)
  1923. {
  1924. sem_destroy(&ctx.pollthread_sema);
  1925. sem_destroy(&ctx.decoderthread_sema);
  1926. }
  1927. return -error;
  1928. }
  1929. /**
  1930. * Start of video Decode application.
  1931. *
  1932. * @param argc : Argument Count
  1933. * @param argv : Argument Vector
  1934. */
  1935. int
  1936. main(int argc, char *argv[])
  1937. {
  1938. /* create decoder context. */
  1939. context_t ctx;
  1940. int ret = 0;
  1941. /* save decode iterator number */
  1942. int iterator_num = 0;
  1943. int targc = 3;
  1944. char * targv[3];
  1945. targv[0] = "videoc_encode";
  1946. targv[1] = "H264";
  1947. targv[2] = "/home/nvidia/testh264.mp4";
  1948. // targv[2] = strwidth;
  1949. // targv[3] = strheight;
  1950. // targv[5] = "/home/nvidia/testh264.mp4";
  1951. do
  1952. {
  1953. /* Invoke video decode function. */
  1954. ret = decode_proc(ctx,targc,targv);
  1955. // ret = decode_proc(ctx, argc, argv);
  1956. iterator_num++;
  1957. } while((ctx.stress_test != iterator_num) && ret == 0);
  1958. /* Report application run status on exit. */
  1959. if (ret)
  1960. {
  1961. cout << "App run failed" << endl;
  1962. }
  1963. else
  1964. {
  1965. cout << "App run was successful" << endl;
  1966. }
  1967. return ret;
  1968. }