Logo Search packages:      
Sourcecode: kaffeine version File versions

ts2pes.cpp

/*  Code from :

 *  mpegtools for the Siemens Fujitsu DVB PCI card
 *
 * Copyright (C) 2000, 2001 Marcus Metzler
 *            for convergence integrated media GmbH
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 *

 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *

 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 * Or, point your browser to http://www.gnu.org/copyleft/gpl.html
 */

#include "ts2pes.h"

#define FILE_LIMIT 1024*1024*2047



/*QFile fileOutPes;
QString fileOutName;
int fileOutNum;
char fileOutIndex[10]={'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j' };
int fileLength;*/

unsigned int g_bitrates[3][16] =
{{0,32,64,96,128,160,192,224,256,288,320,352,384,416,448,0},
 {0,32,48,56,64,80,96,112,128,160,192,224,256,320,384,0},
 {0,32,40,48,56,64,80,96,112,128,160,192,224,256,320,0}};

uint32_t g_freq[4] = {441, 480, 320, 0};



uint64_t Ts2Pes::trans_pts_dts(uint8_t *pts)
{
      uint64_t wts;

      wts = ((uint64_t)((pts[0] & 0x0E) << 5) |
             ((pts[1] & 0xFC) >> 2)) << 24;
      wts |= (((pts[1] & 0x03) << 6) |
            ((pts[2] & 0xFC) >> 2)) << 16;
      wts |= (((pts[2] & 0x02) << 6) |
            ((pts[3] & 0xFE) >> 1)) << 8;
      wts |= (((pts[3] & 0x01) << 7) |
            ((pts[4] & 0xFE) >> 1));
      return wts;
}



uint16_t Ts2Pes::get_pid(uint8_t *pid)
{
      uint16_t pp = 0;

      pp = (pid[0] & PID_MASK_HI)<<8;
      pp |= pid[1];

      return pp;
}



void Ts2Pes::reset_ipack(ipack *p)
{
      p->found = 0;
      p->cid = 0;
      p->plength = 0;
      p->flag1 = 0;
      p->flag2 = 0;
      p->hlength = 0;
      p->mpeg = 0;
      p->check = 0;
      p->which = 0;
      p->done = 0;
      p->count = 0;
      p->size = p->size_orig;
}



void Ts2Pes::init_ipack(ipack *p, int size, void (*func)(uint8_t *buf,  int size, void *priv), int ps)
{
      if ( !(p->buf = (uint8_t*)malloc(size)) ){
            fprintf(stderr,"Couldn't allocate memory for ipack\n");
            //exit(1);
      }
      p->ps = ps;
      p->size_orig = size;
      p->func = func;
      reset_ipack(p);
      p->has_ai = 0;
      p->has_vi = 0;
      p->start = 0;
}



void Ts2Pes::write_ipack(ipack *p, uint8_t *data, int count)
{

      uint8_t headr[3] = { 0x00, 0x00, 0x01} ;
      int diff =0;

      if (p->count < 6){
            if (trans_pts_dts(p->pts) > trans_pts_dts(p->last_pts))
                  memcpy(p->last_pts, p->pts, 5);
            p->count = 0;
            memcpy(p->buf+p->count, headr, 3);
            p->count += 6;
      }
      if ( p->size == p->size_orig && p->plength &&
           (diff = 6+p->plength - p->found + p->count +count) > p->size &&
           diff < 3*p->size/2){

                  p->size = diff/2;
//                fprintf(stderr,"size: %d \n",p->size);
      }
      if (p->count + count < p->size){
            memcpy(p->buf+p->count, data, count);
            p->count += count;
      } else {
            int rest = p->size - p->count;
            if (rest < 0) rest = 0;
            memcpy(p->buf+p->count, data, rest);
            p->count += rest;
//          fprintf(stderr,"count: %d \n",p->count);
            send_ipack(p);
            if (count - rest > 0)
                  write_ipack(p, data+rest, count-rest);
      }
}



int Ts2Pes::getVinfo(uint8_t *mbuf, int count, VideoInfo *vi, int pr)
{
      uint8_t *headr;
      int found = 0;
        int sw;
      int form = -1;
      int c = 0;

      while (found < 4 && c+4 < count){
            uint8_t *b;

            b = mbuf+c;
            if ( b[0] == 0x00 && b[1] == 0x00 && b[2] == 0x01
                 && b[3] == 0xb3) found = 4;
            else {
                  c++;
            }
      }

      if (! found) return -1;
      c += 4;
      if (c+12 >= count) return -1;
      headr = mbuf+c;

      vi->horizontal_size     = ((headr[1] &0xF0) >> 4) | (headr[0] << 4);
      vi->vertical_size = ((headr[1] &0x0F) << 8) | (headr[2]);

        sw = (int)((headr[3]&0xF0) >> 4) ;

        switch( sw ){
      case 1:
            if (pr)
                  fprintf(stderr,"Videostream: ASPECT: 1:1");
            vi->aspect_ratio = 100;
            break;
      case 2:
            if (pr)
                  fprintf(stderr,"Videostream: ASPECT: 4:3");
                vi->aspect_ratio = 133;
            break;
      case 3:
            if (pr)
                  fprintf(stderr,"Videostream: ASPECT: 16:9");
                vi->aspect_ratio = 177;
            break;
      case 4:
            if (pr)
                  fprintf(stderr,"Videostream: ASPECT: 2.21:1");
                vi->aspect_ratio = 221;
            break;

        case 5:
        case 6:
        case 7:
        case 8:
        case 9:
        case 10:
        case 11:
        case 12:
        case 13:
        case 14:
        case 15:
            if (pr)
                  fprintf(stderr,"Videostream: ASPECT: reserved");
                vi->aspect_ratio = 0;
            break;

        default:
                vi->aspect_ratio = 0;
                return -1;
      }

      if (pr)
            fprintf(stderr,"  Size = %dx%d",vi->horizontal_size,
                  vi->vertical_size);

        sw = (int)(headr[3]&0x0F);

        switch ( sw ) {
      case 1:
            if (pr)
                  fprintf(stderr,"  FRate: 23.976 fps");
                vi->framerate = 24000/1001.;
            form = -1;
            break;
      case 2:
            if (pr)
                  fprintf(stderr,"  FRate: 24 fps");
                vi->framerate = 24;
            form = -1;
            break;
      case 3:
            if (pr)
                  fprintf(stderr,"  FRate: 25 fps");
                vi->framerate = 25;
            form = VIDEO_MODE_PAL;
            break;
      case 4:
            if (pr)
                  fprintf(stderr,"  FRate: 29.97 fps");
                vi->framerate = 30000/1001.;
            form = VIDEO_MODE_NTSC;
            break;
      case 5:
            if (pr)
                  fprintf(stderr,"  FRate: 30 fps");
                vi->framerate = 30;
            form = VIDEO_MODE_NTSC;
            break;
      case 6:
            if (pr)
                  fprintf(stderr,"  FRate: 50 fps");
                vi->framerate = 50;
            form = VIDEO_MODE_PAL;
            break;
      case 7:
            if (pr)
                  fprintf(stderr,"  FRate: 60 fps");
                vi->framerate = 60;
            form = VIDEO_MODE_NTSC;
            break;
      }

      vi->bit_rate = 400*(((headr[4] << 10) & 0x0003FC00UL)
                      | ((headr[5] << 2) & 0x000003FCUL) |
                      (((headr[6] & 0xC0) >> 6) & 0x00000003UL));

      if (pr){
            fprintf(stderr,"  BRate: %.2f Mbit/s",(vi->bit_rate)/1000000.);
            fprintf(stderr,"\n");
      }
        vi->video_format = form;

      vi->off = c-4;
      return c-4;
}



int Ts2Pes::getAinfo(uint8_t *mbuf, int count, AudioInfo *ai, int pr)
{
      uint8_t *headr;
      int found = 0;
      int c = 0;
      int fr =0;

      while (!found && c < count){
            uint8_t *b = mbuf+c;

            if ( b[0] == 0xff && (b[1] & 0xf8) == 0xf8)
                  found = 1;
            else {
                  c++;
            }
      }

      if (!found) return -1;

      if (c+3 >= count) return -1;
        headr = mbuf+c;

      ai->layer = (headr[1] & 0x06) >> 1;

        if (pr)
            fprintf(stderr,"Audiostream: Layer: %d", 4-ai->layer);


      ai->bit_rate = g_bitrates[(3-ai->layer)][(headr[2] >> 4 )]*1000;

      if (pr){
            if (ai->bit_rate == 0)
                  fprintf (stderr,"  Bit rate: free");
            else if (ai->bit_rate == 0xf)
                  fprintf (stderr,"  BRate: reserved");
            else
                  fprintf (stderr,"  BRate: %d kb/s", ai->bit_rate/1000);
      }

      fr = (headr[2] & 0x0c ) >> 2;
      ai->frequency = g_freq[fr]*100;

      if (pr){
            if (ai->frequency == 3)
                  fprintf (stderr, "  Freq: reserved\n");
            else
                  fprintf (stderr,"  Freq: %2.1f kHz\n",
                         ai->frequency/1000.);
      }
      ai->off = c;
      return c;
}



void Ts2Pes::psPes(ipack *p)
{
      int check;
      uint8_t pbuf[PS_HEADER_L2];
      static int muxr = 0;
      static int ai = 0;
      static int vi = 0;
      static int start = 0;
      static uint32_t SCR = 0;

      if (p->mpeg == 2){
            if ( (p->buf[3]>=VIDEO_STREAM_S) && (p->buf[3]<=VIDEO_STREAM_E) ) {
                  if (!p->has_vi){
                        if(getVinfo(p->buf, p->count, &p->vi,1) >=0) {
                              p->has_vi = 1;
                              vi = p->vi.bit_rate;
                        }
                  }
            }
            else if ( (p->buf[3]>=AUDIO_STREAM_S) && (p->buf[3]<=AUDIO_STREAM_E) ) {
                  if (!p->has_ai){
                        if(getAinfo(p->buf, p->count, &p->ai,1) >=0) {
                              p->has_ai = 1;
                              ai = p->ai.bit_rate;
                        }
                  }
            }

            if (p->has_vi && vi && !muxr){
                  muxr = (vi+ai)/400;
            }

            if ( start && muxr && (p->buf[7] & PTS_ONLY) && (p->has_ai ||
                               p->buf[9+p->buf[8]+4] == 0xb3)){
                  SCR = trans_pts_dts(p->pts)-3600;

                  check = write_ps_header(pbuf,
                                    SCR,
                                    muxr, 1, 0, 0, 1, 1, 1,
                                    0, 0, 0, 0, 0, 0);

                  p->func(pbuf, check , p->data);
            }

            if (muxr && !start && vi){
                  SCR = trans_pts_dts(p->pts)-3600;
                  check = write_ps_header(pbuf,
                                    SCR,
                                    muxr, 1, 0, 0, 1, 1, 1,
                                    0xC0, 0, 64, 0xE0, 1, 460);
                  start = 1;
                  p->func(pbuf, check , p->data);
            }

            if (start)
                  p->func(p->buf, p->count, p->data);
      }
}



void Ts2Pes::init_ps(ps_packet *p)
{
      p->stuff_length=0xF8;
      p->data = NULL;
      p->sheader_length = 0;
      p->audio_bound = 0;
      p->video_bound = 0;
      p->npes = 0;
      p->mpeg = 2;
}



void Ts2Pes::kill_ps(ps_packet *p)
{
      if (p->data)
            free(p->data);
      init_ps(p);
}



int Ts2Pes::cwrite_ps(uint8_t *buf, ps_packet *p, long length)
{
      long count, i=length;
      uint8_t headr1[4] = {0x00, 0x00, 0x01, 0xBA };
      uint8_t headr2[4] = {0x00, 0x00, 0x01, 0xBB };
      uint8_t buffy = 0xFF;


      memcpy(buf,headr1,4);
      count = 4;
      if (p->mpeg == 2){
            memcpy(buf+count,p->scr,6);
            count += 6;
            memcpy(buf+count,p->mux_rate,3);
            count += 3;
            memcpy(buf+count,&p->stuff_length,1);
            count++;
            for(i=0; i< (p->stuff_length & 3); i++){
                  memcpy(buf+count,&buffy,1);
                  count++;
            }
      } else {
            memcpy(buf+count,p->scr,5);
            count += 5;
            memcpy(buf+count,p->mux_rate,3);
            count += 3;
      }
      if (p->sheader_length){
            memcpy(buf+count,headr2,4);
            count += 4;
            memcpy(buf+count,p->sheader_llength,2);
            count += 2;
            if ( p->mpeg == 2){
                  memcpy(buf+count,p->rate_bound,3);
                  count += 3;
                  memcpy(buf+count,&p->audio_bound,1);
                  count++;
                  memcpy(buf+count,&p->video_bound,1);
                  count++;
                  memcpy(buf+count,&p->reserved,1);
                  count++;
            }
            memcpy(buf+count,p->data,p->sheader_length);
            count += p->sheader_length;
      }

      return count;
}



void Ts2Pes::setl_ps(ps_packet *p)
{
      short *ll;
      
      ll = (short *) p->sheader_llength;
      if (p->mpeg == 2) p->sheader_length = ntohs(*ll) - 6;
      else p->sheader_length = ntohs(*ll);
      p->data = (uint8_t *) malloc(p->sheader_length);
}



int Ts2Pes::write_ps_header( uint8_t *buf, uint32_t SCR, long muxr, uint8_t audio_bound, uint8_t fixed,
                uint8_t CSPS, uint8_t audio_lock, uint8_t video_lock, uint8_t video_bound, uint8_t stream1,
                uint8_t buffer1_scale, uint32_t buffer1_size, uint8_t stream2, uint8_t buffer2_scale, uint32_t buffer2_size)
{
      ps_packet p;
      uint8_t *pts;
      long lpts;
      init_ps(&p);

      lpts = htonl(SCR);
      pts = (uint8_t *) &lpts;


      p.mpeg = 2;
// SCR = 0
      p.scr[0] = 0x44;
      p.scr[1] = 0x00;
      p.scr[2] = 0x04;
      p.scr[3] = 0x00;
      p.scr[4] = 0x04;
      p.scr[5] = 0x01;

// SCR = PTS
      p.scr[0] = 0x44 | ((pts[0] >> 3)&0x18) | ((pts[0] >> 4)&0x03);
      p.scr[1] = 0x00 | ((pts[0] << 4)&0xF0) | ((pts[1] >> 4)&0x0F);
      p.scr[2] = 0x04 | ((pts[1] << 4)&0xF0) | ((pts[2] >> 4)&0x08)
            | ((pts[2] >> 5)&0x03);
      p.scr[3] = 0x00 | ((pts[2] << 3)&0xF8) | ((pts[3] >> 5)&0x07);
      p.scr[4] = 0x04 | ((pts[3] << 3)&0xF8);
      p.scr[5] = 0x01;

      p.mux_rate[0] = (uint8_t)(muxr >> 14);
      p.mux_rate[1] = (uint8_t)(0xff & (muxr >> 6));
      p.mux_rate[2] = (uint8_t)(0x03 | ((muxr & 0x3f) << 2));

      p.stuff_length = 0xF8;

      if (stream1 && stream2){
            p.sheader_llength[0] = 0x00;
            p.sheader_llength[1] = 0x0c;

            setl_ps(&p);

            p.rate_bound[0] = (uint8_t)(0x80 | (muxr >>15));
            p.rate_bound[1] = (uint8_t)(0xff & (muxr >> 7));
            p.rate_bound[2] = (uint8_t)(0x01 | ((muxr & 0x7f)<<1));


            p.audio_bound = (uint8_t)((audio_bound << 2)|(fixed << 1)|CSPS);
            p.video_bound = (uint8_t)((audio_lock << 7)|
                             (video_lock << 6)|0x20|video_bound);
            p.reserved = (uint8_t)(0xFF >> 1);

            p.data[0] =  stream2;
            p.data[1] =  (uint8_t) (0xc0 | (buffer2_scale << 5) |
                           (buffer2_size >> 8));
            p.data[2] =  (uint8_t) (buffer2_size & 0xff);
            p.data[3] =  stream1;
            p.data[4] =  (uint8_t) (0xc0 | (buffer1_scale << 5) |
                           (buffer1_size >> 8));
            p.data[5] =  (uint8_t) (buffer1_size & 0xff);

            cwrite_ps(buf, &p, PS_HEADER_L2);
            kill_ps(&p);
            return PS_HEADER_L2;
      } else {
            cwrite_ps(buf, &p, PS_HEADER_L1);
            kill_ps(&p);
            return PS_HEADER_L1;
      }
}



void Ts2Pes::send_ipack(ipack *p)
{
      //int streamid=0;
      //int off;
      //int ac3_off = 0;
      //AudioInfo ai;
      //int nframes= 0;
      //int f=0;

      if (p->count < 10) return;
      p->buf[3] = p->cid;
      p->buf[4] = (uint8_t)(((p->count-6) & 0xFF00) >> 8);
      p->buf[5] = (uint8_t)((p->count-6) & 0x00FF);


      /*if (p->cid == PRIVATE_STREAM1){

            off = 9+p->buf[8];
            streamid = p->buf[off];
            if ((streamid & 0xF8) == 0x80){
                  ai.off = 0;
                  ac3_off = ((p->buf[off+2] << 8)| p->buf[off+3]);
                  if (ac3_off < p->count)
                        f=get_ac3info(p->buf+off+3+ac3_off,
                                    p->count-ac3_off, &ai,0);
                  if ( !f ){
                        nframes = (p->count-off-3-ac3_off)/
                              ai.framesize + 1;
                        p->buf[off+2] = (ac3_off >> 8)& 0xFF;
                        p->buf[off+3] = (ac3_off)& 0xFF;
                        p->buf[off+1] = nframes;

                        ac3_off +=  nframes * ai.framesize - p->count;
                  }
            }
      }*/

      if (p->ps) psPes(p);
      else p->func(p->buf, p->count, p->data);

      switch ( p->mpeg ){
      case 2:

            p->buf[6] = 0x80;
            p->buf[7] = 0x00;
            p->buf[8] = 0x00;
            p->count = 9;

            /*if (p->cid == PRIVATE_STREAM1 && (streamid & 0xF8)==0x80 ){
                  p->count += 4;
                  p->buf[9] = streamid;
                  p->buf[10] = (ac3_off >> 8)& 0xFF;
                  p->buf[11] = (ac3_off)& 0xFF;
                  p->buf[12] = 0;
            }*/

            break;
      case 1:
            p->buf[6] = 0x0F;
            p->count = 7;
            break;
      }

}



void Ts2Pes::instant_repack (uint8_t *buf, int count, ipack *p)
{

      int l;
      unsigned short *pl;
      int c=0;
      int tmp;

      while (c < count && (p->mpeg == 0 ||
                       (p->mpeg == 1 && p->found < 7) ||
                       (p->mpeg == 2 && p->found < 9))
             &&  (p->found < 5 || !p->done)){
            switch ( p->found ){
            case 0:
            case 1:
                  if (buf[c] == 0x00) p->found++;
                  else p->found = 0;
                  c++;
                  break;
            case 2:
                  if (buf[c] == 0x01) p->found++;
                  else if (buf[c] == 0){
                        p->found = 2;
                  } else p->found = 0;
                  c++;
                  break;
            case 3:
                  p->cid = 0;
                  tmp = p->found;
                  p->found = 0;
                  switch (buf[c]){
                        case PROG_STREAM_MAP:
                        case PRIVATE_STREAM2:
                        case PROG_STREAM_DIR:
                        case ECM_STREAM     :
                        case EMM_STREAM     :
                        case PADDING_STREAM :
                        case DSM_CC_STREAM  :
                        case ISO13522_STREAM:
                              p->found = tmp;
                              p->done = 1;
                  }
                  if ( ( (buf[c]>=VIDEO_STREAM_S) && (buf[c]<=VIDEO_STREAM_E) )
                        || ( (buf[c]>=AUDIO_STREAM_S) && (buf[c]<=AUDIO_STREAM_E) )
                        || (buf[c]==PRIVATE_STREAM1) ) {
                        p->found = tmp;
                        p->found++;
                        p->cid = buf[c];
                        c++;
                  }
                  break;
            case 4:
                  if (count-c > 1){
                        pl = (unsigned short *) (buf+c);
                        p->plength =  ntohs(*pl);
                        p->plen[0] = buf[c];
                        c++;
                        p->plen[1] = buf[c];
                        c++;
                        p->found+=2;
                  } else {
                        p->plen[0] = buf[c];
                        p->found++;
                        return;
                  }
                  break;
            case 5:
                  p->plen[1] = buf[c];
                  c++;
                  pl = (unsigned short *) p->plen;
                  p->plength = ntohs(*pl);
                  p->found++;
                  break;


            case 6:
                  if (!p->done){
                        p->flag1 = buf[c];
                        c++;
                        p->found++;
                        if ( (p->flag1 & 0xC0) == 0x80 ) p->mpeg = 2;
                        else {
                              p->hlength = 0;
                              p->which = 0;
                              p->mpeg = 1;
                              p->flag2 = 0;
                        }
                  }
                  break;

            case 7:
                  if ( !p->done && p->mpeg == 2){
                        p->flag2 = buf[c];
                        c++;
                        p->found++;
                  }
                  break;

            case 8:
                  if ( !p->done && p->mpeg == 2){
                        p->hlength = buf[c];
                        c++;
                        p->found++;
                  }
                  break;

            default:

                  break;
            }
      }


      if (c == count) return;

      if (!p->plength) p->plength = MMAX_PLENGTH-6;


      if ( p->done || ((p->mpeg == 2 && p->found >= 9)  || (p->mpeg == 1 && p->found >= 7)) ) {
             if ( ( (p->cid>=VIDEO_STREAM_S) && (p->cid<=VIDEO_STREAM_E) )
                  || ( (p->cid>=AUDIO_STREAM_S) && (p->cid<=AUDIO_STREAM_E) )
                  || (p->cid==PRIVATE_STREAM1) ) {
                  if (p->mpeg == 2 && p->found == 9){
                        write_ipack(p, &p->flag1, 1);
                        write_ipack(p, &p->flag2, 1);
                        write_ipack(p, &p->hlength, 1);
                  }

                  if (p->mpeg == 1 && p->found == 7){
                        write_ipack(p, &p->flag1, 1);
                  }


                  if (p->mpeg == 2 && (p->flag2 & PTS_ONLY) &&
                      p->found < 14){
                        while (c < count && p->found < 14){
                              p->pts[p->found-9] = buf[c];
                              write_ipack(p, buf+c, 1);
                              c++;
                              p->found++;
                        }
                        if (c == count) return;
                  }

                  if (p->mpeg == 1 && p->which < 2000){

                        if (p->found == 7) {
                              p->check = p->flag1;
                              p->hlength = 1;
                        }

                        while (!p->which && c < count &&
                               p->check == 0xFF){
                              p->check = buf[c];
                              write_ipack(p, buf+c, 1);
                              c++;
                              p->found++;
                              p->hlength++;
                        }

                        if ( c == count) return;

                        if ( (p->check & 0xC0) == 0x40 && !p->which){
                              p->check = buf[c];
                              write_ipack(p, buf+c, 1);
                              c++;
                              p->found++;
                              p->hlength++;

                              p->which = 1;
                              if ( c == count) return;
                              p->check = buf[c];
                              write_ipack(p, buf+c, 1);
                              c++;
                              p->found++;
                              p->hlength++;
                              p->which = 2;
                              if ( c == count) return;
                        }

                        if (p->which == 1){
                              p->check = buf[c];
                              write_ipack(p, buf+c, 1);
                              c++;
                              p->found++;
                              p->hlength++;
                              p->which = 2;
                              if ( c == count) return;
                        }

                        if ( (p->check & 0x30) && p->check != 0xFF){
                              p->flag2 = (p->check & 0xF0) << 2;
                              p->pts[0] = p->check;
                              p->which = 3;
                        }

                        if ( c == count) return;
                        if (p->which > 2){
                              if ((p->flag2 & PTS_DTS_FLAGS)
                                  == PTS_ONLY){
                                    while (c < count &&
                                           p->which < 7){
                                          p->pts[p->which-2] =
                                                buf[c];
                                          write_ipack(p,buf+c,1);
                                          c++;
                                          p->found++;
                                          p->which++;
                                          p->hlength++;
                                    }
                                    if ( c == count) return;
                              } else if ((p->flag2 & PTS_DTS_FLAGS)
                                       == PTS_DTS){
                                    while (c < count &&
                                           p->which< 12){
                                          if (p->which< 7)
                                                p->pts[p->which
                                                      -2] =
                                                      buf[c];
                                          write_ipack(p,buf+c,1);
                                          c++;
                                          p->found++;
                                          p->which++;
                                          p->hlength++;
                                    }
                                    if ( c == count) return;
                              }
                              p->which = 2000;
                        }

                  }

                  while ( c<count && p->found<(int)p->plength+6){
                        l = count -c;
                        if (l+p->found > (int)p->plength+6)
                              l = p->plength+6-p->found;
                        write_ipack(p, buf+c, l);
                        p->found += l;
                        c += l;
                  }
            }


            if ( p->done ){
                  if( p->found + count - c < (int)p->plength+6){
                        p->found += count-c;
                        c = count;
                  } else {
                        c += p->plength+6 - p->found;
                        p->found = p->plength+6;
                  }
            }

            if (p->plength && p->found == (int)p->plength+6) {
                  send_ipack(p);
                  reset_ipack(p);
                  if (c < count)
                        instant_repack(buf+c, count-c, p);
            }
      }
      return;
}




void Ts2Pes::write_out( uint8_t *buf, int count, void  *p)
{
      Ts2Pes *tp = (Ts2Pes*)(p);
      /*if ( (fileLength+count)>FILE_LIMIT ) {
            fileOutPes.close();
            fileOutNum++;
            if ( fileOutNum>9 ) {
                  return;
            }
            fileOutPes.setName( fileOutName+"_"+fileOutIndex[fileOutNum]+".mpg" );
            if ( !fileOutPes.open( IO_WriteOnly | IO_Truncate ) ) {
                  return;
            }
            fileLength = 0;
      }*/
      //fileLength+=
      tp->fileOutPes.writeBlock( (char*)buf, count );
}



Ts2Pes::Ts2Pes( QString outfile, uint16_t pida, uint16_t pidv, int ps, bool *ok )
{
      *ok = true;

      pa.data = this;
      pv.data = this;
      pidAudio = pida;
      pidVideo = pidv;
      pType = ps;
      fileOutPes.setName( outfile+".mpg" );
      if ( !fileOutPes.open( IO_WriteOnly | IO_Truncate ) ) *ok = false;
}



void Ts2Pes::run( uint8_t *buf, int count )
{
      int i;
      uint16_t pid;

      for( i = 0; i < count; i+= TS_SIZE){
            uint8_t off = 0;
            if ( count - i < TS_SIZE) break;
            pid = get_pid(buf+i+1);
            if (!(buf[3+i]&0x10)) // no payload?
                  continue;
            if (pid == pidVideo){
                  p = &pv;
            } else {
                  if (pid == pidAudio){
                        p = &pa;
                  } else continue;
            }
            if ( buf[1+i]&0x40) {
                  if (p->plength == MMAX_PLENGTH-6){
                        p->plength = p->found-6;
                        p->found = 0;
                        send_ipack(p);
                        reset_ipack(p);
                  }
            }

            if ( buf[3+i] & 0x20) {  // adaptation field?
                  off = buf[4+i] + 1;
            }

            instant_repack(buf+4+off+i, TS_SIZE-4-off, p);
      }
}



void Ts2Pes::go()
{
      init_ipack(&pa, IPACKS,write_out, pType);
      init_ipack(&pv, IPACKS,write_out, pType);
}



void Ts2Pes::stop()
{
      fileOutPes.close();
}



Ts2Pes::~Ts2Pes()
{
      fileOutPes.close();
}

Generated by  Doxygen 1.6.0   Back to index