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