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

流媒体/Mpeg4/MP4

开发平台:

Visual C++

  1. #include "mpeg4ip.h"
  2. #include "mpeg2_transport.h"
  3. #include "mpeg2t_private.h"
  4. #include "mp4av.h"
  5. #define MPEG3_SEQUENCE_START_CODE        0x000001b3
  6. #define MPEG3_PICTURE_START_CODE         0x00000100
  7. #define MPEG3_GOP_START_CODE             0x000001b8
  8. #define MPEG3_SEQUENCE_END_CODE          0x000001b7
  9. int process_mpeg2t_mpeg_video (mpeg2t_es_t *es_pid, 
  10.        const uint8_t *esptr, 
  11.        uint32_t buflen)
  12. {
  13.   int framesfinished = 0;
  14.   if ((es_pid->stream_id & 0xf0) != 0xe0) {
  15.     mpeg2t_message(LOG_ERR, "Video stream PID %x with bad stream_id %x", 
  16.    es_pid->pid.pid,
  17.    es_pid->stream_id);
  18.     return 0;
  19.   }
  20.   while (buflen > 0) {
  21.     es_pid->header <<= 8;
  22.     es_pid->header |= *esptr;
  23.     if (es_pid->work_state == 0) {
  24.       /*
  25.        * Work state 0 - looking for any header
  26.        */
  27.       if ((es_pid->header & 0xffffff00) == 0x00000100) {
  28. // have first header.
  29. if (es_pid->work == NULL) {
  30.   if (es_pid->work_max_size < 4096) es_pid->work_max_size = 4096;
  31.   mpeg2t_malloc_es_work(es_pid, es_pid->work_max_size);
  32.   if (es_pid->work == NULL) return framesfinished;
  33. }
  34. es_pid->work->frame[0] = 0;
  35. es_pid->work->frame[1] = 0;
  36. es_pid->work->frame[2] = 1;
  37. es_pid->work->frame[3] = *esptr;
  38. es_pid->work_loaded = 4;
  39. if (es_pid->header == MPEG3_PICTURE_START_CODE) {
  40.   es_pid->work_state = 2;
  41.   es_pid->pict_header_offset = 0;
  42. } else 
  43.   es_pid->work_state = 1;
  44. #if 0
  45. printf("video - state 0 header %x state %dn", es_pid->header, 
  46.        es_pid->work_state);
  47. #endif
  48.       } 
  49.       buflen--;
  50.       esptr++;
  51.     } else {
  52.       /*
  53.        * All other work states - load the current byte into the
  54.        * buffer - reallocate buffer if needed
  55.        */
  56.       if (es_pid->work_loaded >= es_pid->work_max_size - 1) {
  57. uint8_t *frameptr;
  58. es_pid->work_max_size += 1024;
  59. frameptr = 
  60.   (uint8_t *)realloc(es_pid->work,
  61.      sizeof(mpeg2t_frame_t) + 
  62.      es_pid->work_max_size);
  63. #if 0
  64. printf("Es pid work reallocing to %dn", es_pid->work_max_size);
  65. #endif
  66. if (frameptr == NULL) {
  67.   es_pid->work = NULL;
  68.   es_pid->work_state = 0;
  69.   es_pid->header = 0;
  70.   buflen--;
  71.   esptr++;
  72.   break;
  73. } else {
  74.   es_pid->work = (mpeg2t_frame_t *)frameptr;
  75.   frameptr += sizeof(mpeg2t_frame_t);
  76.   es_pid->work->frame = frameptr;
  77. }
  78.       }
  79.       es_pid->work->frame[es_pid->work_loaded] = *esptr;
  80.       es_pid->work_loaded++;
  81.       if (es_pid->work_state == 1) {
  82. /*
  83.  * Work State 1 - looking for first picture start code
  84.  */
  85. // Looking for first picture start code
  86. if (es_pid->header == MPEG3_PICTURE_START_CODE) {
  87.   es_pid->pict_header_offset = es_pid->work_loaded - 4;
  88.   es_pid->work_state = 2;
  89. #if 0
  90.   printf("Now at work state 2 - len %dn", es_pid->work_loaded);
  91. #endif
  92. }
  93.       } else {
  94. /*
  95.  * Work state 2 - have picture start code in buffer - looking for
  96.  * next picture start code
  97.  */
  98. // Might want to enhance this to stop at GOP, also
  99. if (es_pid->header == MPEG3_PICTURE_START_CODE ||
  100.     es_pid->header == MPEG3_SEQUENCE_START_CODE ||
  101.     es_pid->header == MPEG3_GOP_START_CODE ||
  102.     es_pid->header == MPEG3_SEQUENCE_END_CODE) {
  103.   framesfinished = 1;
  104.   if (es_pid->have_seq_header) {
  105.     uint32_t h, w;
  106.     double frame_rate;
  107.     if (MP4AV_Mpeg3ParseSeqHdr(es_pid->work->frame + es_pid->seq_header_offset,
  108.        es_pid->work_loaded - es_pid->seq_header_offset,
  109.        &h, 
  110.        &w, 
  111.        &frame_rate) >= 0) {
  112.       mpeg2t_message(LOG_DEBUG, "Found seq header - h %d w %d fr %g", 
  113.      h, w, frame_rate);
  114.     }
  115.   }
  116.   mpeg2t_message(LOG_CRIT, "Video seq type is %d", 
  117.  MP4AV_Mpeg3PictHdrType(es_pid->work->frame + es_pid->pict_header_offset));
  118.   mpeg2t_finished_es_work(es_pid, es_pid->work_loaded);
  119.   es_pid->have_seq_header = 0;
  120.   mpeg2t_malloc_es_work(es_pid, es_pid->work_max_size);
  121.   if (es_pid->work != NULL) {
  122.     es_pid->work->frame[0] = 0;
  123.     es_pid->work->frame[1] = 0;
  124.     es_pid->work->frame[2] = 1;
  125.     es_pid->work->frame[3] = *esptr;
  126.     es_pid->work_loaded = 4;
  127.     if (es_pid->header == MPEG3_PICTURE_START_CODE) {
  128.       es_pid->work_state = 2;
  129.       es_pid->pict_header_offset = 0;
  130.     } else {
  131.       es_pid->work_state = 1;
  132.     }
  133.   } else {
  134.     es_pid->work_state = 0;
  135.     es_pid->header = 0;
  136.     return framesfinished;
  137.   }
  138. }
  139.       }
  140.       esptr++;
  141.       buflen--;
  142.     }
  143.     // Check for sequence header here...
  144.     if (es_pid->header == MPEG3_SEQUENCE_START_CODE) {
  145.       es_pid->have_seq_header = 1;
  146.       es_pid->seq_header_offset = es_pid->work_loaded - 4;
  147.     }
  148.   }
  149.   return framesfinished;
  150. }