1 /*
2  *  Copyright (C) 2005-2018 Team Kodi
3  *  This file is part of Kodi - https://kodi.tv
4  *
5  *  SPDX-License-Identifier: GPL-2.0-or-later
6  *  See LICENSES/README.md for more information.
7  */
8 
9 #pragma once
10 
11 #include "ICodec.h"
12 #include "cores/AudioEngine/Utils/AEChannelInfo.h"
13 #include "threads/CriticalSection.h"
14 #include "utils/RingBuffer.h"
15 
16 class CFileItem;
17 
18 #define PACKET_SIZE 3840    // audio packet size - we keep 1 in reserve for gapless playback
19                             // using a multiple of 1, 2, 3, 4, 5, 6 to guarantee track alignment
20                             // note that 7 or higher channels won't work too well.
21 
22 #define INPUT_SIZE PACKET_SIZE * 3      // input data size we read from the codecs at a time
23                                         // * 3 to allow 24 bit audio
24 
25 #define OUTPUT_SAMPLES PACKET_SIZE      // max number of output samples
26 #define INPUT_SAMPLES  PACKET_SIZE      // number of input samples (distributed over channels)
27 
28 #define STATUS_NO_FILE  0
29 #define STATUS_QUEUING  1
30 #define STATUS_QUEUED   2
31 #define STATUS_PLAYING  3
32 #define STATUS_ENDING   4
33 #define STATUS_ENDED    5
34 
35 // return codes from decoders
36 #define RET_ERROR -1
37 #define RET_SUCCESS 0
38 #define RET_SLEEP 1
39 
40 class CAudioDecoder
41 {
42 public:
43   CAudioDecoder();
44   ~CAudioDecoder();
45 
46   bool Create(const CFileItem &file, int64_t seekOffset);
47   void Destroy();
48 
49   int ReadSamples(int numsamples);
50 
CanSeek()51   bool CanSeek() { if (m_codec) return m_codec->CanSeek(); else return false; };
52   int64_t Seek(int64_t time);
53   int64_t TotalTime();
54   void SetTotalTime(int64_t time);
Start()55   void Start() { m_canPlay = true;}; // cause a pre-buffered stream to start.
GetStatus()56   int GetStatus() { return m_status; };
SetStatus(int status)57   void SetStatus(int status) { m_status = status; }
58 
59   AEAudioFormat GetFormat();
GetChannels()60   unsigned int GetChannels() { return GetFormat().m_channelLayout.Count(); }
61   // Data management
62   unsigned int GetDataSize(bool checkPktSize);
63   void *GetData(unsigned int samples);
64   uint8_t* GetRawData(int &size);
GetCodec()65   ICodec *GetCodec() const { return m_codec; }
66   float GetReplayGain(float &peakVal);
67 
68 private:
69   // pcm buffer
70   CRingBuffer m_pcmBuffer;
71 
72   // output buffer (for transferring data from the Pcm Buffer to the rest of the audio chain)
73   float m_outputBuffer[OUTPUT_SAMPLES];
74 
75   // input buffer (for transferring data from the Codecs to our Pcm Ringbuffer
76   uint8_t m_pcmInputBuffer[INPUT_SIZE];
77   float m_inputBuffer[INPUT_SAMPLES];
78 
79   uint8_t *m_rawBuffer;
80   int m_rawBufferSize;
81 
82   // status
83   bool m_eof;
84   int m_status;
85   bool m_canPlay;
86 
87   // the codec we're using
88   ICodec* m_codec;
89 
90   CCriticalSection m_critSection;
91 };
92