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_MPEGMUXER_H 22 #define _DVBCUT_MPEGMUXER_H 23 24 #define MINPACKSIZE 64 25 #define DTSMAXDELAY 90000 26 27 #include <list> 28 #include "defines.h" 29 #include "muxer.h" 30 #include "mpgfile.h" 31 32 typedef int64_t scr_t; 33 #define pts2scr(x) (((scr_t)(x))*300) 34 #define scr2pts(x) ((pts_t)((x)/300)) 35 36 /** 37 @author Sven Over 38 */ 39 class mpegmuxer : public muxer 40 { 41 public: 42 class bufferremoval 43 { 44 scr_t _scr; 45 int _bytes; 46 public: bufferremoval(scr_t scr,int bytes)47 bufferremoval(scr_t scr, int bytes) : _scr(scr),_bytes(bytes) 48 {} bytes()49 int bytes() 50 { 51 return _bytes; 52 } scr()53 scr_t scr() 54 { 55 return _scr; 56 } 57 }; 58 59 class au 60 { 61 protected: 62 void *data; 63 int size; 64 pts_t pts,dts; 65 int flags; 66 int pos; 67 public: 68 au(const void *_data,int _size, pts_t _pts, pts_t _dts, int _flags); 69 ~au(); getdata()70 const void *getdata() const 71 { 72 return data; 73 } getdata()74 void *getdata() 75 { 76 return (void*)((char*)data+pos); 77 } getsize()78 int getsize() 79 { 80 return size-pos; 81 } incomplete()82 bool incomplete() 83 { 84 return pos; 85 } getpos()86 int getpos() 87 { 88 return pos; 89 } addpos(int p)90 void addpos(int p) 91 { 92 pos+=p; 93 if (pos>size) 94 pos=size; 95 } getpts()96 pts_t getpts() 97 { 98 return pts; 99 } getdts()100 pts_t getdts() 101 { 102 return dts; 103 } getflags()104 int getflags() 105 { 106 return flags; 107 } addflags(int fl)108 void addflags(int fl) 109 { 110 flags|=fl; 111 } unsetflags(int fl)112 void unsetflags(int fl) 113 { 114 flags &= ~fl; 115 } 116 }; 117 118 class pack 119 { 120 protected: 121 void *data; 122 int size; 123 scr_t minscr,maxscr; 124 pts_t dts; 125 int payloadpos; 126 int payloadlen; 127 int aupayloadlen; 128 friend class mpegmuxer; 129 130 public: 131 pack(int packsize, int payloadsize, int muxrate, pts_t _dts); 132 ~pack(); 133 getdata()134 const void *getdata() const 135 { 136 return data; 137 } getsize()138 int getsize() const 139 { 140 return size; 141 } getpayload()142 void *getpayload() 143 { 144 return (void*)((char*)data+payloadpos); 145 } getpayloadlen()146 int getpayloadlen() const 147 { 148 return payloadlen; 149 } addaupayload(int p)150 void addaupayload(int p) 151 { 152 aupayloadlen+=p; 153 } getaupayloadlen()154 int getaupayloadlen() const 155 { 156 return aupayloadlen; 157 } 158 void setscr(scr_t scr); setlastdts(pts_t dts)159 void setlastdts(pts_t dts) 160 { 161 setminscr(pts2scr(dts-DTSMAXDELAY)); 162 } setminscr(scr_t scr)163 void setminscr(scr_t scr) 164 { 165 if (scr>minscr) 166 minscr=scr; 167 } setmaxscr(scr_t scr)168 void setmaxscr(scr_t scr) 169 { 170 if (scr<maxscr) 171 maxscr=scr; 172 } getminscr()173 scr_t getminscr() const 174 { 175 return minscr; 176 } getmaxscr()177 scr_t getmaxscr() const 178 { 179 return maxscr; 180 } getdts()181 pts_t getdts() const 182 { 183 return dts; 184 } nopayload()185 void nopayload() 186 { 187 payloadlen=0; 188 } 189 maxpayload(int packsize)190 static int maxpayload(int packsize) 191 { 192 return packsize-14; 193 } 194 195 bool operator<(const pack &p) 196 { 197 return maxscr<p.maxscr; 198 } 199 200 bool write(int fd); 201 }; 202 203 class stream 204 { 205 protected: 206 std::list<au*> aulist; 207 std::list<pack*> packlist; 208 std::list<bufferremoval> bufferremovals; 209 streamtype::type type; 210 int id; 211 int bufsize; 212 int filllevel; 213 int packet; 214 uint32_t startcode; 215 uint16_t pstdbuffer; 216 friend class mpegmuxer; 217 218 public: 219 stream(streamtype::type _type, int _id, int _bufsize, int _pstdbuffer, bool bufferscale=true) : type(_type)220 type(_type), id(_id&0x3ff), bufsize(_bufsize), filllevel(0), packet(0) 221 { 222 if (bufferscale) 223 pstdbuffer=htom16(0x6000|((_pstdbuffer/1024)&0x1fff)); 224 else 225 pstdbuffer=htom16(0x4000|((_pstdbuffer/128)&0x1fff)); 226 227 if ( (id&~0xff)==0x100 ) 228 startcode=mbo32(0x1bd); 229 else if ( (id&~0xff)==0x200 ) 230 startcode=mbo32(0x1bf); 231 else 232 startcode=htom32(0x100|id); 233 } ~stream()234 ~stream() 235 { 236 for(std::list<au*>::iterator it=aulist.begin();it!=aulist.end();++it) 237 delete *it; 238 for(std::list<pack*>::iterator it=packlist.begin();it!=packlist.end();++it) 239 delete *it; 240 } getbufsize()241 int getbufsize() const 242 { 243 return bufsize; 244 } getbuffree()245 int getbuffree() const 246 { 247 return bufsize-filllevel; 248 } getstartcode()249 uint32_t getstartcode() const 250 { 251 return startcode; 252 } getpstdbuffer()253 uint16_t getpstdbuffer() const 254 { 255 return pstdbuffer; 256 } getid()257 int getid() const 258 { 259 return id; 260 } fill(int bytes)261 void fill(int bytes) 262 { 263 filllevel+=bytes; 264 } unfill(int bytes)265 void unfill(int bytes) 266 { 267 filllevel-=bytes; 268 if (filllevel<0) 269 filllevel=0; 270 } zerofill()271 void zerofill() 272 { 273 filllevel=0; 274 } getfill()275 int getfill() const 276 { 277 return filllevel; 278 } 279 bool operator<(const stream &s) const 280 { 281 if (packlist.empty()) 282 return false; 283 if (s.packlist.empty()) 284 return true; 285 return packlist.front()->getmaxscr()<s.packlist.front()->getmaxscr(); 286 } 287 bool operator<(const scr_t &s) const 288 { 289 if (packlist.empty()) 290 return false; 291 return packlist.front()->getmaxscr()<s; 292 } 293 }; 294 295 protected: 296 int fd; 297 stream *st[MAXAVSTREAMS]; 298 int muxrate; 299 int packsize; 300 pts_t ptsoffset; 301 int aucounter; 302 void *systemhdr; 303 int systemhdrlen; 304 bool pespacket_setlength; 305 scr_t scr; 306 int scrpack; 307 308 bool flush(bool flushall); 309 void packetizer(int str, pts_t maxdts); 310 311 public: 312 mpegmuxer(uint32_t audiostreammask, mpgfile &mpg, const char *filename, bool dvdnavpackets=true, int packsize_bytes=2048, int muxrate_bitsps=10080000); 313 ~mpegmuxer(); 314 315 virtual bool putpacket(int str, const void *data, int len, pts_t pts, pts_t dts, uint32_t flags=0); ready()316 virtual bool ready() 317 { 318 return fd>=0; 319 } finish()320 virtual void finish() 321 { 322 flush(true); 323 } 324 }; 325 326 #endif 327 328