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