2 * Copyright (C) 2013 Team XBMC
5 * This Program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2, or (at your option)
10 * This Program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with XBMC; see the file COPYING. If not, see
17 * <http://www.gnu.org/licenses/>.
20 /***************************************************************************/
22 //#define DEBUG_VERBOSE 1
25 #include "system_gl.h"
27 #include "StageFrightVideo.h"
28 #include "StageFrightVideoPrivate.h"
30 #include "guilib/GraphicContext.h"
32 #include "utils/log.h"
33 #include "utils/fastmemcpy.h"
34 #include "threads/Thread.h"
35 #include "threads/Event.h"
36 #include "Application.h"
37 #include "ApplicationMessenger.h"
38 #include "settings/AdvancedSettings.h"
39 #include "android/jni/Build.h"
41 #include "xbmc/guilib/FrameBufferObject.h"
44 #include <EGL/eglext.h>
45 #include "windowing/egl/EGLWrapper.h"
46 #include "windowing/WindowingFactory.h"
50 #define OMX_QCOM_COLOR_FormatYVU420SemiPlanar 0x7FA30C00
51 #define OMX_TI_COLOR_FormatYUV420PackedSemiPlanar 0x7F000100
53 #define CLASSNAME "CStageFrightVideo"
55 #define EGL_NATIVE_BUFFER_ANDROID 0x3140
56 #define EGL_IMAGE_PRESERVED_KHR 0x30D2
58 using namespace android;
60 static int64_t pts_dtoi(double pts)
62 return (int64_t)(pts);
65 static double pts_itod(int64_t pts)
70 /***********************************************************/
72 class CStageFrightMediaSource : public MediaSource
75 CStageFrightMediaSource(CStageFrightVideoPrivate *priv, sp<MetaData> meta)
81 virtual sp<MetaData> getFormat()
86 virtual status_t start(MetaData *params)
91 virtual status_t stop()
96 virtual status_t read(MediaBuffer **buffer,
97 const MediaSource::ReadOptions *options)
102 int64_t time_us = -1;
103 MediaSource::ReadOptions::SeekMode mode;
105 if (options && options->getSeekTo(&time_us, &mode))
107 #if defined(DEBUG_VERBOSE)
108 CLog::Log(LOGDEBUG, "%s: reading source(%d): seek:%llu\n", CLASSNAME,p->in_queue.size(), time_us);
113 #if defined(DEBUG_VERBOSE)
114 CLog::Log(LOGDEBUG, "%s: reading source(%d)\n", CLASSNAME,p->in_queue.size());
119 while (p->in_queue.empty() && p->decode_thread)
120 p->in_condition.wait(p->in_mutex);
122 if (p->in_queue.empty())
124 p->in_mutex.unlock();
128 std::list<Frame*>::iterator it = p->in_queue.begin();
131 *buffer = frame->medbuf;
133 p->in_queue.erase(it);
134 p->in_mutex.unlock();
136 #if defined(DEBUG_VERBOSE)
137 CLog::Log(LOGDEBUG, ">>> exiting reading source(%d); pts:%llu\n", p->in_queue.size(),frame->pts);
146 sp<MetaData> source_meta;
147 CStageFrightVideoPrivate *p;
150 /********************************************/
152 class CStageFrightDecodeThread : public CThread
155 CStageFrightVideoPrivate *p;
158 CStageFrightDecodeThread(CStageFrightVideoPrivate *priv)
159 : CThread("CStageFrightDecodeThread")
165 #if defined(DEBUG_VERBOSE)
166 CLog::Log(LOGDEBUG, "%s: entering decode thread\n", CLASSNAME);
172 #if defined(DEBUG_VERBOSE)
173 CLog::Log(LOGDEBUG, "%s: exited decode thread\n", CLASSNAME);
182 MediaSource::ReadOptions readopt;
185 //SetPriority(THREAD_PRIORITY_ABOVE_NORMAL);
188 #if defined(DEBUG_VERBOSE)
189 unsigned int time = XbmcThreads::SystemClockMillis();
190 CLog::Log(LOGDEBUG, "%s: >>> Handling frame\n", CLASSNAME);
193 frame = (Frame*)malloc(sizeof(Frame));
200 frame->eglimg = EGL_NO_IMAGE_KHR;
201 frame->medbuf = NULL;
204 readopt.setSeekTo(0);
205 p->resetting = false;
207 frame->status = p->decoder->read(&frame->medbuf, &readopt);
208 readopt.clearSeekTo();
210 if (frame->status == OK)
212 if (!frame->medbuf->graphicBuffer().get()) // hw buffers
214 if (frame->medbuf->range_length() == 0)
216 CLog::Log(LOGERROR, "%s - Invalid buffer\n", CLASSNAME);
217 frame->status = VC_ERROR;
219 frame->medbuf->release();
220 frame->medbuf = NULL;
223 frame->format = RENDER_FMT_YUV420P;
226 frame->format = RENDER_FMT_EGLIMG;
229 if (frame->status == OK)
231 frame->width = p->width;
232 frame->height = p->height;
235 sp<MetaData> outFormat = p->decoder->getFormat();
236 outFormat->findInt32(kKeyWidth , &w);
237 outFormat->findInt32(kKeyHeight, &h);
238 frame->medbuf->meta_data()->findInt64(kKeyTime, &(frame->pts));
240 else if (frame->status == INFO_FORMAT_CHANGED)
242 int32_t cropLeft, cropTop, cropRight, cropBottom;
243 sp<MetaData> outFormat = p->decoder->getFormat();
245 outFormat->findInt32(kKeyWidth , &p->width);
246 outFormat->findInt32(kKeyHeight, &p->height);
248 cropLeft = cropTop = cropRight = cropBottom = 0;
249 if (!outFormat->findRect(kKeyCropRect, &cropLeft, &cropTop, &cropRight, &cropBottom))
258 p->width = cropRight - cropLeft + 1;
259 p->height = cropBottom - cropTop + 1;
261 outFormat->findInt32(kKeyColorFormat, &p->videoColorFormat);
262 if (!outFormat->findInt32(kKeyStride, &p->videoStride))
263 p->videoStride = p->width;
264 if (!outFormat->findInt32(kKeySliceHeight, &p->videoSliceHeight))
265 p->videoSliceHeight = p->height;
267 #if defined(DEBUG_VERBOSE)
268 CLog::Log(LOGDEBUG, ">>> new format col:%d, w:%d, h:%d, sw:%d, sh:%d, ctl:%d,%d; cbr:%d,%d\n", p->videoColorFormat, p->width, p->height, p->videoStride, p->videoSliceHeight, cropTop, cropLeft, cropBottom, cropRight);
272 frame->medbuf->release();
273 frame->medbuf = NULL;
279 CLog::Log(LOGERROR, "%s - decoding error (%d)\n", CLASSNAME,frame->status);
281 frame->medbuf->release();
282 frame->medbuf = NULL;
287 if (frame->format == RENDER_FMT_EGLIMG)
289 if (!p->eglInitialized)
291 p->InitializeEGL(frame->width, frame->height);
293 else if (p->texwidth != frame->width || p->texheight != frame->height)
296 p->InitializeEGL(frame->width, frame->height);
299 ANativeWindowBuffer* graphicBuffer = frame->medbuf->graphicBuffer()->getNativeBuffer();
300 native_window_set_buffers_timestamp(p->mVideoNativeWindow.get(), frame->pts * 1000);
301 int err = p->mVideoNativeWindow.get()->queueBuffer(p->mVideoNativeWindow.get(), graphicBuffer);
303 frame->medbuf->meta_data()->setInt32(kKeyRendered, 1);
304 frame->medbuf->release();
305 frame->medbuf = NULL;
306 p->UpdateSurfaceTexture();
310 p->free_mutex.lock();
312 stSlot* cur_slot = p->getFreeSlot();
315 CLog::Log(LOGERROR, "STF: No free output buffers\n");
319 p->fbo.BindToTexture(GL_TEXTURE_2D, cur_slot->texid);
320 p->fbo.BeginRender();
322 glDisable(GL_DEPTH_TEST);
323 //glClear(GL_COLOR_BUFFER_BIT);
325 const GLfloat triangleVertices[] = {
332 glVertexAttribPointer(p->mPositionHandle, 2, GL_FLOAT, GL_FALSE, 0, triangleVertices);
333 glEnableVertexAttribArray(p->mPositionHandle);
335 glUseProgram(p->mPgm);
336 glUniform1i(p->mTexSamplerHandle, 0);
338 glBindTexture(GL_TEXTURE_EXTERNAL_OES, p->mVideoTextureId);
340 GLfloat texMatrix[16];
341 p->GetSurfaceTextureTransformMatrix(texMatrix);
342 glUniformMatrix4fv(p->mTexMatrixHandle, 1, GL_FALSE, texMatrix);
344 glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
346 glBindTexture(GL_TEXTURE_EXTERNAL_OES, 0);
349 glBindTexture(GL_TEXTURE_2D, 0);
351 frame->eglimg = cur_slot->eglimg;
352 p->free_mutex.unlock();
356 #if defined(DEBUG_VERBOSE)
357 CLog::Log(LOGDEBUG, "%s: >>> pushed OUT frame; w:%d, h:%d, img:%p, tm:%d\n", CLASSNAME, frame->width, frame->height, frame->eglimg, XbmcThreads::SystemClockMillis() - time);
361 p->cur_frame = frame;
363 p->out_condition.wait(p->out_mutex);
364 p->out_mutex.unlock();
366 while (!decode_done && !m_bStop);
368 if (p->eglInitialized)
374 /***********************************************************/
376 CStageFrightVideo::CStageFrightVideo(CApplication* application, CApplicationMessenger* applicationMessenger, CWinSystemEGL* windowing, CAdvancedSettings* advsettings)
378 #if defined(DEBUG_VERBOSE)
379 CLog::Log(LOGDEBUG, "%s::ctor: %d\n", CLASSNAME, sizeof(CStageFrightVideo));
381 p = new CStageFrightVideoPrivate;
382 p->m_g_application = application;
383 p->m_g_applicationMessenger = applicationMessenger;
384 p->m_g_Windowing = windowing;
385 p->m_g_advancedSettings = advsettings;
388 CStageFrightVideo::~CStageFrightVideo()
393 bool CStageFrightVideo::Open(CDVDStreamInfo &hints)
395 #if defined(DEBUG_VERBOSE)
396 CLog::Log(LOGDEBUG, "%s::Open\n", CLASSNAME);
399 CSingleLock lock(g_graphicsContext);
401 // stagefright crashes with null size. Trap this...
402 if (!hints.width || !hints.height)
404 CLog::Log(LOGERROR, "%s::%s - %s\n", CLASSNAME, __func__,"null size, cannot handle");
407 p->width = hints.width;
408 p->height = hints.height;
410 if (p->m_g_advancedSettings->m_stagefrightConfig.useSwRenderer)
411 p->quirks |= QuirkSWRender;
413 p->meta = new MetaData;
416 CLog::Log(LOGERROR, "%s::%s - %s\n", CLASSNAME, __func__,"cannot allocate MetaData");
420 const char* mimetype;
424 if (p->m_g_advancedSettings->m_stagefrightConfig.useAVCcodec == 0)
426 mimetype = "video/avc";
427 if ( *(char*)hints.extradata == 1 )
428 p->meta->setData(kKeyAVCC, kTypeAVCC, hints.extradata, hints.extrasize);
431 if (p->m_g_advancedSettings->m_stagefrightConfig.useMP4codec == 0)
433 mimetype = "video/mp4v-es";
435 case CODEC_ID_MPEG2VIDEO:
436 if (p->m_g_advancedSettings->m_stagefrightConfig.useMPEG2codec == 0)
438 mimetype = "video/mpeg2";
443 if (p->m_g_advancedSettings->m_stagefrightConfig.useVPXcodec == 0)
445 mimetype = "video/vp6";
448 if (p->m_g_advancedSettings->m_stagefrightConfig.useVPXcodec == 0)
450 mimetype = "video/x-vnd.on2.vp8";
454 if (p->m_g_advancedSettings->m_stagefrightConfig.useVC1codec == 0)
456 mimetype = "video/vc1";
463 p->meta->setCString(kKeyMIMEType, mimetype);
464 p->meta->setInt32(kKeyWidth, p->width);
465 p->meta->setInt32(kKeyHeight, p->height);
467 android::ProcessState::self()->startThreadPool();
469 p->source = new CStageFrightMediaSource(p, p->meta);
470 p->client = new OMXClient;
472 if (p->source == NULL || p->client == NULL)
477 CLog::Log(LOGERROR, "%s::%s - %s\n", CLASSNAME, __func__,"Cannot obtain source / client");
481 if (p->client->connect() != OK)
487 CLog::Log(LOGERROR, "%s::%s - %s\n", CLASSNAME, __func__,"Cannot connect OMX client");
491 if ((p->quirks & QuirkSWRender) == 0)
492 if (!p->InitSurfaceTexture())
498 CLog::Log(LOGERROR, "%s::%s - %s\n", CLASSNAME, __func__,"Cannot allocate texture");
502 p->decoder = OMXCodec::Create(p->client->interface(), p->meta,
503 false, p->source, NULL,
504 OMXCodec::kHardwareCodecsOnly | (p->quirks & QuirkSWRender ? OMXCodec::kClientNeedsFramebuffer : 0),
505 p->mVideoNativeWindow
508 if (!(p->decoder != NULL && p->decoder->start() == OK))
516 sp<MetaData> outFormat = p->decoder->getFormat();
518 if (!outFormat->findInt32(kKeyWidth, &p->width) || !outFormat->findInt32(kKeyHeight, &p->height)
519 || !outFormat->findInt32(kKeyColorFormat, &p->videoColorFormat))
527 const char *component;
528 if (outFormat->findCString(kKeyDecoderComponent, &component))
530 CLog::Log(LOGDEBUG, "%s::%s - component: %s\n", CLASSNAME, __func__, component);
533 if (!strncmp(component, "OMX.google", 10))
535 // On some platforms, software decoders are returned anyway
536 CLog::Log(LOGERROR, "%s::%s - %s\n", CLASSNAME, __func__,"Blacklisted component (software)");
539 else if (!strncmp(component, "OMX.Nvidia.mp4.decode", 21) && p->m_g_advancedSettings->m_stagefrightConfig.useMP4codec != 1)
541 // Has issues with some XVID encoded MP4. Only fails after actual decoding starts...
542 CLog::Log(LOGERROR, "%s::%s - %s\n", CLASSNAME, __func__,"Blacklisted component (MP4)");
547 int32_t cropLeft, cropTop, cropRight, cropBottom;
548 cropLeft = cropTop = cropRight = cropBottom = 0;
549 if (!outFormat->findRect(kKeyCropRect, &cropLeft, &cropTop, &cropRight, &cropBottom))
558 p->width = cropRight - cropLeft + 1;
559 p->height = cropBottom - cropTop + 1;
562 if (!outFormat->findInt32(kKeyStride, &p->videoStride))
563 p->videoStride = p->width;
564 if (!outFormat->findInt32(kKeySliceHeight, &p->videoSliceHeight))
565 p->videoSliceHeight = p->height;
567 for (int i=0; i<INBUFCOUNT; ++i)
569 p->inbuf[i] = new MediaBuffer(300000);
570 p->inbuf[i]->setObserver(p);
573 p->decode_thread = new CStageFrightDecodeThread(p);
574 p->decode_thread->Create(true /*autodelete*/);
576 #if defined(DEBUG_VERBOSE)
577 CLog::Log(LOGDEBUG, ">>> format col:%d, w:%d, h:%d, sw:%d, sh:%d, ctl:%d,%d; cbr:%d,%d\n", p->videoColorFormat, p->width, p->height, p->videoStride, p->videoSliceHeight, cropTop, cropLeft, cropBottom, cropRight);
584 int CStageFrightVideo::Decode(uint8_t *pData, int iSize, double dts, double pts)
586 #if defined(DEBUG_VERBOSE)
587 unsigned int time = XbmcThreads::SystemClockMillis();
588 CLog::Log(LOGDEBUG, "%s::Decode - d:%p; s:%d; dts:%f; pts:%f\n", CLASSNAME, pData, iSize, dts, pts);
592 int demuxer_bytes = iSize;
593 uint8_t *demuxer_content = pData;
598 frame = (Frame*)malloc(sizeof(Frame));
603 if (p->m_g_advancedSettings->m_stagefrightConfig.useInputDTS)
604 frame->pts = (dts != DVD_NOPTS_VALUE) ? pts_dtoi(dts) : ((pts != DVD_NOPTS_VALUE) ? pts_dtoi(pts) : 0);
606 frame->pts = (pts != DVD_NOPTS_VALUE) ? pts_dtoi(pts) : ((dts != DVD_NOPTS_VALUE) ? pts_dtoi(dts) : 0);
608 // No valid pts? libstagefright asserts on this.
615 frame->medbuf = p->getBuffer(demuxer_bytes);
618 CLog::Log(LOGWARNING, "STF: Cannot get input buffer\n");
623 fast_memcpy(frame->medbuf->data(), demuxer_content, demuxer_bytes);
624 frame->medbuf->meta_data()->clear();
625 frame->medbuf->meta_data()->setInt64(kKeyTime, frame->pts);
628 p->in_queue.push_back(frame);
629 p->in_condition.notify();
630 p->in_mutex.unlock();
633 if (p->inputBufferAvailable() && p->in_queue.size() < INBUFCOUNT)
637 if (p->cur_frame != NULL)
639 #if defined(DEBUG_VERBOSE)
640 CLog::Log(LOGDEBUG, "%s::Decode: pushed IN frame (%d); tm:%d\n", CLASSNAME,p->in_queue.size(), XbmcThreads::SystemClockMillis() - time);
646 bool CStageFrightVideo::ClearPicture(DVDVideoPicture* pDvdVideoPicture)
648 #if defined(DEBUG_VERBOSE)
649 unsigned int time = XbmcThreads::SystemClockMillis();
651 if (pDvdVideoPicture->format == RENDER_FMT_EGLIMG && pDvdVideoPicture->eglimg != EGL_NO_IMAGE_KHR)
652 ReleaseBuffer(pDvdVideoPicture->eglimg);
655 if (p->prev_frame->medbuf)
656 p->prev_frame->medbuf->release();
658 p->prev_frame = NULL;
660 #if defined(DEBUG_VERBOSE)
661 CLog::Log(LOGDEBUG, "%s::ClearPicture (%d)\n", CLASSNAME, XbmcThreads::SystemClockMillis() - time);
667 bool CStageFrightVideo::GetPicture(DVDVideoPicture* pDvdVideoPicture)
669 #if defined(DEBUG_VERBOSE)
670 unsigned int time = XbmcThreads::SystemClockMillis();
671 CLog::Log(LOGDEBUG, "%s::GetPicture\n", CLASSNAME);
672 if (p->cycle_time != 0)
673 CLog::Log(LOGDEBUG, ">>> cycle dur:%d\n", XbmcThreads::SystemClockMillis() - p->cycle_time);
674 p->cycle_time = time;
682 CLog::Log(LOGERROR, "%s::%s - Error getting frame\n", CLASSNAME, __func__);
683 p->out_condition.notify();
684 p->out_mutex.unlock();
688 Frame *frame = p->cur_frame;
689 status = frame->status;
691 pDvdVideoPicture->format = frame->format;
692 pDvdVideoPicture->dts = DVD_NOPTS_VALUE;
693 pDvdVideoPicture->pts = frame->pts;
694 pDvdVideoPicture->iWidth = frame->width;
695 pDvdVideoPicture->iHeight = frame->height;
696 pDvdVideoPicture->iDisplayWidth = frame->width;
697 pDvdVideoPicture->iDisplayHeight = frame->height;
698 pDvdVideoPicture->iFlags = DVP_FLAG_ALLOCATED;
699 pDvdVideoPicture->eglimg = EGL_NO_IMAGE_KHR;
703 CLog::Log(LOGERROR, "%s::%s - Error getting picture from frame(%d)\n", CLASSNAME, __func__,status);
705 frame->medbuf->release();
709 p->out_condition.notify();
710 p->out_mutex.unlock();
714 if (pDvdVideoPicture->format == RENDER_FMT_EGLIMG)
716 pDvdVideoPicture->eglimg = frame->eglimg;
717 if (pDvdVideoPicture->eglimg == EGL_NO_IMAGE_KHR)
718 pDvdVideoPicture->iFlags |= DVP_FLAG_DROPPED;
720 LockBuffer(pDvdVideoPicture->eglimg);
721 #if defined(DEBUG_VERBOSE)
722 CLog::Log(LOGDEBUG, ">>> pic dts:%f, pts:%llu, img:%p, tm:%d\n", pDvdVideoPicture->dts, frame->pts, pDvdVideoPicture->eglimg, XbmcThreads::SystemClockMillis() - time);
725 else if (pDvdVideoPicture->format == RENDER_FMT_YUV420P)
727 pDvdVideoPicture->color_range = 0;
728 pDvdVideoPicture->color_matrix = 4;
730 unsigned int luma_pixels = frame->width * frame->height;
731 unsigned int chroma_pixels = luma_pixels/4;
732 uint8_t* data = NULL;
733 if (frame->medbuf && !p->drop_state)
735 data = (uint8_t*)((long)frame->medbuf->data() + frame->medbuf->range_offset());
737 switch (p->videoColorFormat)
739 case OMX_COLOR_FormatYUV420Planar:
740 pDvdVideoPicture->iLineSize[0] = frame->width;
741 pDvdVideoPicture->iLineSize[1] = frame->width / 2;
742 pDvdVideoPicture->iLineSize[2] = frame->width / 2;
743 pDvdVideoPicture->iLineSize[3] = 0;
744 pDvdVideoPicture->data[0] = data;
745 pDvdVideoPicture->data[1] = pDvdVideoPicture->data[0] + luma_pixels;
746 pDvdVideoPicture->data[2] = pDvdVideoPicture->data[1] + chroma_pixels;
747 pDvdVideoPicture->data[3] = 0;
749 case OMX_COLOR_FormatYUV420SemiPlanar:
750 case OMX_QCOM_COLOR_FormatYVU420SemiPlanar:
751 case OMX_TI_COLOR_FormatYUV420PackedSemiPlanar:
752 pDvdVideoPicture->iLineSize[0] = frame->width;
753 pDvdVideoPicture->iLineSize[1] = frame->width;
754 pDvdVideoPicture->iLineSize[2] = 0;
755 pDvdVideoPicture->iLineSize[3] = 0;
756 pDvdVideoPicture->data[0] = data;
757 pDvdVideoPicture->data[1] = pDvdVideoPicture->data[0] + luma_pixels;
758 pDvdVideoPicture->data[2] = pDvdVideoPicture->data[1] + chroma_pixels;
759 pDvdVideoPicture->data[3] = 0;
762 CLog::Log(LOGERROR, "%s::%s - Unsupported color format(%d)\n", CLASSNAME, __func__,p->videoColorFormat);
764 #if defined(DEBUG_VERBOSE)
765 CLog::Log(LOGDEBUG, ">>> pic pts:%f, data:%p, col:%d, w:%d, h:%d, tm:%d\n", pDvdVideoPicture->pts, data, p->videoColorFormat, frame->width, frame->height, XbmcThreads::SystemClockMillis() - time);
770 pDvdVideoPicture->iFlags |= DVP_FLAG_DROPPED;
772 p->prev_frame = p->cur_frame;
774 p->out_condition.notify();
775 p->out_mutex.unlock();
780 void CStageFrightVideo::Dispose()
782 #if defined(DEBUG_VERBOSE)
783 CLog::Log(LOGDEBUG, "%s::Close\n", CLASSNAME);
788 if (p->decode_thread && p->decode_thread->IsRunning())
789 p->decode_thread->StopThread(false);
790 p->decode_thread = NULL;
791 p->in_condition.notify();
793 // Give decoder_thread time to process EOS, if stuck on reading
796 #if defined(DEBUG_VERBOSE)
797 CLog::Log(LOGDEBUG, "Cleaning OUT\n");
802 if (p->cur_frame->medbuf)
803 p->cur_frame->medbuf->release();
807 p->out_condition.notify();
808 p->out_mutex.unlock();
812 if (p->prev_frame->medbuf)
813 p->prev_frame->medbuf->release();
815 p->prev_frame = NULL;
818 #if defined(DEBUG_VERBOSE)
819 CLog::Log(LOGDEBUG, "Stopping omxcodec\n");
821 if (p->decoder != NULL)
828 p->client->disconnect();
833 #if defined(DEBUG_VERBOSE)
834 CLog::Log(LOGDEBUG, "Cleaning IN(%d)\n", p->in_queue.size());
836 std::list<Frame*>::iterator it;
837 while (!p->in_queue.empty())
839 it = p->in_queue.begin();
841 p->in_queue.erase(it);
843 frame->medbuf->release();
846 for (int i=0; i<INBUFCOUNT; ++i)
850 p->inbuf[i]->setObserver(NULL);
851 p->inbuf[i]->release();
857 #if defined(DEBUG_VERBOSE)
858 CLog::Log(LOGDEBUG, "Cleaning libstagefright\n", p->in_queue.size());
860 if ((p->quirks & QuirkSWRender) == 0)
861 p->ReleaseSurfaceTexture();
863 #if defined(DEBUG_VERBOSE)
864 CLog::Log(LOGDEBUG, "Final Cleaning\n", p->in_queue.size());
866 if (p->decoder_component)
867 free(&p->decoder_component);
870 void CStageFrightVideo::Reset(void)
872 #if defined(DEBUG_VERBOSE)
873 CLog::Log(LOGDEBUG, "%s::Reset\n", CLASSNAME);
877 std::list<Frame*>::iterator it;
878 while (!p->in_queue.empty())
880 it = p->in_queue.begin();
882 p->in_queue.erase(it);
884 frame->medbuf->release();
889 p->in_mutex.unlock();
892 void CStageFrightVideo::SetDropState(bool bDrop)
894 if (bDrop == p->drop_state)
897 #if defined(DEBUG_VERBOSE)
898 CLog::Log(LOGDEBUG, "%s::SetDropState (%d->%d)\n", CLASSNAME,p->drop_state,bDrop);
901 p->drop_state = bDrop;
904 void CStageFrightVideo::SetSpeed(int iSpeed)
910 void CStageFrightVideo::LockBuffer(EGLImageKHR eglimg)
912 #if defined(DEBUG_VERBOSE)
913 unsigned int time = XbmcThreads::SystemClockMillis();
915 p->free_mutex.lock();
916 stSlot* slot = p->getSlot(eglimg);
919 CLog::Log(LOGDEBUG, "STF: LockBuffer: Unknown img(%p)", eglimg);
920 p->free_mutex.unlock();
925 #if defined(DEBUG_VERBOSE)
926 CLog::Log(LOGDEBUG, "STF: LockBuffer: Locking %p: cnt:%d tm:%d\n", eglimg, slot->use_cnt, XbmcThreads::SystemClockMillis() - time);
928 p->free_mutex.unlock();
931 void CStageFrightVideo::ReleaseBuffer(EGLImageKHR eglimg)
933 #if defined(DEBUG_VERBOSE)
934 unsigned int time = XbmcThreads::SystemClockMillis();
936 p->free_mutex.lock();
937 stSlot* slot = p->getSlot(eglimg);
940 CLog::Log(LOGDEBUG, "STF: ReleaseBuffer: Unknown img(%p)", eglimg);
941 p->free_mutex.unlock();
944 if (slot->use_cnt == 0)
946 CLog::Log(LOGDEBUG, "STF: ReleaseBuffer: already unlocked img(%p)", eglimg);
947 p->free_mutex.unlock();
952 #if defined(DEBUG_VERBOSE)
953 CLog::Log(LOGDEBUG, "STF: ReleaseBuffer: Unlocking %p: cnt:%d tm:%d\n", eglimg, slot->use_cnt, XbmcThreads::SystemClockMillis() - time);
955 p->free_mutex.unlock();