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