2 Copyright 2005-2006 Mark Calderbank
3 Copyright 2020 Chris Tallon
5 This file is part of VOMP.
7 VOMP is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
12 VOMP is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with VOMP. If not, see <https://www.gnu.org/licenses/>.
32 void Stream::shutdown()
34 if (initted) free(outbuf);
39 int Stream::init(DrainTarget* tdt, int bufsize)
41 outbuf = static_cast<UCHAR*>(malloc(bufsize));
43 if (!outbuf) return 0;
58 if (draintarget) draintarget->ResetTimeOffsets();
61 int Stream::put(const UCHAR* inbuf, int len, UCHAR type, unsigned int index)
65 if (!draintarget) return 0;
67 MediaPacket newPacket;
68 newPacket.length = len;
69 newPacket.pos_buffer = 0;
70 newPacket.type = type;
73 newPacket.synched = false;
74 newPacket.index = index;
75 newPacket.disconti = false;
76 newPacket.presentation_time = 0;
78 if (type != MPTYPE_MPEG_AUDIO_LAYER3) //no PES
83 if ((inbuf[7] & 0x80) && len > 14 )
85 newPacket.synched = true;
86 newPacket.pts = ( static_cast<ULLONG>(inbuf[9] & 0x0E) << 29 ) |
87 ( static_cast<ULLONG>(inbuf[10]) << 22 ) |
88 ( static_cast<ULLONG>(inbuf[11] & 0xFE) << 14 ) |
89 ( static_cast<ULLONG>(inbuf[12]) << 7 ) |
90 ( static_cast<ULLONG>(inbuf[13] & 0xFE) >> 1 );
92 if ((inbuf[7] & 0x40) && len > 19)
94 newPacket.dts = ( static_cast<ULLONG>(inbuf[14] & 0x0E) << 29 ) |
95 ( static_cast<ULLONG>(inbuf[15]) << 22 ) |
96 ( static_cast<ULLONG>(inbuf[16] & 0xFE) << 14 ) |
97 ( static_cast<ULLONG>(inbuf[17]) << 7 ) |
98 ( static_cast<ULLONG>(inbuf[18] & 0xFE) >> 1 );
102 //ok we have the pts now convert it to a continously time code in 100ns units
103 if (hasdts && draintarget->dtsTimefix()) newPacket.presentation_time = static_cast<ULLONG>(newPacket.dts * 10000LL / 90LL);
104 else newPacket.presentation_time = static_cast<ULLONG>(newPacket.pts * 10000LL / 90LL);
106 //newPacket.presentation_time-=draintarget->SetStartOffset(static_cast<ULLONG>(newPacket.pts*10000LL/90LL),&newPacket.disconti);
107 newPacket.presentation_time -= draintarget->SetStartOffset(static_cast<ULLONG>(newPacket.pts * 10000LL / 90LL), &newPacket.disconti);
114 if (mediapackets.empty())
116 back = 0; front = bufferSize;
120 front = mediapackets.front().pos_buffer;
121 back = mediapackets.back().pos_buffer + mediapackets.back().length;
123 if (back == bufferSize) back = 0;
130 // The free space (if any) is in one continuous chunk.
131 if (len <= front - back) ret = len; // Is there enough of it?
133 else if (len <= bufferSize - back)
135 // There is enough space at the end of the buffer
138 else if (len <= front)
140 // There is enough space at the start of the buffer
145 if (ret) // Nonzero if we managed to find room for the packet
147 memcpy(outbuf + back, inbuf, len);
148 newPacket.pos_buffer = back;
150 mediapackets.push_back(newPacket);
155 // Log::getInstance()->log("Stream", Log::DEBUG, "We are full %d!",bufferSize);
161 bool Stream::drain(bool* dataavail)
165 if (dataavail) *dataavail = false;
167 if (draintarget->DrainTargetBufferFull()) return false; //We are full, no need to do something else
170 UINT listlength = mediapackets.size();
174 draintarget->PrepareMediaSample(mediapackets, cur_packet_pos);
177 if (dataavail && draintarget->DrainTargetReady()) *dataavail = true;
179 UINT consumed = draintarget->DeliverMediaSample(outbuf, &cur_packet_pos);
182 if (consumed != 0) ret = true;
184 if (consumed > listlength) consumed = listlength;
188 mediapackets.pop_front();