MythTV  0.25-pre
pes.c
Go to the documentation of this file.
00001 /*
00002  * pes.c: MPEG PES functions for replex
00003  *        
00004  *
00005  * Copyright (C) 2003 Marcus Metzler <mocm@metzlerbros.de>
00006  *                    Metzler Brothers Systementwicklung GbR
00007  * Changes to use MythTV logging
00008  * Copyright (C) 2011 Gavin Hurlbut <ghurlbut@mythtv.org>
00009  *
00010  * This program is free software; you can redistribute it and/or
00011  * modify it under the terms of the GNU General Public License
00012  * as published by the Free Software Foundation; either version 2
00013  * of the License, or (at your option) any later version.
00014  *
00015  *
00016  * This program is distributed in the hope that it will be useful,
00017  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00018  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00019  * General Public License for more details.
00020  *
00021  *
00022  * You should have received a copy of the GNU General Public License
00023  * along with this program; if not, write to the Free Software
00024  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
00025  * Or, point your browser to http://www.gnu.org/copyleft/gpl.html
00026  *
00027  */
00028 
00029 #include <stdlib.h>
00030 #include <stdio.h>
00031 #include <string.h>
00032 
00033 #ifdef USING_MINGW
00034 #include <winsock2.h>
00035 #else
00036 #include <netinet/in.h>
00037 #endif
00038 
00039 #include "pes.h"
00040 #include "mythlogging.h"
00041 
00042 void printpts(int64_t pts)
00043 {
00044         int negative = 0;
00045         if (pts < 0){
00046                 negative = 1;
00047                 pts = -pts;
00048         }
00049         pts = pts/300;
00050         pts &= (MAX_PTS-1);
00051         LOG(VB_GENERAL, LOG_INFO, "%s%2d:%02d:%02d.%04d",
00052                 (negative ? "-" : ""),
00053                 (unsigned int)(pts/90000.0)/3600,
00054                 ((unsigned int)(pts/90000.0)%3600)/60,
00055                 ((unsigned int)(pts/90000.0)%3600)%60,
00056                 (((unsigned int)(pts/9.0)%36000000)%600000)%10000);
00057 }
00058 
00059 void printptss(int64_t pts)
00060 {
00061         int negative = 0;
00062         if (pts < 0){
00063                 negative = 0;
00064                 pts = -pts;
00065         }
00066         pts = pts/300;
00067         pts &= (MAX_PTS-1);
00068         LOG(VB_GENERAL, LOG_INFO, "%s%2d:%02d:%02d.%03d",
00069                 (negative ? "-" : ""),
00070                 (unsigned int)(pts/90000.0)/3600,
00071                 ((unsigned int)(pts/90000.0)%3600)/60,
00072                 ((unsigned int)(pts/90000.0)%3600)%60,
00073                 (((unsigned int)(pts/90.0)%3600000)%60000)%1000
00074                 );
00075 }
00076 
00077 /* use if you know that ptss are close and may overflow */
00078 int64_t ptsdiff(uint64_t pts1, uint64_t pts2)
00079 {
00080         switch (ptscmp(pts1, pts2)){
00081         case 0:
00082                 return 0;
00083                 break;
00084 
00085         case 1:
00086         case -2:
00087                 return (pts1 -pts2);
00088                 break;
00089 
00090         case 2:
00091                 return (pts1 + MAX_PTS2 -pts2);
00092                 break;
00093 
00094         case -1:
00095                 return (pts1 - (pts2+ MAX_PTS2));
00096                 break;
00097 
00098         }
00099 
00100         return 0;
00101 }
00102 
00103 /* use, if you need  an unsigned result in pts range */
00104 uint64_t uptsdiff(uint64_t pts1, uint64_t pts2)
00105 {
00106         int64_t diff;
00107 
00108         diff = pts1 - pts2;
00109                 
00110         if (diff < 0){
00111                 diff = MAX_PTS2 +diff;
00112         }
00113         return diff;
00114 }
00115 
00116 int ptscmp(uint64_t pts1, uint64_t pts2)
00117 {
00118         int ret;
00119 
00120         if (pts1 > pts2){
00121                 if ((pts1 - pts2) > MAX_PTS2/2)
00122                         ret = -1;
00123                 else 
00124                         ret = 1;
00125         } else if (pts1 == pts2) ret = 0;
00126         else {
00127                 if ((pts2 - pts1) > MAX_PTS2/2)
00128                         ret = 2;
00129                 else 
00130                         ret = -2;
00131         }
00132 #if 0
00133         LOG(VB_GENERAL, LOG_INFO, "PTSCMP: %lli %lli %d\n", pts1, pts2, ret);
00134         printpts(pts1);
00135         printpts(pts2);
00136 #endif
00137         return ret;
00138 }
00139 
00140 uint64_t ptsadd(uint64_t pts1, uint64_t pts2)
00141 {
00142         ptsinc(&pts1,pts2);
00143         return pts1;
00144 
00145 }
00146 
00147 void init_pes_in(pes_in_t *p, int t, ringbuffer *rb, int wi){
00148         p->type = t;
00149         p->found = 0;
00150         p->cid = 0;
00151         p->mpeg = 0;
00152         p->withbuf = wi;
00153         
00154         if (p->withbuf && !p->buf){
00155                 p->buf = malloc(MAX_PLENGTH*sizeof(uint8_t));
00156                 memset(p->buf,0,MAX_PLENGTH*sizeof(uint8_t));
00157         } else if (rb) p->rbuf = rb;
00158         if (p->rbuf) p->ini_pos = ring_wpos(p->rbuf); 
00159         p->done = 0;
00160         memset(p->pts, 0 , 5);
00161         memset(p->dts, 0 , 5);
00162 }
00163 
00164 
00165 void get_pes (pes_in_t *p, uint8_t *buf, int count, void (*func)(pes_in_t *p))
00166 {
00167 
00168         int l;
00169         unsigned short *pl;
00170         int done;
00171 
00172         uint8_t headr[3] = { 0x00, 0x00, 0x01} ;
00173         do {
00174                 int c=0;
00175                 done = 1;
00176                 while (c < count && (!p->mpeg ||
00177                                      (p->mpeg == 2 && p->found < 9))
00178                        &&  (p->found < 5 || !p->done)){
00179                         switch ( p->found ){
00180                         case 0:
00181                         case 1:
00182                                 if (buf[c] == 0x00) p->found++;
00183                                 else p->found = 0;
00184                                 c++;
00185                                 break;
00186                         case 2:
00187                                 if (buf[c] == 0x01) p->found++;
00188                                 else if (buf[c] == 0){
00189                                         p->found = 2;
00190                                 } else p->found = 0;
00191                                 c++;
00192                                 break;
00193                         case 3:
00194                                 p->cid = 0;
00195                                 switch (buf[c]){
00196                                 case PROG_STREAM_MAP:
00197                                 case PRIVATE_STREAM2:
00198                                 case PROG_STREAM_DIR:
00199                                 case ECM_STREAM     :
00200                                 case EMM_STREAM     :
00201                                 case PADDING_STREAM :
00202                                 case DSM_CC_STREAM  :
00203                                 case ISO13522_STREAM:
00204                                         p->done = 1;
00205                                 case PRIVATE_STREAM1:
00206                                 case VIDEO_STREAM_S ... VIDEO_STREAM_E:
00207                                 case AUDIO_STREAM_S ... AUDIO_STREAM_E:
00208                                         p->found++;
00209                                         p->cid = buf[c];
00210                                         c++;
00211                                         break;
00212                                 default:
00213                                 case PACK_START:
00214                                 case SYS_START:
00215                                         p->found = 0;
00216                                         c++;
00217                                         break;
00218                                 }
00219                                 break;
00220                         
00221 
00222                         case 4:
00223                                 if (count-c > 1){
00224                                         pl = (unsigned short *) (buf+c);
00225                                         p->plength =  ntohs(*pl);
00226                                         p->plen[0] = buf[c];
00227                                         c++;
00228                                         p->plen[1] = buf[c];
00229                                         c++;
00230                                         p->found+=2;
00231                                 } else {
00232                                         p->plen[0] = buf[c];
00233                                         p->found++;
00234                                         return;
00235                                 }
00236                                 break;
00237                         case 5:
00238                                 p->plen[1] = buf[c];
00239                                 c++;
00240                                 pl = (unsigned short *) p->plen;
00241                                 p->plength = ntohs(*pl);
00242                                 p->found++;
00243                                 break;
00244 
00245 
00246                         case 6:
00247                                 if (!p->done){
00248                                         p->flag1 = buf[c];
00249                                         c++;
00250                                         p->found++;
00251                                         if ( (p->flag1 & 0xC0) == 0x80 ) p->mpeg = 2;
00252                                         else {
00253                                                 LOG(VB_GENERAL, LOG_ERR,
00254                                                 "Error: THIS IS AN MPEG1 FILE");
00255                                                 exit(1);
00256                                         }
00257                                 }
00258                                 break;
00259 
00260                         case 7:
00261                                 if ( !p->done && p->mpeg == 2){
00262                                         p->flag2 = buf[c];
00263                                         c++;
00264                                         p->found++;
00265                                 }       
00266                                 break;
00267 
00268                         case 8:
00269                                 if ( !p->done && p->mpeg == 2){
00270                                         p->hlength = buf[c];
00271                                         c++;
00272                                         p->found++;
00273                                 }
00274                                 break;
00275                         
00276                         default:
00277 
00278                                 break;
00279                         }
00280                 }
00281 
00282                 if (!p->plength) p->plength = MMAX_PLENGTH-6;
00283 
00284 
00285                 if ( p->done || (p->mpeg == 2 && p->found >= 9) ){
00286                         switch (p->cid){
00287                         
00288                         case AUDIO_STREAM_S ... AUDIO_STREAM_E:                 
00289                         case VIDEO_STREAM_S ... VIDEO_STREAM_E:
00290                         case PRIVATE_STREAM1:
00291 
00292                                 if (p->withbuf){
00293                                         memcpy(p->buf, headr, 3);
00294                                         p->buf[3] = p->cid;
00295                                         memcpy(p->buf+4,p->plen,2);
00296                                 } else {
00297                                         memcpy(p->hbuf, headr, 3);
00298                                         p->hbuf[3] = p->cid;
00299                                         memcpy(p->hbuf+4,p->plen,2);
00300                                 }
00301 
00302                                 if (p->found == 9){
00303                                         if (p->withbuf){
00304                                                 p->buf[6] = p->flag1;
00305                                                 p->buf[7] = p->flag2;
00306                                                 p->buf[8] = p->hlength;
00307                                         } else {
00308                                                 p->hbuf[6] = p->flag1;
00309                                                 p->hbuf[7] = p->flag2;
00310                                                 p->hbuf[8] = p->hlength;
00311                                         }
00312                                 }
00313 
00314                                 if ( (p->flag2 & PTS_ONLY) &&  p->found < 14){
00315                                         while (c < count && p->found < 14){
00316                                                 p->pts[p->found-9] = buf[c];
00317                                                 if (p->withbuf)
00318                                                         p->buf[p->found] = buf[c];
00319                                                 else 
00320                                                         p->hbuf[p->found] = buf[c];
00321                                                 c++;
00322                                                 p->found++;
00323                                         }
00324                                         if (c == count) return;
00325                                 }
00326 
00327                                 if (((p->flag2 & PTS_DTS) == 0xC0) && p->found < 19){
00328                                         while (c < count && p->found < 19){
00329                                                 p->dts[p->found-14] = buf[c];
00330                                                 if (p->withbuf)
00331                                                         p->buf[p->found] = buf[c];
00332                                                 else 
00333                                                         p->hbuf[p->found] = buf[c];
00334                                                 c++;
00335                                                 p->found++;
00336                                         }
00337                                         if (c == count) return;
00338                                 }
00339 
00340 
00341                                 while (c < count && p->found < p->plength+6){
00342                                         l = count -c;
00343                                         if (l+p->found > p->plength+6)
00344                                                 l = p->plength+6-p->found;
00345                                         if (p->withbuf)
00346                                                 memcpy(p->buf+p->found, buf+c, l);
00347                                         else {
00348                                                 if ( p->found < 
00349                                                      (unsigned int)p->hlength+9 ){
00350                                                         int rest = p->hlength+9-p->found;
00351                                                         memcpy(p->hbuf+p->found, buf+c, rest);
00352                                                         if (ring_write(p->rbuf, buf+c+rest, 
00353                                                                        l-rest) <0){
00354                                                                 exit(1);
00355                                                         }
00356                                                 } else {
00357                                                         if (ring_write(p->rbuf, buf+c, l)<0){
00358                                                                 LOG(VB_GENERAL, LOG_ERR,
00359                                                                         "ring buffer overflow %d",
00360                                                                         p->rbuf->size);
00361                                                                 exit(1);
00362                                                         }
00363                                                 }
00364                                         }
00365 
00366                                         p->found += l;
00367                                         c += l;
00368                                 }                       
00369                                 if(p->found == p->plength+6){
00370                                         func(p);
00371                                 }
00372                                 break;
00373                         }
00374 
00375                         if ( p->done ){
00376                                 if( p->found + count - c < p->plength+6){
00377                                         p->found += count-c;
00378                                         c = count;
00379                                 } else {
00380                                         c += p->plength+6 - p->found;
00381                                         p->found = p->plength+6;
00382                                 }
00383                         }
00384 
00385                         if (p->plength && p->found == p->plength+6) {
00386                                 init_pes_in(p, p->type, NULL, p->withbuf);
00387                                 if (c < count) {
00388                                         done = 0;
00389                                         count -= c;
00390                                         buf += c;
00391                                 }
00392                         }
00393                 } 
00394         } while(!done);
00395         return;
00396 }
00397 
00398 
00399 static uint32_t scr_base_ps(uint8_t *scr)
00400 {
00401         uint32_t base = 0;
00402         uint8_t *buf = (uint8_t *)&base;
00403         
00404         buf[0] |= (uint8_t)((scr[0] & 0x18) << 3);
00405         buf[0] |= (uint8_t)((scr[0] & 0x03) << 4);
00406         buf[0] |= (uint8_t)((scr[1] & 0xF0) >> 4);
00407                  
00408         buf[1] |= (uint8_t)((scr[1] & 0x0F) << 4);
00409         buf[1] |= (uint8_t)((scr[2] & 0xF0) >> 4);
00410 
00411         buf[2] |= (uint8_t)((scr[2] & 0x08) << 4);
00412         buf[2] |= (uint8_t)((scr[2] & 0x03) << 5);
00413         buf[2] |= (uint8_t)((scr[3] & 0xF8) >> 3);
00414 
00415         buf[3] |= (uint8_t)((scr[3] & 0x07) << 5);
00416         buf[3] |= (uint8_t)((scr[4] & 0xF8) >> 3);
00417 
00418         base = ntohl(base);
00419         return base;
00420 }
00421 
00422 static uint16_t scr_ext_ps(uint8_t *scr)
00423 {
00424         short ext = 0;
00425 
00426         ext = (short)(scr[5] >> 1);
00427         ext += (short) (scr[4] &  0x03) * 128;
00428 
00429         return ext;
00430 }
00431 
00432 
00433 
00434 static void init_ps(ps_packet *p)
00435 {
00436         p->stuff_length=0xF8;
00437         p->data = NULL;
00438         p->sheader_length = 0;
00439         p->audio_bound = 0;
00440         p->video_bound = 0;
00441         p->npes = 0;
00442 }
00443 
00444 static void kill_ps(ps_packet *p)
00445 {
00446         if (p->data)
00447                 free(p->data);
00448         init_ps(p);
00449 }
00450 
00451 static void setlength_ps(ps_packet *p)
00452 {
00453         short *ll;
00454         ll = (short *) p->sheader_llength;
00455         p->sheader_length = ntohs(*ll) - 6;
00456 }
00457 
00458 static void setl_ps(ps_packet *p)
00459 {
00460         setlength_ps(p);
00461         p->data = (uint8_t *) malloc(p->sheader_length);
00462 }
00463 
00464 
00465 static int cwrite_ps(uint8_t *buf, ps_packet *p, uint32_t length)
00466 {
00467         long count,i;
00468         (void)length;
00469         uint8_t headr1[4] = {0x00, 0x00, 0x01, PACK_START };
00470         uint8_t headr2[4] = {0x00, 0x00, 0x01, SYS_START };
00471         uint8_t buffy = 0xFF;
00472 
00473 
00474         memcpy(buf,headr1,4);
00475         count = 4;
00476         memcpy(buf+count,p->scr,6);
00477         count += 6;
00478         memcpy(buf+count,p->mux_rate,3);
00479         count += 3;
00480         memcpy(buf+count,&p->stuff_length,1);
00481         count++;
00482         for(i=0; i< (p->stuff_length & 3); i++){
00483                 memcpy(buf+count,&buffy,1);
00484                 count++;
00485         }
00486 
00487         if (p->sheader_length){
00488                 memcpy(buf+count,headr2,4);
00489                 count += 4;
00490                 memcpy(buf+count,p->sheader_llength,2);
00491                 count += 2;
00492                 memcpy(buf+count,p->rate_bound,3);
00493                 count += 3;
00494                 memcpy(buf+count,&p->audio_bound,1);
00495                 count++;
00496                 memcpy(buf+count,&p->video_bound,1);
00497                 count++;
00498                 memcpy(buf+count,&p->reserved,1);
00499                 count++;
00500                 memcpy(buf+count,p->data,p->sheader_length);
00501                 count += p->sheader_length;
00502         }
00503 
00504         return count;
00505 }
00506 
00507 
00508 
00509 static int write_ps_header(uint8_t *buf,
00510                     uint64_t   SCR, 
00511                     uint32_t   muxr,
00512                     uint8_t    audio_bound,
00513                     uint8_t    fixed,
00514                     uint8_t    CSPS,
00515                     uint8_t    audio_lock,
00516                     uint8_t    video_lock,
00517                     uint8_t    video_bound,
00518                     uint8_t    navpack)
00519 {
00520         ps_packet p;
00521         uint8_t *scr;
00522         uint32_t lscr;
00523         uint16_t scr_ext = 0;
00524 
00525         init_ps(&p);
00526         
00527         lscr = htonl((uint32_t) ((SCR/300ULL) & 0x00000000FFFFFFFF));
00528         scr = (uint8_t *) &lscr;
00529         scr_ext = (uint16_t) ((SCR%300ULL) & 0x00000000000001FF);
00530         
00531 // SCR = 0
00532         p.scr[0] = 0x44;
00533         p.scr[1] = 0x00;
00534         p.scr[2] = 0x04;
00535         p.scr[3] = 0x00;
00536         p.scr[4] = 0x04;
00537         p.scr[5] = 0x01;
00538         
00539         p.scr[0] = 0x44 | ((scr[0] >> 3)&0x18) | ((scr[0] >> 4)&0x03);
00540         p.scr[1] = 0x00 | ((scr[0] << 4)&0xF0) | ((scr[1] >> 4)&0x0F);
00541         p.scr[2] = 0x04 | ((scr[1] << 4)&0xF0) | ((scr[2] >> 4)&0x08)
00542                 | ((scr[2] >> 5)&0x03);
00543         p.scr[3] = 0x00 | ((scr[2] << 3)&0xF8) | ((scr[3] >> 5)&0x07);
00544         p.scr[4] = 0x04 | ((scr[3] << 3)&0xF8) | ((scr_ext >> 7)&0x03);
00545         p.scr[5] = 0x01 | ((scr_ext << 1)&0xFF);
00546 
00547         
00548         muxr = muxr/50;
00549         p.mux_rate[0] = (uint8_t)(muxr >> 14);
00550         p.mux_rate[1] = (uint8_t)(0xff & (muxr >> 6));
00551         p.mux_rate[2] = (uint8_t)(0x03 | ((muxr & 0x3f) << 2));
00552 
00553         p.stuff_length = 0xF8;
00554         
00555         if (navpack){
00556                 p.sheader_llength[0] = 0x00;
00557                 p.sheader_llength[1] = 0x12;
00558 
00559                 setl_ps(&p);
00560                 
00561                 p.rate_bound[0] = (uint8_t)(0x80 | (muxr >>15));
00562                 p.rate_bound[1] = (uint8_t)(0xff & (muxr >> 7));
00563                 p.rate_bound[2] = (uint8_t)(0x01 | ((muxr & 0x7f)<<1));
00564 
00565         
00566                 p.audio_bound = (uint8_t)((audio_bound << 2)|(fixed << 1)|CSPS);
00567                 p.video_bound = (uint8_t)((audio_lock << 7)|
00568                                      (video_lock << 6)|0x20|video_bound);
00569                 p.reserved = (uint8_t)(0xFF >> 1);
00570 
00571                 p.data[0] = 0xB9;  
00572                 p.data[1] = 0xE0;  
00573                 p.data[2] = 0xE8;  
00574                 p.data[3] = 0xB8;  
00575                 p.data[4] = 0xC0;  
00576                 p.data[5] = 0x20;  
00577                 p.data[6] = 0xbd;  
00578                 p.data[7] = 0xe0;  
00579                 p.data[8] = 0x3a;  
00580                 p.data[9] = 0xBF;  
00581                 p.data[10] = 0xE0;  
00582                 p.data[11] = 0x02;  
00583 
00584                 cwrite_ps(buf, &p, PS_HEADER_L2);
00585                 kill_ps(&p);
00586                 return PS_HEADER_L2;
00587         } else {
00588                 cwrite_ps(buf, &p, PS_HEADER_L1);
00589                 kill_ps(&p);
00590                 return PS_HEADER_L1;
00591         }
00592 }
00593 
00594 
00595 static void get_pespts(uint8_t *spts,uint8_t *pts)
00596 {
00597         //Make sure to set the 1st 4 bits properly
00598         pts[0] = 0x01 |
00599                 ((spts[0] & 0xC0) >>5);
00600         pts[1] = ((spts[0] & 0x3F) << 2) |
00601                 ((spts[1] & 0xC0) >> 6);
00602         pts[2] = 0x01 | ((spts[1] & 0x3F) << 2) |
00603                 ((spts[2] & 0x80) >> 6);
00604         pts[3] = ((spts[2] & 0x7F) << 1) |
00605                 ((spts[3] & 0x80) >> 7);
00606         pts[4] = 0x01 | ((spts[3] & 0x7F) << 1);
00607 }
00608 
00609 int write_pes_header(uint8_t id, int length , uint64_t PTS, uint64_t DTS, 
00610                      uint8_t *obuf, int stuffing, uint8_t ptsdts)
00611 {
00612         uint8_t le[2];
00613         uint8_t dummy[3];
00614         uint8_t *pts;
00615         uint8_t ppts[5];
00616         uint32_t lpts;
00617         uint8_t *dts;
00618         uint8_t pdts[5];
00619         uint32_t ldts;
00620         int c;
00621         uint8_t headr[3] = {0x00, 0x00, 0x01};
00622         
00623         lpts = htonl((PTS/300ULL) & 0x00000000FFFFFFFFULL);
00624         pts = (uint8_t *) &lpts;
00625         get_pespts(pts,ppts);
00626         if ((PTS/300ULL) & 0x0000000100000000ULL) ppts[0] |= 0x80;
00627 
00628         ldts = htonl((DTS/300ULL) & 0x00000000FFFFFFFFULL);
00629         dts = (uint8_t *) &ldts;
00630         get_pespts(dts,pdts);
00631         if ((DTS/300ULL) & 0x0000000100000000ULL) pdts[0] |= 0x80;
00632 
00633         c = 0;
00634         memcpy(obuf+c,headr,3);
00635         c += 3;
00636         memcpy(obuf+c,&id,1);
00637         c++;
00638 
00639         le[0] = 0;
00640         le[1] = 0;
00641         length -= 6;
00642 
00643         le[0] |= ((uint8_t)(length >> 8) & 0xFF); 
00644         le[1] |= ((uint8_t)(length) & 0xFF); 
00645         memcpy(obuf+c,le,2);
00646         c += 2;
00647 
00648         if (id == PADDING_STREAM){
00649                 memset(obuf+c,0xff,length);
00650                 c+= length;
00651                 return c;
00652         }
00653 
00654         dummy[0] = 0x80;
00655         dummy[1] = 0;
00656         dummy[2] = stuffing;
00657         
00658         if (ptsdts == PTS_ONLY){
00659                 dummy[2] += 5;
00660                 dummy[1] |= PTS_ONLY;
00661                 ppts[0] |= 0x20;
00662         } else  if (ptsdts == PTS_DTS){
00663                 dummy[2] += 10;
00664                 dummy[1] |= PTS_DTS;
00665                 ppts[0] |= 0x30;
00666                 pdts[0] |= 0x10;
00667         }
00668                 
00669 
00670         memcpy(obuf+c,dummy,3);
00671         c += 3;
00672 
00673         if (ptsdts == PTS_ONLY){
00674                 memcpy(obuf+c,ppts,5);
00675                 c += 5;
00676         } else if ( ptsdts == PTS_DTS ){
00677                 memcpy(obuf+c,ppts,5);
00678                 c += 5;
00679                 memcpy(obuf+c,pdts,5);
00680                 c += 5;
00681         }
00682 
00683         memset(obuf+c,0xFF,stuffing);
00684         c += stuffing;
00685 
00686         return c;
00687 }
00688 
00689 void write_padding_pes( int pack_size, int extcnt, 
00690                         uint64_t SCR, uint64_t muxr, uint8_t *buf)
00691 {
00692         int pos = 0;
00693 
00694         pos = write_ps_header(buf,SCR,muxr, extcnt, 0, 0, 1, 1, 1,
00695                               0);
00696 
00697         pos += write_pes_header( PADDING_STREAM, pack_size-pos, 0, 0, buf+pos,
00698                                  0, 0);
00699 
00700 }
00701 
00702 int write_video_pes( int pack_size, int extcnt, uint64_t vpts, 
00703                      uint64_t vdts, uint64_t SCR, uint64_t muxr, 
00704                      uint8_t *buf, int *vlength, 
00705                      uint8_t ptsdts, ringbuffer *vrbuffer)
00706 {
00707         int add;
00708         int pos = 0;
00709         int p   = 0;
00710         int stuff = 0;
00711         int length = *vlength;
00712 
00713         if (! length) return 0;
00714         p = PS_HEADER_L1+PES_H_MIN;
00715 
00716         if ( ptsdts == PTS_ONLY){
00717                 p += 5;
00718         } else if (ptsdts == PTS_DTS){
00719                 p += 10;
00720         }
00721 
00722         if ( length+p >= pack_size){
00723                 length = pack_size;
00724         } else {
00725                 if (pack_size - length - p <= PES_MIN){
00726                         stuff = pack_size - length-p;
00727                         length = pack_size;
00728                 } else 
00729                         length = length+p;
00730         }
00731 
00732         pos = write_ps_header(buf,SCR,muxr, extcnt, 0, 0, 1, 1, 
00733                               1, 0);
00734 
00735         pos += write_pes_header( 0xE0, length-pos, vpts, vdts, buf+pos, 
00736                                  stuff, ptsdts);
00737         if (length-pos > *vlength){
00738                 LOG(VB_GENERAL, LOG_ERR, "WHAT THE HELL  %d > %d", length-pos,
00739                         *vlength);
00740         }
00741 
00742         add = ring_read( vrbuffer, buf+pos, length-pos);
00743         *vlength = add;
00744         if (add < 0) return -1;
00745         pos += add;
00746 
00747         if (pos+PES_MIN < pack_size){
00748                 pos += write_pes_header( PADDING_STREAM, pack_size-pos, 0, 0,
00749                                          buf+pos, 0, 0);
00750                 pos = pack_size;
00751         }               
00752         return pos;
00753 }
00754 
00755 int write_audio_pes(  int pack_size, int extcnt, int n, uint64_t pts, 
00756                       uint64_t SCR, uint32_t muxr, uint8_t *buf, int *alength, 
00757                       uint8_t ptsdts,   ringbuffer *arbuffer)
00758 {
00759         int add;
00760         int pos = 0;
00761         int p   = 0;
00762         int stuff = 0;
00763         int length = *alength;
00764 
00765         if (!length) return 0;
00766         p = PS_HEADER_L1+PES_H_MIN;
00767 
00768         if (ptsdts == PTS_ONLY){
00769                 p += 5;
00770         }
00771 
00772         if ( length+p >= pack_size){
00773                 length = pack_size;
00774         } else {
00775                 if (pack_size-length-p <= PES_MIN){
00776                         stuff = pack_size - length-p;
00777                         length = pack_size;
00778                 } else 
00779                         length = length+p;
00780         }
00781         pos = write_ps_header(buf,SCR,muxr, extcnt, 0, 0, 1, 1, 
00782                               1, 0);
00783         pos += write_pes_header( 0xC0+n, length-pos, pts, 0, buf+pos, stuff, 
00784                                  ptsdts);
00785         add = ring_read( arbuffer, buf+pos, length-pos);
00786         *alength = add;
00787         if (add < 0) return -1;
00788         pos += add;
00789 
00790         if (pos+PES_MIN < pack_size){
00791                 pos += write_pes_header( PADDING_STREAM, pack_size-pos, 0,0,
00792                                          buf+pos, 0, 0);
00793                 pos = pack_size;
00794         }               
00795         if (pos != pack_size) {
00796                 LOG(VB_GENERAL, LOG_ERR, "apos: %d", pos);
00797                 exit(1);
00798         }
00799 
00800         return pos;
00801 }
00802 
00803 int write_ac3_pes(  int pack_size, int extcnt, int n,
00804                     uint64_t pts, uint64_t SCR, 
00805                     uint32_t muxr, uint8_t *buf, int *alength, uint8_t ptsdts,
00806                     int nframes,int ac3_off, ringbuffer *ac3rbuffer)
00807 {
00808         int add;
00809         int pos = 0;
00810         int p   = 0;
00811         int stuff = 0;
00812         int length = *alength;
00813 
00814         if (!length) return 0;
00815         p = PS_HEADER_L1+PES_H_MIN+4;
00816 
00817         if (ptsdts == PTS_ONLY){
00818                 p += 5;
00819         }
00820 
00821         if ( length+p >= pack_size){
00822                 length = pack_size;
00823         } else {
00824                 if (pack_size-length-p <= PES_MIN){
00825                         stuff = pack_size - length-p;
00826                         length = pack_size;
00827                 } else 
00828                         length = length+p;
00829         }
00830         pos = write_ps_header(buf,SCR,muxr, extcnt, 0, 0, 1, 1, 
00831                               1, 0);
00832 
00833         pos += write_pes_header( PRIVATE_STREAM1, length-pos, pts, 0, 
00834                                  buf+pos, stuff, ptsdts);
00835         buf[pos] = 0x80 + n;
00836         buf[pos+1] = nframes;
00837         buf[pos+2] = (ac3_off >> 8)& 0xFF;
00838         buf[pos+3] = (ac3_off)& 0xFF;
00839         pos += 4;
00840 
00841         add = ring_read( ac3rbuffer, buf+pos, length-pos);
00842         *alength = add;
00843         if (add < 0) return -1;
00844         pos += add;
00845 
00846         if (pos+PES_MIN < pack_size){
00847                 pos += write_pes_header( PADDING_STREAM, pack_size-pos, 0,0,
00848                                          buf+pos, 0, 0);
00849                 pos = pack_size;
00850         }               
00851         if (pos != pack_size) {
00852                 LOG(VB_GENERAL, LOG_ERR, "apos: %d", pos);
00853                 exit(1);
00854         }
00855 
00856         return pos;
00857 }
00858 
00859 int write_nav_pack(int pack_size, int extcnt, uint64_t SCR, uint32_t muxr, 
00860                    uint8_t *buf)
00861 {
00862         int pos = 0;
00863         uint8_t headr[5] = {0x00, 0x00, 0x01, PRIVATE_STREAM2, 0x03 };
00864         (void)pack_size;
00865 
00866         pos = write_ps_header( buf, SCR, muxr, extcnt, 0, 0, 1, 1, 1, 1);
00867         memcpy(buf+pos, headr, 5);
00868         buf[pos+5] = 0xD4;
00869         pos += 6;
00870         memset(buf+pos, 0, 0x03d4);
00871         pos += 0x03d4;
00872 
00873         memcpy(buf+pos, headr, 5);
00874         buf[pos+5] = 0xFA;
00875         pos += 6;
00876         memset(buf+pos, 0, 0x03fA);
00877         pos += 0x03fA;
00878         
00879         return pos;
00880 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends