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