2 Copyright 2005-2006 Mark Calderbank
4 This file is part of VOMP.
6 VOMP is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
11 VOMP is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with VOMP; if not, write to the Free Software
18 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
32 void Stream::shutdown()
34 if (initted) free(outbuf);
38 int Stream::init(DrainTarget* tdt, int bufsize)
40 outbuf = (UCHAR*)malloc(bufsize);
41 if (!outbuf) return 0;
55 if (draintarget) draintarget->ResetTimeOffsets();
58 int Stream::put(const UCHAR* inbuf, int len, UCHAR type,unsigned int index)
61 if (!draintarget) return 0;
62 MediaPacket newPacket;
63 newPacket.length = len;
64 newPacket.pos_buffer = 0;
65 newPacket.type = type;
68 newPacket.synched=false;
69 newPacket.index=index;
70 newPacket.disconti=false;
71 newPacket.presentation_time=0;
73 if (type!=MPTYPE_MPEG_AUDIO_LAYER3) {//no PES
76 if ((inbuf[7] & 0x80) && len>14 ) {
77 newPacket.synched=true;
78 newPacket.pts=((ULLONG)(inbuf[9] & 0x0E) << 29 ) |
79 ( (ULLONG)(inbuf[10]) << 22 ) |
80 ( (ULLONG)(inbuf[11] & 0xFE) << 14 ) |
81 ( (ULLONG)(inbuf[12]) << 7 ) |
82 ( (ULLONG)(inbuf[13] & 0xFE) >> 1 );
83 if ((inbuf[7] & 0x40) && len>19) {
84 newPacket.dts=((ULLONG)(inbuf[14] & 0x0E) << 29 ) |
85 ( (ULLONG)(inbuf[15]) << 22 ) |
86 ( (ULLONG)(inbuf[16] & 0xFE) << 14 ) |
87 ( (ULLONG)(inbuf[17]) << 7 ) |
88 ( (ULLONG)(inbuf[18] & 0xFE) >> 1 );
91 //ok we have the pts now convert it to a continously time code in 100ns units
92 if (hasdts && draintarget->dtsTimefix()) newPacket.presentation_time=(ULLONG)(newPacket.dts*10000LL/90LL);
93 else newPacket.presentation_time=(ULLONG)(newPacket.pts*10000LL/90LL);
95 //newPacket.presentation_time-=draintarget->SetStartOffset((ULLONG)(newPacket.pts*10000LL/90LL),&newPacket.disconti);
96 newPacket.presentation_time-=draintarget->SetStartOffset((ULLONG)(newPacket.pts*10000LL/90LL),&newPacket.disconti);
102 if (mediapackets.empty())
104 back = 0; front = bufferSize;
108 front = mediapackets.front().pos_buffer;
109 back = mediapackets.back().pos_buffer + mediapackets.back().length;
110 if (back == bufferSize) back = 0;
116 // The free space (if any) is in one continuous chunk.
117 if (len <= front - back) ret = len; // Is there enough of it?
119 else if (len <= bufferSize - back)
121 // There is enough space at the end of the buffer
124 else if (len <= front)
126 // There is enough space at the start of the buffer
131 if (ret) // Nonzero if we managed to find room for the packet
133 memcpy(outbuf + back, inbuf, len);
134 newPacket.pos_buffer = back;
136 mediapackets.push_back(newPacket);
139 // Log::getInstance()->log("Stream", Log::DEBUG, "We are full %d!",bufferSize);
145 bool Stream::drain(bool * dataavail)
148 if (dataavail) *dataavail = false;
149 if (draintarget->DrainTargetBufferFull()) return false; //We are full, no need to do something else
151 UINT listlength = mediapackets.size();
154 draintarget->PrepareMediaSample(mediapackets, cur_packet_pos);
156 if (dataavail && draintarget->DrainTargetReady()) *dataavail = true;
157 UINT consumed = draintarget->DeliverMediaSample(outbuf, &cur_packet_pos);
159 if (consumed != 0) ret = true;
160 if (consumed > listlength) consumed = listlength;
163 mediapackets.pop_front();