1 /*
2 *      Copyright (C) 2017 peak3d
3 *      http://www.peak3d.de
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 *  <http://www.gnu.org/licenses/>.
16 *
17 */
18 
19 #pragma once
20 
21 #include <stdint.h>
22 #include "Ap4Types.h"
23 #include "Ap4DataBuffer.h"
24 #include <kodi/addon-instance/Inputstream.h>
25 
26 class AP4_ByteStream;
27 
28 class ATTRIBUTE_HIDDEN ID3TAG
29 {
30 public:
31   enum PARSECODE
32   {
33     PARSE_SUCCESS,
34     PARSE_FAIL,
35     PARSE_NO_ID3
36   };
37 
38   PARSECODE parse(AP4_ByteStream *stream);
getPts(uint64_t & pts)39   bool getPts(uint64_t &pts) { if (m_timestamp) { pts = m_timestamp; m_timestamp = 0; return true; } return false; }
40 
41 private:
42   static uint64_t getSize(const uint8_t *data, unsigned int size, unsigned int shift);
43 
44   static const unsigned int HEADER_SIZE = 10;
45 
46   uint8_t m_majorVer;
47   uint8_t m_flags;
48   uint64_t m_timestamp;
49 };
50 
51 
52 class ATTRIBUTE_HIDDEN ADTSFrame
53 {
54 public:
55   bool parse(AP4_ByteStream *stream);
reset()56   void reset() { m_summedFrameCount = 0; m_frameCount = 0; m_dataBuffer.SetDataSize(0); }
resetFrameCount()57   void resetFrameCount() { m_summedFrameCount = 0; }
getPtsOffset()58   uint64_t getPtsOffset() const { return m_sampleRate ? (static_cast<uint64_t>(m_summedFrameCount) * 90000) / m_sampleRate : 0; }
getDuration()59   uint64_t getDuration() const { return m_sampleRate ? (static_cast<uint64_t>(m_frameCount) * 90000) / m_sampleRate : 0; }
getData()60   const AP4_Byte *getData() const { return m_dataBuffer.GetData(); }
getDataSize()61   AP4_Size getDataSize() const { return m_dataBuffer.GetDataSize(); }
62 private:
63   uint64_t getBE(const uint8_t *data, unsigned int len);
64   uint16_t m_outerHeader;
65   uint64_t m_innerHeader;
66   long m_innerHeaderSize;
67 
68   uint32_t m_totalSize = 0;
69   uint32_t m_summedFrameCount = 0;
70   uint32_t m_frameCount = 0;
71   uint32_t m_sampleRate = 0;
72   uint32_t m_channelConfig = 0;
73 
74   AP4_DataBuffer m_dataBuffer;
75 };
76 
77 class ATTRIBUTE_HIDDEN ADTSReader
78 {
79 public:
80   ADTSReader(AP4_ByteStream *stream);
81   virtual ~ADTSReader();
82 
83   void Reset();
84   bool SeekTime(uint64_t timeInTs, bool preceeding);
85 
86   bool GetInformation(kodi::addon::InputstreamInfo& info);
87   bool ReadPacket();
88 
GetPts()89   uint64_t GetPts() const { return m_pts; }
GetDuration()90   uint64_t GetDuration() const { return m_frameParser.getDuration(); }
GetPacketData()91   const AP4_Byte *GetPacketData() const { return m_frameParser.getData(); };
GetPacketSize()92   const AP4_Size GetPacketSize() const { return m_frameParser.getDataSize(); };
93 
94 private:
95   static const uint64_t ADTS_PTS_UNSET = 0x1ffffffffULL;
96   AP4_ByteStream *m_stream;
97   ID3TAG m_id3TagParser;
98   ADTSFrame m_frameParser;
99   uint64_t m_basePts, m_pts;
100 };
101