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