mpeg2_transport.c
上传用户:sun1608
上传日期:2007-02-02
资源大小:6116k
文件大小:17k
源码类别:

流媒体/Mpeg4/MP4

开发平台:

Visual C++

  1. #include "mpeg4ip.h"
  2. #include "mpeg2_transport.h"
  3. #include <assert.h>
  4. #include "mpeg2t_private.h"
  5. #define DEBUG 1
  6. #ifdef DEBUG
  7. #define CHECK_MP2T_HEADER assert(*pHdr == MPEG2T_SYNC_BYTE)
  8. #else
  9. #define CHECK_MP2T_HEADER 
  10. #endif
  11. uint32_t mpeg2t_find_sync_byte (const uint8_t *buffer, uint32_t buflen)
  12. {
  13.   uint32_t offset;
  14.   offset = 0;
  15.   while (offset < buflen) {
  16.     if (buffer[offset] == MPEG2T_SYNC_BYTE) {
  17.       return (offset);
  18.     }
  19.     offset++;
  20.   }
  21.   return (offset);
  22. }
  23. uint32_t mpeg2t_transport_error_indicator (const uint8_t *pHdr)
  24. {
  25.   CHECK_MP2T_HEADER;
  26.   return ((pHdr[1] >> 7) & 0x1);
  27. }
  28. uint32_t mpeg2t_payload_unit_start_indicator (const uint8_t *pHdr)
  29. {
  30.   CHECK_MP2T_HEADER;
  31.   return ((pHdr[1] >> 6) & 0x1);
  32. }
  33. uint16_t mpeg2t_pid (const uint8_t *pHdr)
  34. {
  35.   int pid;
  36.   CHECK_MP2T_HEADER;
  37.   pid = (pHdr[1] & 0x1f) << 8;
  38.   pid |= pHdr[2];
  39.   return (pid);
  40. }
  41. uint32_t mpeg2t_adaptation_control (const uint8_t *pHdr)
  42. {
  43.   CHECK_MP2T_HEADER;
  44.   return ((pHdr[3] >> 4) & 0x3);
  45. }
  46. uint32_t mpeg2t_continuity_counter (const uint8_t *pHdr)
  47. {
  48.   CHECK_MP2T_HEADER;
  49.   return (pHdr[3] & 0xf);
  50. }
  51. const uint8_t *mpeg2t_transport_payload_start (const uint8_t *pHdr,
  52.      uint32_t *payload_len)
  53. {
  54.   uint32_t adaption_control;
  55.   CHECK_MP2T_HEADER;
  56.   if (mpeg2t_transport_error_indicator(pHdr) != 0) {
  57.     *payload_len = 0;
  58.     return NULL;
  59.   }
  60.   adaption_control = mpeg2t_adaptation_control(pHdr);
  61.   if (adaption_control == 1) {
  62.     *payload_len = 184;
  63.     return pHdr + 4;
  64.   }
  65.   if (adaption_control == 3) {
  66.     if (pHdr[4] > 183) {
  67.       *payload_len = 0;
  68.       return NULL;
  69.     }
  70.     *payload_len = 183 - pHdr[4];
  71.     return pHdr + 5 + pHdr[4];
  72.   }
  73.   *payload_len = 0;
  74.   return NULL;
  75. }
  76. static void mpeg2t_start_join_pak (mpeg2t_pid_t *pidptr,
  77.    const uint8_t *bufstart,
  78.    uint32_t buflen,
  79.    uint32_t seqlen, 
  80.    uint32_t cc)
  81. {
  82.   if (seqlen == 0) {
  83.     if (pidptr->data_len_max < buflen) {
  84.       pidptr->data = (uint8_t *)realloc(pidptr->data, buflen + 4096);
  85.       if (pidptr->data == NULL) {
  86. pidptr->data_len_max = 0;
  87. return;
  88.       }
  89.       pidptr->data_len_max = buflen + 4096;
  90.     }
  91.   } else if (seqlen > pidptr->data_len_max) {
  92.     pidptr->data = (uint8_t *)realloc(pidptr->data, seqlen);
  93.     if (pidptr->data == NULL) {
  94.       pidptr->data_len_max = 0;
  95.       return;
  96.     }
  97.     pidptr->data_len_max = seqlen;
  98.   }
  99.   pidptr->data_len = seqlen;
  100.   pidptr->data_len_loaded = buflen;
  101.   memcpy(pidptr->data, bufstart, buflen);
  102.   pidptr->lastcc = cc;
  103. }
  104. static int mpeg2t_join_pak (mpeg2t_pid_t *pidptr,
  105.     const uint8_t *bufstart,
  106.     uint32_t buflen,
  107.     uint32_t cc)
  108. {
  109.   uint32_t nextcc;
  110.   uint32_t remaining;
  111.   if (pidptr->data_len_loaded == 0) {
  112.     mpeg2t_message(LOG_WARNING, 
  113.    "Trying to add to unstarted packet - PID %x", 
  114.    pidptr->pid);
  115.     return -1;
  116.   }
  117.   nextcc = (pidptr->lastcc + 1) & 0xf;
  118.   if (nextcc != cc) {
  119.     mpeg2t_message(LOG_ERR, "Illegal cc value %d - should be %d - PID %x", 
  120.    cc, nextcc, pidptr->pid);
  121.     pidptr->data_len_loaded = 0;
  122.     return -1;
  123.   }
  124.   pidptr->lastcc = cc;
  125.   if (pidptr->data_len == 0) {
  126.     remaining = pidptr->data_len_max - pidptr->data_len_loaded;
  127.     if (remaining < buflen) {
  128.       pidptr->data = (uint8_t *)realloc(pidptr->data, 
  129. pidptr->data_len_max + 4096);
  130.       if (pidptr->data == NULL) {
  131. pidptr->data_len_max = 0;
  132. return -1;
  133.       }
  134.       pidptr->data_len_max = pidptr->data_len_max + 4096;
  135.     }
  136.   } else {
  137.     remaining = pidptr->data_len - pidptr->data_len_loaded;
  138.     buflen = buflen > remaining ? remaining : buflen;
  139.   }
  140.   memcpy(pidptr->data + pidptr->data_len_loaded,
  141.  bufstart, 
  142.  buflen);
  143.   pidptr->data_len_loaded += buflen;
  144.   if (pidptr->data_len == 0 || pidptr->data_len_loaded < pidptr->data_len) 
  145.     return 0;
  146.   // Indicate that next one starts from beginning
  147.   pidptr->data_len_loaded = 0;
  148.   return 1;
  149. }
  150. static mpeg2t_pid_t *mpeg2t_lookup_pid (mpeg2t_t *ptr,
  151. uint16_t pid)
  152. {
  153.   mpeg2t_pid_t *pidptr = &ptr->pas.pid;
  154.   while (pidptr != NULL && pidptr->pid != pid) {
  155.     pidptr = pidptr->next_pid;
  156.   }
  157.   return pidptr;
  158. }
  159. static void add_to_pidQ (mpeg2t_t *ptr, mpeg2t_pid_t *pidptr)
  160. {
  161.   mpeg2t_pid_t *p = &ptr->pas.pid;
  162.   while (p->next_pid != NULL) {
  163.     p = p->next_pid;
  164.   }
  165.   p->next_pid = pidptr;
  166. }
  167. static void create_pmap (mpeg2t_t *ptr, uint16_t prog_num, uint16_t pid)
  168. {
  169.   mpeg2t_pmap_t *pmap;
  170.   mpeg2t_message(LOG_INFO, "Adding pmap prog_num %x pid %x", prog_num, pid);
  171.   pmap = MALLOC_STRUCTURE(mpeg2t_pmap_t);
  172.   if (pmap == NULL) return;
  173.   memset(pmap, 0, sizeof(*pmap));
  174.   pmap->pid.pak_type = MPEG2T_PROG_MAP_PAK;
  175.   pmap->pid.pid = pid;
  176.   pmap->program_number = prog_num;
  177.   add_to_pidQ(ptr, &pmap->pid);
  178. }
  179. static void create_es (mpeg2t_t *ptr, 
  180.        uint16_t pid, 
  181.        uint8_t stream_type,
  182.        const uint8_t *es_data,
  183.        uint32_t es_info_len)
  184. {
  185.   mpeg2t_es_t *es;
  186.   mpeg2t_message(LOG_INFO, 
  187.  "Adding ES PID %x stream type %d", pid, stream_type);
  188.   es = MALLOC_STRUCTURE(mpeg2t_es_t);
  189.   if (es == NULL) return;
  190.   memset(es, 0, sizeof(*es));
  191.   es->pid.pak_type = MPEG2T_ES_PAK;
  192.   es->pid.pid = pid;
  193.   es->stream_type = stream_type;
  194.   if (es_info_len != 0) {
  195.     es->es_data = (uint8_t *)malloc(es_info_len);
  196.     if (es->es_data != NULL) {
  197.       memcpy(es->es_data, es_data, es_info_len);
  198.       es->es_info_len = es_info_len;
  199.     }
  200.   }
  201.   es->work_max_size = 4096;
  202.   add_to_pidQ(ptr, &es->pid);
  203. }
  204.   
  205. static int mpeg2t_process_pas (mpeg2t_t *ptr, const uint8_t *buffer)
  206. {
  207.   uint32_t buflen;
  208.   uint32_t section_len;
  209.   uint32_t len;
  210.   const uint8_t *mapptr;
  211.   uint16_t prog_num, pid;
  212.   const uint8_t *pasptr;
  213.   int ret;
  214.   buflen = 188;
  215.   // process pas pointer
  216.   pasptr = mpeg2t_transport_payload_start(buffer, &buflen);
  217.   if (pasptr == NULL) return 0;
  218.   if (mpeg2t_payload_unit_start_indicator(buffer) == 0) {
  219.     ret = mpeg2t_join_pak(&ptr->pas.pid, 
  220.   pasptr,
  221.   buflen,
  222.   mpeg2t_continuity_counter(buffer));
  223.     if (ret <= 0) return 0; // not done, or bad
  224.     pasptr = ptr->pas.pid.data;
  225.     section_len = ptr->pas.pid.data_len;
  226.   } else {
  227.     if (*pasptr + 1 > buflen) 
  228.       return 0;
  229.     buflen -= *pasptr + 1;
  230.     pasptr += *pasptr + 1; // go through the pointer field
  231.     
  232.     if (*pasptr != 0 || (pasptr[1] & 0xc0) != 0x80) {
  233.       mpeg2t_message(LOG_ERR, "PAS field not 0");
  234.       return 0;
  235.     }
  236.     section_len = ((pasptr[1] << 8) | pasptr[2]) & 0x3ff; 
  237.     // remove table_id, section length fields
  238.     pasptr += 3;
  239.     buflen -= 3;
  240.     if (buflen < section_len) {
  241.       mpeg2t_start_join_pak(&ptr->pas.pid,
  242.     pasptr, // start after section len
  243.     buflen,
  244.     section_len,
  245.     mpeg2t_continuity_counter(buffer));
  246.       return 0;
  247.     }
  248.     // At this point, pasptr points to transport_stream_id
  249.   }
  250.   
  251.   ptr->pas.transport_stream_id = ((pasptr[0] << 8 | pasptr[1]));
  252.   ptr->pas.version_number = (pasptr[2] >> 1) & 0x1f;
  253.   mapptr = &pasptr[5];
  254.   section_len -= 5 + 4; // remove CRC and stuff before map list
  255.   for (len = 0; len < section_len; len += 4, mapptr += 4) {
  256.     prog_num = (mapptr[0] << 8) | mapptr[1];
  257.     if (prog_num != 0) {
  258.       pid = ((mapptr[2] << 8) | mapptr[3]) & 0x1fff;
  259.       if (mpeg2t_lookup_pid(ptr, pid) == NULL) {
  260. create_pmap(ptr, prog_num, pid);
  261.       }
  262.     }
  263.   }
  264.   return 1;
  265. }
  266. static int mpeg2t_process_pmap (mpeg2t_t *ptr, 
  267. mpeg2t_pid_t *ifptr,
  268. const uint8_t *buffer)
  269. {
  270.   uint32_t buflen;
  271.   uint32_t section_len;
  272.   uint32_t len, es_len;
  273.   uint16_t prog_num, pcr_pid;
  274.   const uint8_t *pmapptr;
  275.   mpeg2t_pmap_t *pmap_pid = (mpeg2t_pmap_t *)ifptr;
  276.   int ret;
  277.   uint8_t stream_type;
  278.   uint16_t e_pid;
  279.   buflen = 188;
  280.   // process pas pointer
  281.   pmapptr = mpeg2t_transport_payload_start(buffer, &buflen);
  282.   if (pmapptr == NULL) return 0;
  283.   if (mpeg2t_payload_unit_start_indicator(buffer) == 0) {
  284.     ret = mpeg2t_join_pak(ifptr, 
  285.   pmapptr,
  286.   buflen,
  287.   mpeg2t_continuity_counter(buffer));
  288.     if (ret <= 0) return 0;
  289.     pmapptr = ifptr->data;
  290.     section_len = ifptr->data_len;
  291.   } else {
  292.     if (*pmapptr + 1 > buflen) 
  293.       return 0;
  294.     buflen -= *pmapptr + 1;
  295.     pmapptr += *pmapptr + 1; // go through the pointer field
  296.     if (*pmapptr != 2 || (pmapptr[1] & 0xc0) != 0x80) {
  297.       mpeg2t_message(LOG_ERR, "PMAP start field not 2");
  298.       return 0;
  299.     }
  300.     section_len = ((pmapptr[1] << 8) | pmapptr[2]) & 0x3ff; 
  301.     pmapptr += 3;
  302.     buflen -= 3;
  303.     if (buflen < section_len) {
  304.       mpeg2t_start_join_pak(ifptr,
  305.     pmapptr,
  306.     buflen,
  307.     section_len,
  308.     mpeg2t_continuity_counter(buffer));
  309.       return 0;
  310.     }
  311.     // pmapptr points to program number
  312.   }
  313.     
  314.   prog_num = ((pmapptr[0] << 8) | pmapptr[1]);
  315.   if (prog_num != pmap_pid->program_number) {
  316.     mpeg2t_message(LOG_ERR, 
  317.    "Prog Map error - program number doesn't match - pid %x orig %x from pak %x", 
  318.    pmap_pid->pid.pid, pmap_pid->program_number, prog_num);
  319.     return 0;
  320.   }
  321.   pmap_pid->version_number = (pmapptr[2] >> 1) & 0x1f;
  322.   pcr_pid = ((pmapptr[5] << 8) | pmapptr[6]) & 0x1fff;
  323.   if (pcr_pid != 0x1fff) {
  324.     mpeg2t_message(LOG_DEBUG, "Have PCR pid of %x", pcr_pid);
  325.   }
  326.   pmapptr += 7;
  327.   section_len -= 7; // remove all the fixed fields to get the prog info len
  328.   len = ((pmapptr[0] << 8) | pmapptr[1]) & 0xfff;
  329.   pmapptr += 2;
  330.   section_len -= 2;
  331.   if (len != 0) {
  332.     if (len > section_len) return 0;
  333.     if (len == pmap_pid->prog_info_len) {
  334.       // same length - do a compare
  335.     } else {
  336.     }
  337.     pmapptr += len;
  338.     section_len -= len;
  339.   }
  340.   section_len -= 4; // remove CRC
  341.   len = 0;
  342.   while (len < section_len) {
  343.     stream_type = pmapptr[0];
  344.     e_pid = ((pmapptr[1] << 8) | pmapptr[2]) & 0x1fff;
  345.     es_len = ((pmapptr[3] << 8) | pmapptr[4]) & 0xfff;
  346.     if (es_len + len > section_len) return 0;
  347.     if (mpeg2t_lookup_pid(ptr, e_pid) == NULL) {
  348.       mpeg2t_message(LOG_INFO, "Creating es pid %x", e_pid);
  349.       create_es(ptr, e_pid, stream_type, &pmapptr[5], es_len);
  350.     }
  351.     // create_es
  352.     len += 5 + es_len;
  353.     pmapptr += 5 + es_len;
  354.   }
  355.   return 1;
  356. }
  357. static void clean_es_data (mpeg2t_es_t *es_pid) 
  358. {
  359.   switch (es_pid->stream_type) {
  360.   case 1:
  361.   case 2:
  362.     // mpeg1 or mpeg2 video
  363.     es_pid->work_state = 0;
  364.     es_pid->header = 0;
  365.     es_pid->work_loaded = 0;
  366.     es_pid->have_seq_header = 0;
  367.     break;
  368.   case 3:
  369.   case 4:
  370.     // mpeg1/mpeg2 audio (mp3 codec
  371.     if (es_pid->work != NULL ) {
  372.       free(es_pid->work);
  373.       es_pid->work = NULL;
  374.     }
  375.     es_pid->work_loaded = 0;
  376.     es_pid->left = 0;
  377.     break;
  378.   case 0xf:
  379.     // aac
  380.     break;
  381.   }
  382. }  
  383. void mpeg2t_malloc_es_work (mpeg2t_es_t *es_pid, uint32_t frame_len)
  384. {
  385.   uint8_t *frameptr;
  386.   if (es_pid->work == NULL || es_pid->work->frame_len < frame_len) {
  387.     if (es_pid->work != NULL) {
  388.       free(es_pid->work);
  389.       es_pid->work = NULL;
  390.     }
  391.     frameptr = (uint8_t *)malloc(sizeof(mpeg2t_frame_t) + frame_len);
  392.     if (frameptr == NULL) return;
  393.     es_pid->work = (mpeg2t_frame_t *)frameptr;
  394.     es_pid->work->frame = frameptr + sizeof(mpeg2t_frame_t);
  395.     es_pid->work->frame_len = frame_len;
  396.   }
  397.   es_pid->work->next_frame = NULL;
  398.   es_pid->work->have_ps_ts = es_pid->have_ps_ts;
  399.   es_pid->work->ps_ts = es_pid->ps_ts;
  400.   es_pid->have_ps_ts = 0;
  401.   es_pid->work_loaded = 0;
  402. }
  403. void mpeg2t_finished_es_work (mpeg2t_es_t *es_pid,
  404.       uint32_t frame_len)
  405. {
  406.   mpeg2t_frame_t *p;
  407.   es_pid->work->frame_len = frame_len;
  408.   if (es_pid->list == NULL) {
  409.     es_pid->list = es_pid->work;
  410.   } else {
  411.     p = es_pid->list;
  412.     while (p->next_frame != NULL) p = p->next_frame;
  413.     p->next_frame = es_pid->work;
  414.   }
  415.   es_pid->work = NULL;
  416.   es_pid->work_loaded = 0;
  417. }
  418.   
  419. static int mpeg2t_process_es (mpeg2t_t *ptr, 
  420.       mpeg2t_pid_t *ifptr,
  421.       const uint8_t *buffer)
  422. {
  423.   uint32_t buflen;
  424.   uint32_t pes_len;
  425.   const uint8_t *esptr;
  426.   mpeg2t_es_t *es_pid = (mpeg2t_es_t *)ifptr;
  427.   int read_pes_options;
  428.   uint8_t stream_id;
  429.   uint32_t nextcc, pakcc;
  430.   int ret;
  431.   nextcc = ifptr->lastcc;
  432.   nextcc = (nextcc + 1) & 0xf;
  433.   pakcc = mpeg2t_continuity_counter(buffer);
  434.   if (nextcc != pakcc) {
  435.     mpeg2t_message(LOG_ERR, "cc error in PES %x should be %d is %d", 
  436.    ifptr->pid, nextcc, pakcc);
  437.     clean_es_data(es_pid);
  438.   }
  439.   ifptr->lastcc = pakcc;
  440.   buflen = 188;
  441.   // process pas pointer
  442.   esptr = mpeg2t_transport_payload_start(buffer, &buflen);
  443.   if (esptr == NULL) return -1;
  444.   
  445.   if (mpeg2t_payload_unit_start_indicator(buffer) != 0) {
  446.     // start of PES packet
  447.     if ((esptr[0] != 0) ||
  448. (esptr[1] != 0) ||
  449. (esptr[2] != 1)) {
  450.       mpeg2t_message(LOG_ERR, 
  451.      "Illegal start to PES packet - pid %x - %02x %02x %02x",
  452.      ifptr->pid, esptr[0], esptr[1], esptr[2]);
  453.       return -1;
  454.     }
  455.     stream_id = es_pid->stream_id = esptr[3];
  456.     pes_len = (esptr[4] << 8) | esptr[5];
  457.     esptr += 6;
  458.     buflen -= 6;
  459.     
  460.     read_pes_options = 0;
  461.     // do we have header extensions
  462.     switch ((stream_id & 0x70) >> 4) {
  463.     default:
  464.       if ((stream_id == 0xbd) ||
  465.     (stream_id >= 0xf3 && stream_id <= 0xf7) ||
  466.     (stream_id >= 0xf9 && stream_id <= 0xff)) {
  467. read_pes_options = 1;
  468. break;
  469.       }
  470.       // fall through
  471.     case 4:
  472.     case 5:
  473.     case 6:
  474.       if (esptr[2] <= buflen - 3) {
  475. // multiple PES for header
  476. read_pes_options = 1;
  477.       } else {
  478. // don't have enough to read the header
  479.       }
  480.       break;
  481.     }
  482.       
  483.     if (read_pes_options) {
  484.       if (esptr[2] + 3 > buflen) {
  485. return 0;
  486.       }
  487.       //mpeg2t_read_pes_options(es_pid, esptr);
  488.       if (((esptr[1] & 0xc0) == 0x80) ||
  489.   ((esptr[1] & 0xc0) == 0xc0)) {
  490. // read presentation timestamp
  491. uint64_t pts;
  492. #if 1
  493. mpeg2t_message(LOG_DEBUG, "Stream %x %02x %02x %02x", 
  494.        stream_id, esptr[0], esptr[1], esptr[2]);
  495. mpeg2t_message(LOG_DEBUG, "PTS %02x %02x %02x %02x %02x", 
  496.        esptr[3], esptr[4], esptr[5], esptr[6], esptr[7]);
  497. #endif
  498. if (((esptr[1] >> 6) & 0x3) !=
  499.     ((esptr[3] >> 4) & 0xf)) {
  500.   mpeg2t_message(LOG_ERR, "PID %x Timestamp flag value not same %x %x",
  501.  es_pid->pid.pid, esptr[1], esptr[2]);
  502.   return -1;
  503. }
  504. pts = ((esptr[3] >> 1) & 0x7);
  505. pts <<= 8;
  506. pts |= esptr[4];
  507. pts <<= 7;
  508. pts |= ((esptr[5] >> 1) & 0x7f);
  509. pts <<= 8;
  510. pts |= esptr[6];
  511. pts <<= 7;
  512. pts |= ((esptr[7] >> 1) & 0x7f);
  513. es_pid->have_ps_ts = 1;
  514. es_pid->ps_ts = pts;
  515.       }
  516.       buflen -= esptr[2] + 3;
  517.       esptr += esptr[2] + 3;
  518.     }
  519.   // process esptr, buflen
  520.     if (buflen == 0) {
  521.       es_pid->have_ps_ts = 0;
  522.       return 0;
  523.     }
  524.   } else {
  525.     // 0 in Payload start - process frame at start
  526.     read_pes_options = 0;
  527.   }
  528.   // have start of data is at esptr, buflen data
  529.   ret = 0;
  530.   switch (es_pid->stream_type) {
  531.   case 1:
  532.   case 2:
  533.     // mpeg1 or mpeg2 video
  534.     ret = process_mpeg2t_mpeg_video(es_pid, esptr, buflen);
  535.     break;
  536.   case 3:
  537.   case 4:
  538.     // mpeg1/mpeg2 audio (mp3 codec
  539.     ret = process_mpeg2t_mpeg_audio(es_pid, esptr, buflen);
  540.   break;
  541.   case 0xf:
  542.     // aac
  543.     break;
  544.   }
  545.   es_pid->have_ps_ts = 0;
  546.   return ret;
  547. }
  548.     
  549.       
  550. mpeg2t_pid_t *mpeg2t_process_buffer (mpeg2t_t *ptr, 
  551.      const uint8_t *buffer, 
  552.      uint32_t buflen,
  553.      uint32_t *buflen_used)
  554. {
  555.   uint32_t offset;
  556.   uint32_t remaining;
  557.   uint32_t used;
  558.   uint16_t rpid;
  559.   mpeg2t_pid_t *pidptr;
  560.   int ret;
  561.   used = 0;
  562.   remaining = buflen;
  563.   while (used < buflen) {
  564.     offset = mpeg2t_find_sync_byte(buffer, remaining);
  565.     if (offset >= remaining) {
  566.       *buflen_used = buflen;
  567.       return NULL;
  568.     }
  569.     remaining -= offset;
  570.     buffer += offset;
  571.     used += offset;
  572.     if (remaining < 188) {
  573.       *buflen_used = used;
  574.       return NULL;
  575.     }
  576.     // we have a complete buffer
  577.     rpid = mpeg2t_pid(buffer);
  578. #if 1
  579.     mpeg2t_message(LOG_DEBUG, "Buffer- PID %x start %d cc %d",
  580.    rpid, mpeg2t_payload_unit_start_indicator(buffer),
  581.    mpeg2t_continuity_counter(buffer));
  582. #endif
  583.     if (rpid == 0x1fff) {
  584.       // just skip
  585.     } else {
  586.       // look up pid in table
  587.       pidptr = mpeg2t_lookup_pid(ptr, rpid);
  588.       if (pidptr != NULL) {
  589. // okay - we've got a valid pid ptr
  590. switch (pidptr->pak_type) {
  591. case MPEG2T_PAS_PAK:
  592.   ret = mpeg2t_process_pas(ptr, buffer);
  593.   if (ret > 0) {
  594.     *buflen_used = used + 188;
  595.     return pidptr;
  596.   }
  597.   break;
  598. case MPEG2T_PROG_MAP_PAK:
  599.   ret = mpeg2t_process_pmap(ptr, pidptr, buffer);
  600.   if (ret > 0) {
  601.     *buflen_used = used + 188;
  602.     return pidptr;
  603.   }
  604.   break;
  605. case MPEG2T_ES_PAK:
  606.   if (mpeg2t_process_es(ptr, pidptr, buffer) > 0) {
  607.     *buflen_used = used + 188;
  608.     return pidptr;
  609.   }
  610.   break;
  611. }
  612.       }
  613.     }
  614.     used += 188;
  615.     buffer += 188;
  616.     remaining -= 188;
  617.   }
  618.   *buflen_used = buflen;
  619.   return NULL;
  620. }
  621.   
  622. mpeg2t_t *create_mpeg2_transport (void)
  623. {
  624.   mpeg2t_t *ptr;
  625.   ptr = MALLOC_STRUCTURE(mpeg2t_t);
  626.   memset(ptr, 0, sizeof(ptr));
  627.   ptr->pas.pid.pak_type = MPEG2T_PAS_PAK;
  628.   ptr->pas.pid.next_pid = NULL;
  629.   ptr->pas.pid.pid = 0;
  630.   ptr->pas.pid.collect_pes = 1;
  631.   return (ptr);
  632. }