1 /* dvbcut 2 Copyright (c) 2005 Sven Over <svenover@svenover.de> 3 4 This program is free software; you can redistribute it and/or modify 5 it under the terms of the GNU General Public License as published by 6 the Free Software Foundation; either version 2 of the License, or 7 (at your option) any later version. 8 9 This program is distributed in the hope that it will be useful, 10 but WITHOUT ANY WARRANTY; without even the implied warranty of 11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 GNU General Public License for more details. 13 14 You should have received a copy of the GNU General Public License 15 along with this program; if not, write to the Free Software 16 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 17 */ 18 19 /* $Id$ */ 20 21 #ifndef _DVBCUT_STREAMDATA_H 22 #define _DVBCUT_STREAMDATA_H 23 24 #include <string> 25 #include <list> 26 extern "C" { 27 #include <libavformat/avformat.h> 28 } 29 30 #include "port.h" 31 #include "tsfile.h" 32 #include "psfile.h" 33 #include "buffer.h" 34 #include "types.h" 35 #include "pts.h" 36 37 /* obsolete, do not use --mr 38 #define STREAM_ITEM_FLAG_DATA_ALIGNMENT_INDICATOR (1<<0) 39 */ 40 #define STREAM_ITEM_FLAG_HAS_PTS (1<<1) 41 #define STREAM_ITEM_FLAG_FRAME (1<<2) 42 43 /** 44 @author Sven Over 45 */ 46 class streamdata 47 { 48 public: 49 struct item 50 { 51 filepos_t fileposition; 52 53 uint32_t bufferposition; 54 uint32_t flags; 55 pts_t pts; 56 itemitem57 item(filepos_t fp, uint32_t fl, pts_t p, uint32_t bp) : fileposition(fp), bufferposition(bp), flags(fl), pts(p) 58 { 59 if (!(flags&STREAM_ITEM_FLAG_HAS_PTS)) 60 pts=(pts_t)AV_NOPTS_VALUE; 61 } ~itemitem62 ~item() 63 {} 64 setptsitem65 void setpts(pts_t p) 66 { 67 if (p!=(pts_t)AV_NOPTS_VALUE) 68 flags |= STREAM_ITEM_FLAG_HAS_PTS; 69 else 70 flags &=~ STREAM_ITEM_FLAG_HAS_PTS; 71 pts=p; 72 } headerhasptsitem73 bool headerhaspts() const 74 { 75 return flags & STREAM_ITEM_FLAG_HAS_PTS; 76 } headerptsitem77 pts_t headerpts() const 78 { 79 return pts; 80 } headerptsitem81 pts_t headerpts(pts_t reference) const 82 { 83 if (flags & STREAM_ITEM_FLAG_HAS_PTS) 84 return ptsreference(pts,reference); 85 return AV_NOPTS_VALUE; 86 } clearptsitem87 void clearpts() 88 { 89 flags &=~ STREAM_ITEM_FLAG_HAS_PTS; 90 pts=AV_NOPTS_VALUE; 91 } is_frameitem92 bool is_frame() const 93 { 94 return flags & STREAM_ITEM_FLAG_FRAME; 95 } 96 } 97 ; 98 typedef std::list<item> itemlisttype; 99 100 protected: 101 itemlisttype items; 102 unsigned int itemlistsize; 103 buffer data; 104 uint32_t offset; 105 std::string header; 106 filepos_t curpos; 107 const streamtype::type type; 108 bool transportstream; 109 dvbcut_off_t nextfilepos; 110 111 public: 112 streamdata(streamtype::type t, bool transport_stream, uint32_t buffersize=256<<10) : 113 itemlistsize(0), data(buffersize), offset(0), curpos(0), type(t), transportstream(transport_stream) 114 {} ~streamdata()115 ~streamdata() 116 {} 117 itemlist()118 const std::list<item> &itemlist() const 119 { 120 return items; 121 } empty()122 bool empty() const 123 { 124 return items.empty(); 125 } pop()126 void pop() 127 { 128 items.pop_front(); 129 --itemlistsize; 130 if (items.empty()) { 131 itemlistsize=0; // ...should be redundant 132 offset=0; 133 curpos+=data.inbytes(); 134 data.clear(); 135 } else { 136 data.discard(items.front().bufferposition-offset); 137 offset=items.front().bufferposition; 138 curpos=items.front().fileposition; 139 if (offset & (1ul<<31)) { 140 for(std::list<item>::iterator it=items.begin();it!=items.end();++it) 141 it->bufferposition-=offset; 142 offset=0; 143 } 144 } 145 } pop(unsigned int number)146 void pop(unsigned int number) 147 { 148 if (number==0) 149 return; 150 if (number>=itemlistsize) { 151 itemlistsize=0; 152 offset=0; 153 curpos+=data.inbytes(); 154 data.clear(); 155 return; 156 } 157 158 --number; 159 for (unsigned int i=0;i<number;++i) 160 items.pop_front(); 161 itemlistsize-=number; 162 163 pop(); 164 } discard(uint32_t bytes)165 void discard(uint32_t bytes) 166 { 167 if (bytes==0) 168 return; 169 if (bytes>=data.inbytes()) { 170 curpos+=data.inbytes(); 171 data.clear(); 172 items.clear(); 173 itemlistsize=0; 174 offset=0; 175 return; 176 } 177 data.discard(bytes); 178 offset+=bytes; 179 curpos+=bytes; 180 if (items.empty()) 181 return; 182 std::list<item>::iterator it=items.begin(); 183 std::list<item>::iterator nx=it; 184 ++nx; 185 while(nx!=items.end()) { 186 if (nx->bufferposition>offset) 187 break; 188 ++nx; 189 it=items.erase(it); 190 --itemlistsize; 191 } 192 if (it->bufferposition<offset) { 193 it->fileposition += offset-it->bufferposition; 194 it->bufferposition=offset; 195 } 196 curpos=items.front().fileposition; 197 if (offset & (1ul<<31)) { 198 for(std::list<item>::iterator it=items.begin();it!=items.end();++it) 199 it->bufferposition-=offset; 200 offset=0; 201 } 202 } append(const void * d,int s)203 void append(const void *d, int s) 204 { 205 data.putdata(d,s,true); 206 } 207 void appenditem(filepos_t fp, const std::string &header, const void *d, int s); appenditem(filepos_t fp,int flags,pts_t pts,const void * d,int s)208 void appenditem(filepos_t fp, int flags, pts_t pts, const void *d, int s) 209 { 210 if (items.empty()) 211 curpos=fp; 212 items.push_back(item(fp,flags,pts,offset+data.inbytes())); 213 ++itemlistsize; 214 data.putdata(d,s,true); 215 } getdata()216 const void *getdata() const 217 { 218 return data.data(); 219 } getdata()220 void *getdata() 221 { 222 return data.data(); 223 } getdata(uint32_t bufferpos)224 const void *getdata(uint32_t bufferpos) const 225 { 226 return (char*)data.data()+(bufferpos-offset); 227 } getdata(uint32_t bufferpos)228 void *getdata(uint32_t bufferpos) 229 { 230 return (char*)data.data()+(bufferpos-offset); 231 } getbuffer()232 const buffer &getbuffer() const 233 { 234 return data; 235 } getoffset()236 uint32_t getoffset() const 237 { 238 return offset; 239 } inbytes()240 unsigned int inbytes() const 241 { 242 return data.inbytes(); 243 } discardheader()244 void discardheader() 245 { 246 if (!items.empty()) 247 items.front().clearpts(); 248 } getcurpos()249 const filepos_t &getcurpos() const 250 { 251 return curpos; 252 } getitemlistsize()253 unsigned int getitemlistsize() const 254 { 255 return itemlistsize; 256 } 257 void audio_addpts(uint32_t startbufferpos=0, bool onepacket=false); 258 uint32_t ptsbufferpos(pts_t pts); 259 uint32_t closestptsbufferpos(pts_t pts); fileposbufferpos(filepos_t pos)260 uint32_t fileposbufferpos(filepos_t pos) 261 { 262 for (itemlisttype::iterator it=items.begin();it!=items.end();++it) 263 if (it->fileposition.packetposition() > pos.packetposition()) 264 return it->bufferposition; 265 else if (it->fileposition.packetposition() == pos.packetposition()) 266 return it->bufferposition+(pos.packetoffset()-it->fileposition.packetoffset()); 267 return offset+inbytes(); 268 } filepositem(filepos_t pos)269 const item &filepositem(filepos_t pos) 270 { 271 for (itemlisttype::iterator it=items.begin();it!=items.end();++it) 272 if (it->fileposition.packetposition() >= pos.packetposition()) 273 return *it; 274 return items.back(); 275 } bufferpositem(uint32_t bpos)276 const item &bufferpositem(uint32_t bpos) const 277 { 278 const item *i=&items.front(); 279 for (itemlisttype::const_iterator it=++items.begin();it!=items.end();++it) 280 if (it->bufferposition > bpos) 281 break; 282 else 283 i=&(*it); 284 return *i; 285 } 286 287 friend int tsfile::streamreader(streamhandle &s); 288 friend int psfile::streamreader(streamhandle &s); 289 }; 290 291 #endif 292