]> git.vomp.tv Git - vompclient.git/blob - imageomx.cc
Log conversion
[vompclient.git] / imageomx.cc
1 /*
2     Copyright 2004-2005 Chris Tallon, 2009,2014 Marten Richter
3
4     This file is part of VOMP.
5
6     VOMP is free software; you can redistribute it and/or modify
7     it under the terms of the GNU General Public License as published by
8     the Free Software Foundation; either version 2 of the License, or
9     (at your option) any later version.
10
11     VOMP is distributed in the hope that it will be useful,
12     but WITHOUT ANY WARRANTY; without even the implied warranty of
13     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14     GNU General Public License for more details.
15
16     You should have received a copy of the GNU General Public License
17     along with VOMP.  If not, see <https://www.gnu.org/licenses/>.
18 */
19
20 #include <bcm_host.h>
21 #include "videoomx.h"
22 #include "oldlog.h"
23 #include "vdr.h"
24 #include "woptionpane.h"
25 #include "util.h"
26 #include "osdopenvg.h"
27
28 #include "imageomx.h"
29
30 static const char* TAG = "ImageOMX";
31
32 ImageOMX::ImageOMX(OsdVector::PictureReader * treader):OsdVector::PictureDecoder(treader)
33 {
34   initted = 0;
35
36   omx_running=false;
37   pictInfValid=false;
38   omx_imag_decode/*dec*/=NULL;
39   omx_egl_render/*dec*/=NULL;
40
41   buf_head_egl=NULL;
42   curformat = Unsupported;
43
44   strcpy(L_VPE_OMX_IMAGE_DECODER, VPE_OMX_IMAGE_DECODER);
45   strcpy(L_VPE_OMX_EGL_REND, VPE_OMX_EGL_REND);
46 }
47
48 ImageOMX::~ImageOMX()
49 {
50
51 }
52
53 void ImageOMX::init()
54 {
55  // AllocateCodecsOMX();
56 }
57
58 void ImageOMX::shutdown()
59 {
60         LogNT::getInstance()->debug(TAG, "shutdown");
61         //DeAllocateCodecsOMX();
62 }
63
64
65
66
67
68 OMX_ERRORTYPE ImageOMX::EmptyBufferDone_OMX(OMX_IN OMX_HANDLETYPE /*hcomp*/,OMX_IN OMX_PTR /*appdata*/,OMX_IN OMX_BUFFERHEADERTYPE* buffer){
69
70         //LogNT::getInstance()->info(TAG, "EmptyBufferDone");
71         ImageOMX* image = static_cast<ImageOMX*>(buffer->pAppPrivate);
72         image->ReturnEmptyOMXBuffer(buffer);
73         return OMX_ErrorNone;
74
75 }
76
77 void ImageOMX::ReturnEmptyOMXBuffer(OMX_BUFFERHEADERTYPE* buffer){
78         input_bufs_omx_mutex.lock();
79         /*if (buffer->pBuffer) {
80                 free(buffer->pBuffer);
81                 buffer->pBuffer = NULL;
82         }*/
83         buffer->nAllocLen= 0;
84         //LogNT::getInstance()->info(TAG, "ReturnEmptyOMXBuffer {}",input_bufs_omx_free.size());
85         input_bufs_omx_free.push_back(buffer);
86         //LogNT::getInstance()->info(TAG, "ReturnEmptyOMXBuffer {}",input_bufs_omx_free.size());
87         input_bufs_omx_mutex.unlock();
88         VideoOMX* video = static_cast<VideoOMX*>(Video::getInstance());
89
90         video->signalOmx();
91 }
92
93 OMX_ERRORTYPE ImageOMX::FillBufferDone_OMX(OMX_IN OMX_HANDLETYPE /*hcomp*/, OMX_IN OMX_PTR /*appdata*/,OMX_IN OMX_BUFFERHEADERTYPE* buffer) {
94          LogNT::getInstance()->info(TAG, "FillBufferDone");
95          ImageOMX* image = static_cast<ImageOMX*>(buffer->pAppPrivate);
96          image->ReturnFillOMXBuffer(buffer);
97         return OMX_ErrorNone;
98 }
99
100 void ImageOMX::ReturnFillOMXBuffer(OMX_BUFFERHEADERTYPE* /*buffer*/)
101  {
102          //input_bufs_omx_mutex.lock();
103          omx_egl_filled = true;
104         //output_bufs_omx_full.push_back(buffer);
105         //input_bufs_omx_mutex.unlock();
106     VideoOMX* video = static_cast<VideoOMX*>(Video::getInstance());
107          video->signalOmx();
108  }
109
110
111 /*
112
113 int ImageOMX::play() {
114         if (!initted)
115                 return 0;
116         lastAType=MPTYPE_MPEG_Image;
117         Log::getInstance()->log("Image", Log::DEBUG, "enter play");
118
119         ((VideoOMX*)Video::getInstance())->interlaceSwitch4Demux(); // switch resolution if necessary
120
121         if (!AllocateCodecsOMX()) {
122                 return 0;
123         }
124         return 1;
125 }*/
126
127
128
129
130
131 int ImageOMX::AllocateCodecsOMX(unsigned char * buffer, unsigned int length)
132 {
133         OMX_ERRORTYPE error;
134         static OMX_CALLBACKTYPE callbacks= {&VideoOMX::EventHandler_OMX,&EmptyBufferDone_OMX,&FillBufferDone_OMX};
135
136         //LogNT::getInstance()->info(TAG, "Allocate Codecs OMX");
137         //Clock, move later to Image
138         VideoOMX* video = static_cast<VideoOMX*>(Video::getInstance());
139
140         OMX_PORT_PARAM_TYPE p_param;
141         memset(&p_param,0,sizeof(p_param));
142         p_param.nSize=sizeof(p_param);
143         p_param.nVersion.nVersion=OMX_VERSION;
144
145
146         video->LockClock();
147
148
149         error = OMX_GetHandle(&omx_imag_decode, L_VPE_OMX_IMAGE_DECODER, NULL, &callbacks);
150         if (error != OMX_ErrorNone) {
151                 LogNT::getInstance()->debug(TAG,
152                                 "Init OMX Image decoder failed %x", error);
153                 video->UnlockClock();
154                 return 0;
155         }
156
157
158
159         error = OMX_GetParameter(omx_imag_decode, OMX_IndexParamImageInit, &p_param);
160         if (error != OMX_ErrorNone) {
161                 LogNT::getInstance()->debug(TAG,
162                                 "Init OMX Image rend OMX_GetParameter failed %x", error);
163                 video->UnlockClock();
164                 return 0;
165         }
166         omx_image_input_port = p_param.nStartPortNumber;
167         omx_image_output_port = p_param.nStartPortNumber+1;
168
169
170
171
172         OMX_IMAGE_PARAM_PORTFORMATTYPE ft_type;
173         memset(&ft_type,0,sizeof(ft_type));
174         ft_type.nSize=sizeof(ft_type);
175         ft_type.nVersion.nVersion=OMX_VERSION;
176
177         ft_type.nPortIndex=omx_image_input_port;
178
179         switch (curformat)
180         {
181         case Jpeg: ft_type.eCompressionFormat=OMX_IMAGE_CodingJPEG;
182         break;
183         case PNG: ft_type.eCompressionFormat=OMX_IMAGE_CodingPNG;
184         break;
185
186         case Unsupported:
187           ;
188         }
189
190
191         error=OMX_SetParameter(omx_imag_decode,OMX_IndexParamImagePortFormat,&ft_type);
192         if (error!=OMX_ErrorNone){
193                 LogNT::getInstance()->debug(TAG, "Init OMX_IndexParamVImagePortFormat failed %x", error);
194                 video->UnlockClock();
195                 return 0;
196         }
197
198         if (!video->DisablePort(omx_imag_decode,omx_image_input_port) || !video->DisablePort(omx_imag_decode,omx_image_output_port)) {
199                 LogNT::getInstance()->debug(TAG, "Disable Ports OMX Image decoder failed");
200                 video->UnlockClock();
201                 return 0;
202         }
203
204
205         if (!video->ChangeComponentState(omx_imag_decode,OMX_StateIdle)) {
206                 LogNT::getInstance()->debug(TAG, "image decode idle ChangeComponentState");
207                 video->UnlockClock();
208                 return 0;
209         }
210
211
212
213         if (!PrepareInputBufsOMX(true, buffer, length)) {
214                 video->UnlockClock();
215                 LogNT::getInstance()->debug(TAG, "prepare input bufs failed");
216                 return 0;
217         }
218
219
220
221
222
223
224
225         if (!video->ChangeComponentState(omx_imag_decode,OMX_StateExecuting)) {
226                 LogNT::getInstance()->debug(TAG, "omx_image_decode ChangeComponentState Execute");
227                 video->UnlockClock();
228                 return 0;
229         }
230
231
232
233
234         if (!video->EnablePort(omx_imag_decode,omx_image_input_port,false)
235                                         ) {
236                 LogNT::getInstance()->debug(TAG, "Enable Ports OMXdecoder inputfailed");
237                 video->UnlockClock();
238                 return 0;
239         }
240
241
242
243
244         video->UnlockClock();
245         omx_running=true;
246
247
248
249         //LogNT::getInstance()->debug(TAG, "Allocate Codecs OMX finished");
250
251         return 1;
252 }
253
254
255
256
257
258
259 unsigned char* ImageOMX::decodePicture(LoadIndex index, unsigned char * buffer, unsigned int length, bool freemem)
260 {
261         if (pictInfValid) return buffer; // does support only one image at a Time;
262 //      LogNT::getInstance()->debug(TAG,
263 //                                      "decodePicture 1");
264         EGLPictureCreator * pictcreat =dynamic_cast<EGLPictureCreator*>(Osd::getInstance());
265         curformat=Unsupported;
266         if (buffer[0]== 0xff && buffer[1] ==0xd8) curformat=Jpeg;
267         if (buffer[0]== 0x89 && buffer[1] ==0x50 && buffer[2] ==0x4e) curformat=PNG;
268
269         if (curformat == Unsupported)   return buffer; // Jpeg magic numbers
270 //      LogNT::getInstance()->debug(TAG,
271 //                                              "decodePicture 2");
272         VideoOMX* video = static_cast<VideoOMX*>(Video::getInstance());
273
274
275         if (!pictcreat) return NULL;
276         int oldcancelstate;
277         int oldcanceltype;
278         pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &oldcancelstate);
279         pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, &oldcanceltype);
280
281         if (!AllocateCodecsOMX(buffer,length)) {
282                 DeAllocateCodecsOMX();
283                 pthread_setcancelstate(oldcancelstate, NULL);
284                 pthread_setcanceltype(oldcanceltype, NULL);
285                 return NULL;
286         }
287         bool ret=intDecodePicture(index, buffer, length, pictcreat, video);
288         DeAllocateCodecsOMX();
289         pthread_setcancelstate(oldcancelstate, NULL);
290         pthread_setcanceltype(oldcanceltype, NULL);
291         if (ret && freemem) free(buffer);
292
293         if (ret) return NULL;
294         else return buffer;
295 }
296
297
298 bool ImageOMX::intDecodePicture(LoadIndex index, unsigned char* /* buffer */, unsigned int length, EGLPictureCreator* pictcreat, VideoOMX *video)
299 {
300         static OMX_CALLBACKTYPE callbacks= {&VideoOMX::EventHandler_OMX,&EmptyBufferDone_OMX,&FillBufferDone_OMX};
301
302         // Use Buffer
303         OMX_BUFFERHEADERTYPE * bufhead;
304
305         input_bufs_omx_mutex.lock();
306         int count =0;
307         while (input_bufs_omx_free.size()==0) {
308                 input_bufs_omx_mutex.unlock();
309                 //LogNT::getInstance()->debug(TAG, "DMP mark 6");
310                 //LogNT::getInstance()->debug(TAG, "Deliver MediaPacket no free sample");
311                 //return 0; // we do not have a free media sample
312
313                 count++;
314                 if (count>100) return false;
315                 MILLISLEEP(10);
316
317                 input_bufs_omx_mutex.lock();
318
319         }
320         bufhead=input_bufs_omx_free.front();
321         bufhead->nFilledLen=length;
322         //bufhead->nAllocLen= length;
323         bufhead->nOffset=0;
324         bufhead->nTimeStamp=VideoOMX::intToOMXTicks(0);
325         //bufhead->pBuffer=buffer;
326         bufhead->pAppPrivate=this;
327         input_bufs_omx_free.pop_front();
328         input_bufs_omx_mutex.unlock();
329
330
331         bufhead->nFilledLen=length;//bufhead->nAllocLen;
332         bufhead->nFlags=OMX_BUFFERFLAG_EOS;
333         video->ProtOMXEmptyThisBuffer(omx_imag_decode, bufhead);
334
335
336
337         video->LockClock();
338 //      LogNT::getInstance()->debug(TAG,
339 //                      "decodePicture 3");
340
341         video->WaitForEvent(omx_imag_decode,OMX_EventPortSettingsChanged);
342
343         OMX_ERRORTYPE error;
344
345         OMX_PARAM_PORTDEFINITIONTYPE port_def_type;
346         memset(&port_def_type,0,sizeof(port_def_type));
347         port_def_type.nSize=sizeof(port_def_type);
348         port_def_type.nVersion.nVersion=OMX_VERSION;
349         port_def_type.nPortIndex=omx_image_output_port;
350 //      LogNT::getInstance()->debug(TAG,
351 //                      "decodePicture 3a");
352
353         error=OMX_GetParameter(omx_imag_decode,OMX_IndexParamPortDefinition, &port_def_type);
354         if (error != OMX_ErrorNone) {
355                 LogNT::getInstance()->debug(TAG,
356                                 "OMX_IndexParamPortDefinition fix failed {:#x}", error);
357                 video->UnlockClock();
358                 return false;
359         }
360 //      LogNT::getInstance()->debug(TAG,
361 //                      "decodePicture 4");
362
363
364
365
366
367
368
369
370 /*
371         video->DisablePort(omx_imag_decode,omx_image_output_port,false);
372         LogNT::getInstance()->debug(TAG,
373                         "decodePicture 5");
374
375         if ( !video->CommandFinished(omx_imag_decode,OMX_CommandPortDisable,omx_image_output_port)) {
376                 video->UnlockClock();
377                 LogNT::getInstance()->debug(TAG, "commandfinishes end iop");
378                 return false;
379         }*/
380
381         switch (curformat)
382         {
383         case Jpeg:
384                 port_def_type.format.image.eColorFormat = OMX_COLOR_FormatYUV420PackedPlanar;
385                 port_def_type.format.image.nSliceHeight = 16;
386                 port_def_type.format.image.nStride = 0;
387                 break;
388         case PNG:
389                 //port_def_type.format.image.eColorFormat = OMX_COLOR_FormatYUV420PackedPlanar;
390                 //port_def_type.format.image.nSliceHeight = 32;
391                 //port_def_type.format.image.nStride = 0;
392                 port_def_type.format.image.nFrameHeight+=-(port_def_type.format.image.nFrameHeight%32); // The OpenMax png part is broken for the last slice
393                 // so we cut the broken part, not nice but works
394                 break;
395
396         case Unsupported:
397                 ;
398         }
399
400
401
402
403
404         error = OMX_SetParameter(omx_imag_decode, OMX_IndexParamPortDefinition,
405                         &port_def_type);
406         if (error != OMX_ErrorNone) {
407                 LogNT::getInstance()->debug(TAG,
408                                 "Set OMX_IndexParamPortDefinition1 failed {:#x}", error);
409                 video->UnlockClock();
410                 return false;
411         }
412
413
414 //      Log::getInstance()->log("Image", Log::DEBUG,
415 //                      "decodePicture 5 6");
416         error=OMX_GetHandle(&omx_egl_render,L_VPE_OMX_EGL_REND,NULL,&callbacks);
417
418         if (error!=OMX_ErrorNone){
419                 LogNT::getInstance()->debug(TAG, "Init OMX EGL renderer failed {:#x}", error);
420                 video->UnlockClock();
421                 return false;
422         }
423
424         OMX_PORT_PARAM_TYPE p_param;
425         memset(&p_param,0,sizeof(p_param));
426         p_param.nSize=sizeof(p_param);
427         p_param.nVersion.nVersion=OMX_VERSION;
428
429         error=OMX_GetParameter(omx_egl_render,OMX_IndexParamVideoInit,&p_param);
430         if (error!=OMX_ErrorNone){
431                 LogNT::getInstance()->debug(TAG, "Init OMX EGL renderer OMX_GetParameter failed {:#x}", error);
432                 video->UnlockClock();
433                 return false;
434         }
435         omx_egl_input_port=p_param.nStartPortNumber;
436         omx_egl_output_port=p_param.nStartPortNumber+1;
437
438
439
440
441         if (!video->DisablePort(omx_egl_render,omx_egl_input_port) || !video->DisablePort(omx_egl_render,omx_egl_output_port)) {
442                 LogNT::getInstance()->debug(TAG, "Disable Ports OMX Image decoder failed");
443                 video->UnlockClock();
444                 return false;
445         }
446
447
448         if (!video->ChangeComponentState(omx_egl_render,OMX_StateIdle)) {
449                 LogNT::getInstance()->debug(TAG, "egl render idle ChangeComponentState");
450                 video->UnlockClock();
451                 return false;
452         }
453
454
455
456         //Setuo chain
457
458 /*      if ( !video->CommandFinished(omx_egl_render,OMX_CommandPortDisable,omx_egl_input_port)) {
459                 video->UnlockClock();
460                 LogNT::getInstance()->debug(TAG, "commandfinishes end eip");
461                 return false;
462         }*/
463
464
465
466
467         /*      port_def_type.nPortIndex=omx_egl_input_port;
468         error = OMX_SetParameter(omx_egl_render, OMX_IndexParamPortDefinition,
469                                 &port_def_type);
470         if (error != OMX_ErrorNone) {
471                 LogNT::getInstance()->debug(TAG,
472                                 "Set OMX_IndexParamPortDefinition3 failed {:#x}", error);
473                 video->UnlockClock();
474                 pthread_setcancelstate(oldcancelstate, NULL);
475                 pthread_setcanceltype(oldcanceltype, NULL);
476                 return false;
477         }*/
478
479         pictInf.width = port_def_type.format.image.nFrameWidth;
480         pictInf.height = port_def_type.format.image.nFrameHeight;
481         pictInf.decoder = this;
482         pictInf.type = OsdVector::PictureInfo::RGBAMemBlock;
483         pictInf.lindex = index;
484
485
486         port_def_type.nPortIndex=omx_egl_output_port;
487
488         error=OMX_GetParameter(omx_egl_render,OMX_IndexParamPortDefinition, &port_def_type);
489         if (error != OMX_ErrorNone) {
490                 LogNT::getInstance()->debug(TAG,
491                                 "OMX_IndexParamPortDefinition fix failed {:#x}", error);
492                 video->UnlockClock();
493                 return false;
494         }
495
496
497
498         port_def_type.nBufferCountActual = 1;
499         EGLDisplay egl_display;
500         if (!pictcreat->getEGLPicture(pictInf, &egl_display)) {
501                 LogNT::getInstance()->debug(TAG,
502                                 "getEGLPict failed");
503                 video->UnlockClock();
504                 return false;
505         }
506         LogNT::getInstance()->debug(TAG,
507                         "getEGLPict {:#x}",pictInf.reference);
508
509         port_def_type.format.video.pNativeWindow = egl_display;
510         error = OMX_SetParameter(omx_egl_render, OMX_IndexParamPortDefinition,
511                         &port_def_type);
512         if (error != OMX_ErrorNone) {
513                 LogNT::getInstance()->debug(TAG,
514                                 "Set OMX_IndexParamPortDefinition3 failed {:#x}", error);
515                 video->UnlockClock();
516                 return false;
517         }
518
519
520
521
522
523
524
525
526
527
528         error=OMX_SetupTunnel(omx_imag_decode,omx_image_output_port,omx_egl_render,omx_egl_input_port);
529         if (error!=OMX_ErrorNone){
530                 LogNT::getInstance()->debug(TAG, "OMX_Setup tunnel decode to egl rend failed");
531                 video->UnlockClock();
532                 return 0;
533         }
534
535         if (!video->EnablePort(omx_imag_decode,omx_image_output_port,false) || !video->EnablePort(omx_egl_render,omx_egl_input_port,false)
536         ) {
537                 LogNT::getInstance()->debug(TAG, "Enable Ports OMXdecoder rend failed");
538                 video->UnlockClock();
539                 return 0;
540         }
541
542         if ( !video->CommandFinished(omx_imag_decode,OMX_CommandPortEnable,omx_image_output_port)) {
543                 video->UnlockClock();
544                 LogNT::getInstance()->debug(TAG, "commandfinishes end iop");
545                 return 0;
546         }
547
548         if ( !video->CommandFinished(omx_egl_render,OMX_CommandPortEnable,omx_egl_input_port)) {
549                 video->UnlockClock();
550                 LogNT::getInstance()->debug(TAG, "commandfinishes end eip");
551                 return 0;
552         }
553
554 //      LogNT::getInstance()->debug(TAG,
555 //                      "decodePicture 7");
556         video->WaitForEvent(omx_egl_render,OMX_EventPortSettingsChanged);
557
558         LogNT::getInstance()->debug(TAG,
559                         "decodePicture 8");
560
561
562
563
564
565
566
567         error=OMX_SendCommand(omx_egl_render/*dec*/,OMX_CommandPortEnable,omx_egl_output_port/*codec*/,0);
568         if (error!=OMX_ErrorNone){
569                 LogNT::getInstance()->debug(TAG, "Prepare omx_egl_output_port Send Command to enable port {:#x}", error);
570                 return 0;
571         }
572
573
574         error=OMX_UseEGLImage(omx_egl_render/*dec*/,&buf_head_egl,omx_egl_output_port/*codec*/, this, pictInf.reference);
575         if (error!=OMX_ErrorNone){
576                 LogNT::getInstance()->debug(TAG, "Use OMX_UseEGLImage failed {:#x}", error);
577                 video->UnlockClock();
578                 return false;
579         }
580         buf_head_egl->pAppPrivate=this;
581
582 //      LogNT::getInstance()->debug(TAG,
583 //                      "decodePicture 8 a");
584
585         video->EnablePort(omx_imag_decode,omx_image_output_port,false);
586
587         if (!video->CommandFinished(omx_egl_render/*dec*/,OMX_CommandPortEnable, omx_egl_output_port /*codec*/)) {
588                 video->UnlockClock();
589                 return false;
590         }
591
592
593
594
595         LogNT::getInstance()->debug(TAG,
596                         "decodePicture 8 end");
597
598         if (!video->ChangeComponentState(omx_egl_render,OMX_StateExecuting)) {
599                 LogNT::getInstance()->debug(TAG, "omx_egl_rendd ChangeComponentState Execute");
600                 video->UnlockClock();
601                 return false;
602         }
603
604
605 //      LogNT::getInstance()->debug(TAG,
606 //                      "decodePicture 9");
607         //video->EnablePort(omx_egl_render,omx_egl_output_port,false);
608
609 //      LogNT::getInstance()->debug(TAG,
610 //                      "decodePicture 10");
611
612         omx_egl_filled = false;
613         error = OMX_FillThisBuffer(omx_egl_render, buf_head_egl);
614
615         if (error!=OMX_ErrorNone){
616                 LogNT::getInstance()->debug(TAG, "OMX_FillThisBuffer failed {:#x}", error);
617                 video->UnlockClock();
618                 return false;
619         }
620         count =1;
621         video->UnlockClock();
622         while (!omx_egl_filled) {
623
624                 count++;
625                 if (count>500) {
626                         LogNT::getInstance()->debug(TAG, "No one filled my buffer");
627                         return false;
628                 }
629                 MILLISLEEP(1);
630
631
632         }
633         omx_egl_filled = false;
634
635 //      LogNT::getInstance()->debug(TAG,
636 //                      "decodePicture left");
637
638
639
640         pictInfValid=true;
641         return true;
642
643 }
644
645 bool ImageOMX::getDecodedPicture(struct OsdVector::PictureInfo& pict_inf)
646 {
647         if (!pictInfValid) return false;
648         pict_inf=pictInf;
649         pictInfValid = false;
650         return true;
651 }
652
653 void ImageOMX::freeReference(void* /* ref */)
654 {
655 }
656
657 int ImageOMX::PrepareInputBufsOMX(bool setportdef, unsigned char * buffer, unsigned int length) //needs to be called with locvke omx clock mutex
658 {
659         VideoOMX* video = static_cast<VideoOMX*>(Video::getInstance());
660         OMX_ERRORTYPE error;
661         OMX_PARAM_PORTDEFINITIONTYPE port_def_type;
662         memset(&port_def_type,0,sizeof(port_def_type));
663         port_def_type.nSize=sizeof(port_def_type);
664         port_def_type.nVersion.nVersion=OMX_VERSION;
665         port_def_type.nPortIndex=omx_image_input_port;//omx_codec_input_port;
666
667         error=OMX_GetParameter(omx_imag_decode/*dec*/,OMX_IndexParamPortDefinition, &port_def_type);
668
669         if (error!=OMX_ErrorNone){
670                         LogNT::getInstance()->debug(TAG, "Get OMX OMX_IndexParamPortDefinition failed {:#x}", error);
671         }
672
673
674         if (setportdef) {
675                 port_def_type.nBufferCountActual=port_def_type.nBufferCountMin;
676                 port_def_type.nBufferSize=max(port_def_type.nBufferSize,length); // for transcoder important
677
678                 error=OMX_SetParameter(omx_imag_decode/*dec*/,OMX_IndexParamPortDefinition, &port_def_type);
679
680                 if (error!=OMX_ErrorNone){
681                         LogNT::getInstance()->debug(TAG, "Set OMX OMX_IndexParamPortDefinition failed {:#x}", error);
682                 }
683         }
684
685
686         error=OMX_SendCommand(omx_imag_decode/*dec*/,OMX_CommandPortEnable,omx_image_input_port/*codec*/,0);
687         if (error!=OMX_ErrorNone){
688                 LogNT::getInstance()->debug(TAG, "Prepare Input bufs Send Command to enable port {:#x}", error);
689                 return 0;
690         }
691
692         input_bufs_omx_mutex.lock();
693         for (unsigned int i=0; i< port_def_type.nBufferCountActual;i++) {
694                 OMX_BUFFERHEADERTYPE *buf_head=NULL;
695                 error=OMX_UseBuffer(omx_imag_decode/*dec*/,&buf_head,omx_image_input_port/*codec*/,this,port_def_type.nBufferSize, buffer);
696                 if (error!=OMX_ErrorNone){
697                         LogNT::getInstance()->debug(TAG, "Use OMX_UseBuffer failed {:#x}", error);
698                         input_bufs_omx_mutex.unlock();
699                         return 0;
700                 }
701                 input_bufs_omx_all.push_back(buf_head);
702                 input_bufs_omx_free.push_back(buf_head);
703         }
704         omx_first_frame=true;
705
706
707         input_bufs_omx_mutex.unlock();
708
709         if (!video->CommandFinished(omx_imag_decode/*dec*/,OMX_CommandPortEnable, omx_image_input_port /*codec*/)) {
710                 return 0;
711         }
712
713         return 1;
714 }
715
716 int ImageOMX::DestroyInputBufsOMX() //call with clock mutex locked
717 {
718         OMX_ERRORTYPE error;
719
720         input_bufs_omx_mutex.lock();
721         for (UINT i=0; i< input_bufs_omx_all.size();i++) {
722                 LogNT::getInstance()->debug(TAG, "OMX_FreeBuffer mark");
723                 //if (input_bufs_omx_all[i]->pBuffer) free(input_bufs_omx_all[i]->pBuffer);
724                 input_bufs_omx_all[i]->pBuffer=NULL;
725                 error=OMX_FreeBuffer(omx_imag_decode/*dec*/,omx_image_input_port/*codec*/,input_bufs_omx_all[i]);
726                 if (error!=OMX_ErrorNone){
727                         LogNT::getInstance()->debug(TAG, "Use OMX_FreeBuffer failed {:#x}", error);
728                         input_bufs_omx_mutex.unlock();
729                         return 0;
730                 }
731
732         }
733         input_bufs_omx_all.clear();
734         input_bufs_omx_free.clear();
735         input_bufs_omx_mutex.unlock();
736
737         return 1;
738 }
739
740 int ImageOMX::DestroyInputBufsOMXwhilePlaying() //call with clock mutex locked
741 {
742         //OMX_ERRORTYPE error;
743
744         input_bufs_omx_mutex.lock();
745         while (input_bufs_omx_all.size()>0) {
746                 if (input_bufs_omx_free.size()>0) {
747                         // Destroy one buffer
748                         std::vector<OMX_BUFFERHEADERTYPE*>::iterator itty=input_bufs_omx_all.begin();
749                         OMX_BUFFERHEADERTYPE* cur_buf=input_bufs_omx_free.front();
750                         for (; itty!= input_bufs_omx_all.end();itty++) {
751                                 if ((*itty)==cur_buf) {
752                                         input_bufs_omx_all.erase(itty);
753                                         input_bufs_omx_free.pop_front();
754                                         break;
755                                 }
756                         }
757                 } else {
758                         input_bufs_omx_mutex.unlock();
759                         MILLISLEEP(5);
760                         input_bufs_omx_mutex.lock();
761                 }
762         }
763
764         LogNT::getInstance()->debug(TAG, "DestroyInputBufsOMXwhilePlaying {} {}", input_bufs_omx_all.size(),input_bufs_omx_free.size());
765         input_bufs_omx_mutex.unlock();
766         return 1;
767 }
768
769
770 int ImageOMX::DeAllocateCodecsOMX()
771 {
772         OMX_ERRORTYPE error;
773         omx_running=false;
774         VideoOMX* video = static_cast<VideoOMX*>(Video::getInstance());
775 //       LogNT::getInstance()->debug(TAG, "enter deallocatecodecsomx");
776
777
778
779 //   LogNT::getInstance()->debug(TAG, "deallocatecodecsomx mark 1");
780
781 //   LogNT::getInstance()->debug(TAG, "deallocatecodecsomx mark 2");
782
783    video->LockClock();
784         if (omx_imag_decode/*dec*/) {
785
786
787                 if (!video->ChangeComponentState(omx_imag_decode,OMX_StateIdle)) {
788                         LogNT::getInstance()->debug(TAG, "omx_imag_decode ChangeComponentState");
789                 }
790
791                 if (omx_egl_render) {
792
793                         if (!video->ChangeComponentState(omx_egl_render,OMX_StateIdle)) {
794                                 LogNT::getInstance()->debug(TAG, "omx_egl_render ChangeComponentState");
795                         }
796                         /*if (!video->ChangeComponentState(omx_egl_render,OMX_StateLoaded,false)) {
797                                 LogNT::getInstance()->debug(TAG, "omx_egl_render ChangeComponentState");
798                         }*/
799                 }
800
801         /*      if (!video->ChangeComponentState(omx_imag_decode,OMX_StateLoaded,false)) {
802                         LogNT::getInstance()->debug(TAG, "omx_imag_decode ChangeComponentState");
803                 }*/
804
805
806
807         // TODO proper deinit sequence
808                 // first flush all buffers
809
810
811
812 //              LogNT::getInstance()->debug(TAG, "deallocatecodecsomx mark 3");
813
814                 error=OMX_SendCommand(omx_imag_decode,OMX_CommandFlush, omx_image_output_port, NULL);
815                 if (error!=OMX_ErrorNone) {
816                         LogNT::getInstance()->debug(TAG, "OMX_Flush rend in failed {:#x}", error);
817
818                 }
819
820                 if (omx_egl_render) {
821
822                         if (!video->ChangeComponentState(omx_egl_render,OMX_StateIdle)) {
823                                 LogNT::getInstance()->debug(TAG, "omx_egl_render ChangeComponentState");
824                         }
825
826 //                      LogNT::getInstance()->debug(TAG, "deallocatecodecsomx mark 4");
827
828                         error=OMX_SendCommand(omx_egl_render,OMX_CommandFlush, omx_egl_input_port, NULL);
829                         if (error!=OMX_ErrorNone) {
830                                 LogNT::getInstance()->debug(TAG, "OMX_Flush rend in failed {:#x}", error);
831
832                         }
833
834 //                      LogNT::getInstance()->debug(TAG, "deallocatecodecsomx mark 5");
835
836                         error=OMX_SendCommand(omx_egl_render,OMX_CommandFlush, omx_egl_output_port, NULL);
837                         if (error!=OMX_ErrorNone) {
838                                 LogNT::getInstance()->debug(TAG, "OMX_Flush rend in failed {:#x}", error);
839
840                         }
841
842 //                      Log::getInstance()->log("Image", Log::DEBUG, "deallocatecodecsomx mark 6");
843
844                         if (!video->CommandFinished(omx_egl_render,OMX_CommandFlush,omx_egl_input_port) ||
845                                         !video->CommandFinished(omx_egl_render,OMX_CommandFlush,omx_egl_output_port)) {
846                                 LogNT::getInstance()->debug(TAG, "flush cmd clock shed failed");
847                         }
848 //                      LogNT::getInstance()->debug(TAG, "deallocatecodecsomx mark 6 a");
849                 }
850                 error=OMX_SendCommand(omx_imag_decode,OMX_CommandFlush, omx_image_input_port, NULL);
851                 if (error!=OMX_ErrorNone) {
852                         LogNT::getInstance()->debug(TAG, "OMX_Flush rend in failed {:#x}", error);
853
854                 }
855
856                 if (buf_head_egl) {
857                         error=OMX_FreeBuffer(omx_egl_render/*dec*/, omx_egl_output_port/*codec*/,buf_head_egl);
858                         if (error!=OMX_ErrorNone){
859                                 LogNT::getInstance()->debug(TAG, "Use OMX_FreeBuffer 2 failed {:#x}", error);
860                         }
861                 }
862
863                 buf_head_egl=NULL;
864
865
866 //              LogNT::getInstance()->debug(TAG, "deallocatecodecsomx mark 6 b");
867
868                 if (!video->CommandFinished(omx_imag_decode,OMX_CommandFlush,omx_image_input_port) ||
869                                 !video->CommandFinished(omx_imag_decode,OMX_CommandFlush,omx_image_output_port) ) {
870                         LogNT::getInstance()->debug(TAG, "flush cmd clock shed failed");
871                 }
872
873 //              LogNT::getInstance()->debug(TAG, "deallocatecodecsomx mark 6 c");
874
875
876                 DestroyInputBufsOMX(); //We have to make sure that no buffers are in use
877
878 //              LogNT::getInstance()->debug(TAG, "deallocatecodecsomx mark 7");
879
880                 //todo flushing
881                 if (!video->DisablePort(omx_imag_decode,omx_image_output_port,true)) {
882                         LogNT::getInstance()->debug(TAG, "Disable Tunnel Port failed 1");
883                 }
884
885                 if (omx_egl_render) {
886
887                         if (!video->DisablePort(omx_egl_render,omx_egl_input_port,true)) {
888                                 LogNT::getInstance()->debug(TAG, "Disable Tunnel Port failed 4");
889                         }
890
891
892                         error=OMX_SetupTunnel(omx_imag_decode,omx_image_output_port,NULL,0);
893                         if (error!=OMX_ErrorNone) {
894                                 LogNT::getInstance()->debug(TAG, "OMX_Setup tunnel teardown failed {:#x}", error);
895
896                         }
897
898                         error=OMX_SetupTunnel(omx_egl_render,omx_egl_input_port,NULL,0);
899                         if (error!=OMX_ErrorNone) {
900                                 LogNT::getInstance()->debug(TAG, "OMX_Setup tunnel teardown failed {:#x}", error);
901
902                         }
903                 }
904
905
906 //              LogNT::getInstance()->debug(TAG, "deallocatecodecsomx mark 8");
907
908
909                 //error=OMX_FreeHandle(omx_aud_dec);
910                 error=OMX_FreeHandle(omx_imag_decode);
911                 if (error!=OMX_ErrorNone) {
912                         LogNT::getInstance()->debug(TAG, "FreeHandle failed {}", error);
913                 }
914                 if (omx_egl_render) {
915                         error=OMX_FreeHandle(omx_egl_render);
916                         if (error!=OMX_ErrorNone) {
917                                 LogNT::getInstance()->debug(TAG, "FreeHandle failed {}", error);
918                         }
919                 }
920                 video->UnlockClock();
921
922                 video->clearEventsForComponent(omx_imag_decode);
923                 video->clearEventsForComponent(omx_egl_render); // removes spurious error messages
924                 omx_imag_decode/*dec*/=NULL;
925                 omx_egl_render/*dec*/=NULL;
926
927         } else  {
928
929                 video->UnlockClock();
930         }
931 //        LogNT::getInstance()->debug(TAG, "leave deallocate codecs OMX");
932
933         return 1;
934 }