Merge pull request #3252 from bavison/music_search_bug
[vuplus_xbmc] / xbmc / cores / paplayer / FLACcodec.cpp
1 /*
2  *      Copyright (C) 2005-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 #include "FLACcodec.h"
22 #include "utils/log.h"
23 #include "cores/AudioEngine/Utils/AEUtil.h"
24 #include "music/tags/TagLoaderTagLib.h"
25
26 FLACCodec::FLACCodec()
27 {
28   m_SampleRate = 0;
29   m_Channels = 0;
30   m_BitsPerSample = 0;
31   m_DataFormat = AE_FMT_INVALID;
32   m_TotalTime=0;
33   m_Bitrate = 0;
34   m_CodecName = "flac";
35
36   m_pFlacDecoder=NULL;
37
38   m_pBuffer=NULL;
39   m_BufferSize=0;
40   m_MaxFrameSize=0;
41
42 }
43
44 FLACCodec::~FLACCodec()
45 {
46   DeInit();
47 }
48
49 bool FLACCodec::Init(const CStdString &strFile, unsigned int filecache)
50 {
51   if (!m_dll.Load())
52     return false;
53
54   if (!m_file.Open(strFile, READ_CACHED))
55     return false;
56
57   //  Extract ReplayGain info
58   CTagLoaderTagLib tagLoaderTagLib;
59   tagLoaderTagLib.Load(strFile, m_tag, "flac");
60
61   m_pFlacDecoder=m_dll.FLAC__stream_decoder_new();
62
63   if (!m_pFlacDecoder)
64   {
65     CLog::Log(LOGERROR, "FLACCodec: Error creating decoder");
66     return false;
67   }
68
69   if (m_dll.FLAC__stream_decoder_init_stream(m_pFlacDecoder, DecoderReadCallback,
70                                                              DecoderSeekCallback,
71                                                              DecoderTellCallback,
72                                                              DecoderLengthCallback,
73                                                              DecoderEofCallback,
74                                                              DecoderWriteCallback,
75                                                              DecoderMetadataCallback,
76                                                              DecoderErrorCallback,
77                                                              this) != FLAC__STREAM_DECODER_INIT_STATUS_OK)
78   {
79     CLog::Log(LOGERROR, "FLACCodec: Error initializing decoder");
80     FreeDecoder();
81     return false;
82   }
83
84   //  Process metadata like number of channels...
85   if (!m_dll.FLAC__stream_decoder_process_until_end_of_metadata(m_pFlacDecoder))
86   {
87     CLog::Log(LOGERROR, "FLACCodec: Error while processing metadata");
88     FreeDecoder();
89     return false;
90   }
91
92   //  These are filled by the metadata callback
93   if (m_SampleRate==0 || m_Channels==0 || m_BitsPerSample==0 || m_TotalTime==0 || m_MaxFrameSize==0 || m_DataFormat == AE_FMT_INVALID)
94   {
95     CLog::Log(LOGERROR, "FLACCodec: Can't get stream info, SampleRate=%i, Channels=%i, BitsPerSample=%i, TotalTime=%"PRIu64", MaxFrameSize=%i", m_SampleRate, m_Channels, m_BitsPerSample, m_TotalTime, m_MaxFrameSize);
96     FreeDecoder();
97     return false;
98   }
99
100   m_Bitrate = (int)(((float)m_file.GetLength() * 8) / ((float)m_TotalTime / 1000));
101
102   if (m_pBuffer)
103   {
104     delete[] m_pBuffer;
105     m_pBuffer=NULL;
106   }
107   //  allocate the buffer to hold the audio data,
108   //  it is 5 times bigger then a single decoded frame
109   m_pBuffer=new BYTE[m_MaxFrameSize*5];
110
111   return true;
112 }
113
114 void FLACCodec::DeInit()
115 {
116   FreeDecoder();
117   m_file.Close();
118
119   if (m_pBuffer)
120   {
121     delete[] m_pBuffer;
122     m_pBuffer=NULL;
123   }
124 }
125
126 int64_t FLACCodec::Seek(int64_t iSeekTime)
127 {
128   //  Seek to the nearest sample
129   // set the buffer size to 0 first, as this invokes a WriteCallback which
130   // may be called when the buffer is almost full (resulting in a buffer
131   // overrun unless we reset m_BufferSize first).
132   m_BufferSize=0;
133   if(!m_dll.FLAC__stream_decoder_seek_absolute(m_pFlacDecoder, (int64_t)(iSeekTime*m_SampleRate)/1000))
134     CLog::Log(LOGERROR, "FLACCodec::Seek - failed to seek");
135
136   if(m_dll.FLAC__stream_decoder_get_state(m_pFlacDecoder)==FLAC__STREAM_DECODER_SEEK_ERROR)
137   {
138     CLog::Log(LOGINFO, "FLACCodec::Seek - must reset decoder after seek");
139     if(!m_dll.FLAC__stream_decoder_flush(m_pFlacDecoder))
140       CLog::Log(LOGERROR, "FLACCodec::Seek - flush failed");
141   }
142
143   return iSeekTime;
144 }
145
146 int FLACCodec::ReadPCM(BYTE *pBuffer, int size, int *actualsize)
147 {
148   *actualsize=0;
149
150   bool eof=false;
151   if (m_dll.FLAC__stream_decoder_get_state(m_pFlacDecoder)==FLAC__STREAM_DECODER_END_OF_STREAM)
152     eof=true;
153
154   if (!eof)
155   {
156     //  fill our buffer 4 decoded frame (the buffer could hold 5)
157     while(m_BufferSize < m_MaxFrameSize*4 &&
158           m_dll.FLAC__stream_decoder_get_state(m_pFlacDecoder)!=FLAC__STREAM_DECODER_END_OF_STREAM)
159     {
160       if (!m_dll.FLAC__stream_decoder_process_single(m_pFlacDecoder))
161       {
162         CLog::Log(LOGERROR, "FLACCodec: Error decoding single block");
163         return READ_ERROR;
164       }
165     }
166   }
167
168   if (size<m_BufferSize)
169   { //  do we need less audio data then in our buffer
170     memcpy(pBuffer, m_pBuffer, size);
171     memmove(m_pBuffer, m_pBuffer+size, m_BufferSize-size);
172     m_BufferSize-=size;
173     *actualsize=size;
174   }
175   else
176   {
177     memcpy(pBuffer, m_pBuffer, m_BufferSize);
178     *actualsize=m_BufferSize;
179     m_BufferSize=0;
180   }
181
182   if (eof && m_BufferSize==0)
183     return READ_EOF;
184
185   return READ_SUCCESS;
186 }
187
188 bool FLACCodec::CanInit()
189 {
190   return m_dll.CanLoad();
191 }
192
193 void FLACCodec::FreeDecoder()
194 {
195   if (m_pFlacDecoder)
196   {
197     m_dll.FLAC__stream_decoder_finish(m_pFlacDecoder);
198     m_dll.FLAC__stream_decoder_delete(m_pFlacDecoder);
199     m_pFlacDecoder=NULL;
200   }
201 }
202
203 FLAC__StreamDecoderReadStatus FLACCodec::DecoderReadCallback(const FLAC__StreamDecoder *decoder, FLAC__byte buffer[], size_t *bytes, void *client_data)
204 {
205   FLACCodec* pThis=(FLACCodec*)client_data;
206   if (!pThis)
207     return FLAC__STREAM_DECODER_READ_STATUS_ABORT;
208
209   *bytes=pThis->m_file.Read(buffer, *bytes);
210
211   return FLAC__STREAM_DECODER_READ_STATUS_CONTINUE;
212 }
213
214 FLAC__StreamDecoderSeekStatus FLACCodec::DecoderSeekCallback(const FLAC__StreamDecoder *decoder, FLAC__uint64 absolute_byte_offset, void *client_data)
215 {
216   FLACCodec* pThis=(FLACCodec*)client_data;
217   if (!pThis)
218     return FLAC__STREAM_DECODER_SEEK_STATUS_ERROR;
219
220   if (pThis->m_file.Seek(absolute_byte_offset, SEEK_SET)<0)
221     return FLAC__STREAM_DECODER_SEEK_STATUS_ERROR;
222
223
224   return FLAC__STREAM_DECODER_SEEK_STATUS_OK;
225 }
226
227 FLAC__StreamDecoderTellStatus FLACCodec::DecoderTellCallback(const FLAC__StreamDecoder *decoder, FLAC__uint64 *absolute_byte_offset, void *client_data)
228 {
229   FLACCodec* pThis=(FLACCodec*)client_data;
230   if (!pThis)
231     return FLAC__STREAM_DECODER_TELL_STATUS_ERROR;
232
233   *absolute_byte_offset=pThis->m_file.GetPosition();
234
235   return FLAC__STREAM_DECODER_TELL_STATUS_OK;
236 }
237
238 FLAC__StreamDecoderLengthStatus FLACCodec::DecoderLengthCallback(const FLAC__StreamDecoder *decoder, FLAC__uint64 *stream_length, void *client_data)
239 {
240   FLACCodec* pThis=(FLACCodec*)client_data;
241   if (!pThis)
242     return FLAC__STREAM_DECODER_LENGTH_STATUS_ERROR;
243
244   *stream_length=pThis->m_file.GetLength();
245
246   return FLAC__STREAM_DECODER_LENGTH_STATUS_OK;
247 }
248
249 FLAC__bool FLACCodec::DecoderEofCallback(const FLAC__StreamDecoder *decoder, void *client_data)
250 {
251   FLACCodec* pThis=(FLACCodec*)client_data;
252   if (!pThis)
253     return true;
254
255   return (pThis->m_file.GetLength()==pThis->m_file.GetPosition());
256 }
257
258 FLAC__StreamDecoderWriteStatus FLACCodec::DecoderWriteCallback(const FLAC__StreamDecoder *decoder, const FLAC__Frame *frame, const FLAC__int32 * const buffer[], void *client_data)
259 {
260   FLACCodec* pThis=(FLACCodec*)client_data;
261   if (!pThis)
262     return FLAC__STREAM_DECODER_WRITE_STATUS_ABORT;
263
264   const int bytes_per_sample = frame->header.bits_per_sample/8;
265   BYTE* outptr = pThis->m_pBuffer+pThis->m_BufferSize;
266   FLAC__int16* outptr16 = (FLAC__int16 *) outptr;
267   FLAC__int32* outptr32 = (FLAC__int32 *) outptr;
268
269   unsigned int current_sample = 0;
270   for(current_sample = 0; current_sample < frame->header.blocksize; current_sample++)
271   {
272     for(unsigned int channel = 0; channel < frame->header.channels; channel++)
273     {
274       switch(bytes_per_sample)
275       {
276         case 2:
277           outptr16[current_sample*frame->header.channels + channel] = (FLAC__int16) buffer[channel][current_sample];
278           break;
279         case 3:
280           outptr[2] = (buffer[channel][current_sample] >> 16) & 0xff;
281           outptr[1] = (buffer[channel][current_sample] >> 8 ) & 0xff;
282           outptr[0] = (buffer[channel][current_sample] >> 0 ) & 0xff;
283           outptr += bytes_per_sample;
284           break;
285         default:
286           outptr32[current_sample*frame->header.channels + channel] = buffer[channel][current_sample];
287           break;
288       }
289     }
290   }
291
292   if (bytes_per_sample == 1)
293   {
294     for(unsigned int i=0;i<current_sample;i++)
295     {
296       BYTE* outptr=pThis->m_pBuffer+pThis->m_BufferSize;
297       outptr[i]^=0x80;
298     }
299   }
300
301   pThis->m_BufferSize += current_sample*bytes_per_sample*frame->header.channels;
302
303   return FLAC__STREAM_DECODER_WRITE_STATUS_CONTINUE;
304 }
305
306 void FLACCodec::DecoderMetadataCallback(const FLAC__StreamDecoder *decoder, const FLAC__StreamMetadata *metadata, void *client_data)
307 {
308   FLACCodec* pThis=(FLACCodec*)client_data;
309   if (!pThis)
310     return;
311
312   if (metadata->type==FLAC__METADATA_TYPE_STREAMINFO)
313   {
314     static enum AEChannel map[8][9] = {
315       {AE_CH_FC, AE_CH_NULL},
316       {AE_CH_FL, AE_CH_FR, AE_CH_NULL},
317       {AE_CH_FL, AE_CH_FR, AE_CH_FC, AE_CH_NULL},
318       {AE_CH_FL, AE_CH_FR, AE_CH_BL, AE_CH_BR, AE_CH_NULL},
319       {AE_CH_FL, AE_CH_FR, AE_CH_FC, AE_CH_BL, AE_CH_BR, AE_CH_NULL},
320       {AE_CH_FL, AE_CH_FR, AE_CH_FC, AE_CH_LFE, AE_CH_BL, AE_CH_BR, AE_CH_NULL}, // 6 channels
321       {AE_CH_FL, AE_CH_FR, AE_CH_FC, AE_CH_LFE, AE_CH_BC, AE_CH_BL, AE_CH_BR, AE_CH_NULL}, // 7 channels
322       {AE_CH_FL, AE_CH_FR, AE_CH_FC, AE_CH_LFE, AE_CH_BL, AE_CH_BR, AE_CH_SL, AE_CH_SR, AE_CH_NULL} // 8 channels
323     };
324
325     /* channel counts greater then 6 are undefined */
326     if (metadata->data.stream_info.channels > 8)
327       pThis->m_ChannelInfo = CAEUtil::GuessChLayout(metadata->data.stream_info.channels);
328     else
329       pThis->m_ChannelInfo = CAEChannelInfo(map[metadata->data.stream_info.channels - 1]);
330
331     pThis->m_SampleRate    = metadata->data.stream_info.sample_rate;
332     pThis->m_Channels      = metadata->data.stream_info.channels;
333     pThis->m_BitsPerSample = metadata->data.stream_info.bits_per_sample;
334     switch(pThis->m_BitsPerSample)
335     {
336       case  8: pThis->m_DataFormat = AE_FMT_U8;     break;
337       case 16: pThis->m_DataFormat = AE_FMT_S16NE;  break;
338       case 24: pThis->m_DataFormat = AE_FMT_S24NE3; break;
339       case 32: pThis->m_DataFormat = AE_FMT_FLOAT;  break;
340     }
341     pThis->m_TotalTime     = (int64_t)metadata->data.stream_info.total_samples * 1000 / metadata->data.stream_info.sample_rate;
342     pThis->m_MaxFrameSize  = metadata->data.stream_info.max_blocksize*(pThis->m_BitsPerSample/8)*pThis->m_Channels;
343   }
344 }
345
346 void FLACCodec::DecoderErrorCallback(const FLAC__StreamDecoder *decoder, FLAC__StreamDecoderErrorStatus status, void *client_data)
347 {
348   CLog::Log(LOGERROR, "FLACCodec: Read error %i", status);
349 }