Merge pull request #5101 from FernetMenta/ffmpeg-threads
[vuplus_xbmc] / xbmc / cores / dvdplayer / DVDCodecs / Video / DVDVideoCodecStageFright.cpp
1 /*
2  *      Copyright (C) 2013 Team XBMC
3  *      http://xbmc.org
4  *
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)
8  *  any later version.
9  *
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.
14  *
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/>.
18  *
19  */
20
21 //#define DEBUG_VERBOSE 1
22
23 #if (defined HAVE_CONFIG_H) && (!defined TARGET_WINDOWS)
24 #include "config.h"
25 #elif defined(TARGET_WINDOWS)
26 #include "system.h"
27 #endif
28
29 #if defined(HAS_LIBSTAGEFRIGHT)
30 #include "DVDClock.h"
31 #include "settings/Settings.h"
32 #include "DVDStreamInfo.h"
33 #include "DVDVideoCodecStageFright.h"
34 #include "utils/log.h"
35 #include "Application.h"
36 #include "ApplicationMessenger.h"
37 #include "windowing/WindowingFactory.h"
38 #include "settings/AdvancedSettings.h"
39
40 #include "DllLibStageFrightCodec.h"
41
42 #define CLASSNAME "CDVDVideoCodecStageFright"
43 ////////////////////////////////////////////////////////////////////////////////////////////
44 ////////////////////////////////////////////////////////////////////////////////////////////
45
46 DllLibStageFrightCodec*     CDVDVideoCodecStageFright::m_stf_dll = NULL;
47
48 CDVDVideoCodecStageFright::CDVDVideoCodecStageFright()
49   : CDVDVideoCodec()
50   , m_convert_bitstream(false),  m_converter(NULL)
51   , m_stf_handle(NULL)
52 {
53   m_pFormatName = "stf-xxxx";
54
55   if (!m_stf_dll)
56     m_stf_dll = new DllLibStageFrightCodec;
57 }
58
59 CDVDVideoCodecStageFright::~CDVDVideoCodecStageFright()
60 {
61   Dispose();
62 }
63
64 bool CDVDVideoCodecStageFright::Open(CDVDStreamInfo &hints, CDVDCodecOptions &options)
65 {
66   // we always qualify even if DVDFactoryCodec does this too.
67   if (CSettings::Get().GetBool("videoplayer.usestagefright") && !hints.software)
68   {
69     m_convert_bitstream = false;
70     CLog::Log(LOGDEBUG,
71           "%s::%s - trying to open, codec(%d), profile(%d), level(%d)",
72           CLASSNAME, __func__, hints.codec, hints.profile, hints.level);
73
74     switch (hints.codec)
75     {
76       case CODEC_ID_H264:
77         m_pFormatName = "stf-h264";
78         if (hints.extrasize < 7 || hints.extradata == NULL)
79         {
80           CLog::Log(LOGNOTICE,
81               "%s::%s - avcC data too small or missing", CLASSNAME, __func__);
82           return false;
83         }
84         m_converter     = new CBitstreamConverter();
85         m_convert_bitstream = m_converter->Open(hints.codec, (uint8_t *)hints.extradata, hints.extrasize, true);
86
87         break;
88       case CODEC_ID_MPEG2VIDEO:
89         m_pFormatName = "stf-mpeg2";
90         break;
91       case CODEC_ID_MPEG4:
92         m_pFormatName = "stf-mpeg4";
93         break;
94       case CODEC_ID_VP3:
95       case CODEC_ID_VP6:
96       case CODEC_ID_VP6F:
97       case CODEC_ID_VP8:
98         m_pFormatName = "stf-vpx";
99         break;
100       case CODEC_ID_WMV3:
101       case CODEC_ID_VC1:
102         m_pFormatName = "stf-wmv";
103         break;
104       default:
105         return false;
106         break;
107     }
108
109     if (!(m_stf_dll && m_stf_dll->Load()))
110       return false;
111     m_stf_dll->EnableDelayedUnload(false);
112
113     m_stf_handle = m_stf_dll->create_stf(&g_application, &CApplicationMessenger::Get(), &g_Windowing, &g_advancedSettings);
114
115     if (!m_stf_dll->stf_Open(m_stf_handle, hints))
116     {
117       CLog::Log(LOGERROR,
118           "%s::%s - failed to open, codec(%d), profile(%d), level(%d)",
119           CLASSNAME, __func__, hints.codec, hints.profile, hints.level);
120       Dispose();
121       return false;
122     }
123
124     return true;
125   }
126
127   return false;
128 }
129
130 void CDVDVideoCodecStageFright::Dispose()
131 {
132   if (m_converter)
133   {
134     m_converter->Close();
135     delete m_converter;
136     m_converter = NULL;
137   }
138   if (m_stf_handle)
139   {
140     m_stf_dll->stf_Dispose(m_stf_handle);
141     m_stf_dll->destroy_stf(m_stf_handle);
142     m_stf_handle = NULL;
143   }
144 }
145
146 void CDVDVideoCodecStageFright::SetDropState(bool bDrop)
147 {
148   m_stf_dll->stf_SetDropState(m_stf_handle, bDrop);
149 }
150
151 int CDVDVideoCodecStageFright::Decode(uint8_t *pData, int iSize, double dts, double pts)
152 {
153 #if defined(DEBUG_VERBOSE)
154   unsigned int time = XbmcThreads::SystemClockMillis();
155 #endif
156   int rtn;
157   int demuxer_bytes = iSize;
158   uint8_t *demuxer_content = pData;
159
160   if (m_convert_bitstream && demuxer_content)
161   {
162     // convert demuxer packet from bitstream to bytestream (AnnexB)
163     if (m_converter->Convert(demuxer_content, demuxer_bytes))
164     {
165       demuxer_content = m_converter->GetConvertBuffer();
166       demuxer_bytes = m_converter->GetConvertSize();
167     }
168     else
169       CLog::Log(LOGERROR,"%s::%s - bitstream_convert error", CLASSNAME, __func__);
170   }
171 #if defined(DEBUG_VERBOSE)
172   CLog::Log(LOGDEBUG, ">>> decode conversion - tm:%d\n", XbmcThreads::SystemClockMillis() - time);
173 #endif
174
175   rtn = m_stf_dll->stf_Decode(m_stf_handle, demuxer_content, demuxer_bytes, dts, pts);
176
177   return rtn;
178 }
179
180 void CDVDVideoCodecStageFright::Reset(void)
181 {
182   m_stf_dll->stf_Reset(m_stf_handle);
183 }
184
185 bool CDVDVideoCodecStageFright::GetPicture(DVDVideoPicture* pDvdVideoPicture)
186 {
187   pDvdVideoPicture->stf = this;
188   return m_stf_dll->stf_GetPicture(m_stf_handle, pDvdVideoPicture);
189 }
190
191 bool CDVDVideoCodecStageFright::ClearPicture(DVDVideoPicture* pDvdVideoPicture)
192 {
193   return m_stf_dll->stf_ClearPicture(m_stf_handle, pDvdVideoPicture);
194 }
195
196 void CDVDVideoCodecStageFright::SetSpeed(int iSpeed)
197 {
198   m_stf_dll->stf_SetSpeed(m_stf_handle, iSpeed);
199 }
200
201 int CDVDVideoCodecStageFright::GetDataSize(void)
202 {
203   return 0;
204 }
205
206 double CDVDVideoCodecStageFright::GetTimeSize(void)
207 {
208   return 0;
209 }
210
211 void CDVDVideoCodecStageFright::LockBuffer(EGLImageKHR eglimg)
212 {
213   m_stf_dll->stf_LockBuffer(m_stf_handle, eglimg);
214 }
215
216 void CDVDVideoCodecStageFright::ReleaseBuffer(EGLImageKHR eglimg)
217 {
218   m_stf_dll->stf_ReleaseBuffer(m_stf_handle, eglimg);
219 }
220
221 #endif