⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mpeg2t_video.c

📁 完整的RTP RTSP代码库
💻 C
📖 第 1 页 / 共 2 页
字号:
	       es_pid->work_state);#endif      }    } else {      /*       * All other work states - load the current byte into the       * buffer - reallocate buffer if needed       */      if (es_pid->work_loaded >= es_pid->work_max_size - 5) {	uint8_t *frameptr;	es_pid->work_max_size += 1024;	frameptr = 	  (uint8_t *)realloc(es_pid->work,			     sizeof(mpeg2t_frame_t) + 			     es_pid->work_max_size);	if (frameptr == NULL) {	  es_pid->work = NULL;	  es_pid->work_state = 0;	  es_pid->header = 0;	  buflen--;	  esptr++;	  break;	} else {	  es_pid->work = (mpeg2t_frame_t *)frameptr;	  frameptr += sizeof(mpeg2t_frame_t);	  es_pid->work->frame = frameptr;	}      }	      es_pid->work->frame[es_pid->work_loaded] = *esptr;      es_pid->work_loaded++;      if (have_header != 0) {	if (h264_nal_unit_type_is_slice(nal_value)) {	  if ((es_pid->work->flags & HAVE_PICT_HEADER) == 0) {	    es_pid->work->pict_header_offset = es_pid->work_loaded - 4;	    es_pid->work->flags |= HAVE_PICT_HEADER;	  }	} else {	  switch (nal_value) {	  case H264_NAL_TYPE_ACCESS_UNIT:	    es_pid->work->frame[es_pid->work_loaded - 1] = 0;	    framesfinished = 1;	    if (es_pid->info_loaded == 0) {	      // look to fill in es_pid information such as frame rate, etc	      if ((es_pid->work->flags & HAVE_SEQ_HEADER) == HAVE_SEQ_HEADER) {		h264_decode_t dec;		memset(&dec, 0, sizeof(dec));		if (h264_read_seq_info(es_pid->work->frame + es_pid->work->seq_header_offset,				       es_pid->work_loaded - es_pid->work->seq_header_offset,				       &dec) == 0) {		  es_pid->info_loaded = 1;		  es_pid->h = dec.pic_height;		  es_pid->w = dec.pic_width;		  mpeg2t_message(LOG_DEBUG, "h264 read seq header - %ux%u",				 es_pid->w, es_pid->h);		  // don't have timing info yet.		  //es_pid->bitrate = bitrate;		  //es_pid->frame_rate = frame_rate;		  //es_pid->tick_per_frame = (uint32_t)(90000.0 / frame_rate);		  //es_pid->mpeg_layer = have_mpeg2 ? 2 : 1;		}	      }	    }	    // store the frame type so we can figure out the timestamps	    // we don't know how the pts and dts will work, so assume we'll	    // have the values.#if 0	    es_pid->work->frame_type = 	      MP4AV_Mpeg3PictHdrType(es_pid->work->frame + 				     es_pid->pict_header_offset);#endif	    // xxx hack for temporary	    es_pid->work->frame_type = 1;	    //printf("hi %d\n", es_pid->work->frame_type);	    mpeg2t_message(LOG_DEBUG, "finished work %d", es_pid->work_loaded);	    // -4 might have to be -5 in the case of zero byte	    mpeg2t_finished_es_work(es_pid, es_pid->work_loaded - 4);	    es_pid->have_seq_header = 0;	    mpeg2t_malloc_es_work(es_pid, es_pid->work_max_size);	    if (es_pid->work != NULL) {	      // Put the header we just found at the start of the frame,	      // then set the work state accordingly.	      es_pid->work->frame[0] = 0;	      es_pid->work->frame[1] = 0;	      es_pid->work->frame[2] = 1;	      es_pid->work->frame[3] = *esptr;	      es_pid->work_loaded = 4;	      es_pid->work->flags = 0;	      es_pid->work_state = 2;	    } else {	      es_pid->work_state = 0;	      es_pid->header = 0;	      return framesfinished;	    }	    break;	  case H264_NAL_TYPE_SEQ_PARAM:	    es_pid->work->seq_header_offset = es_pid->work_loaded - 4;	    es_pid->work->flags |= HAVE_SEQ_HEADER;	    es_pid->have_seq_header = 1;	    break;	  case H264_NAL_TYPE_PIC_PARAM:	    es_pid->work->nal_pic_param_offset = es_pid->work_loaded - 4;	    es_pid->work->flags |= HAVE_PIC_PARAM_HEADER;	    break;	  	  }	}      }    }    esptr++;    buflen--;  }  return framesfinished;}int mpeg2t_mpeg4_video_info (mpeg2t_es_t *es_pid, char *buffer, size_t len){  int offset;  if (es_pid->info_loaded == 0) return -1;  offset = snprintf(buffer, len, "Mpeg-4 Video, %d x %d",		    es_pid->w, es_pid->h);  return 0;}int process_mpeg2t_mpeg4_video (mpeg2t_es_t *es_pid, 				const uint8_t *esptr, 				uint32_t buflen){  bool have_header = false;  uint8_t header_value = 0;  int framesfinished = 0;#if 0  mpeg2t_message(LOG_DEBUG, "enter mpeg4 process");  if (es_pid->peshdr_loaded != 0 && ((es_pid->stream_id & 0xf0) != 0xe0)) {    mpeg2t_message(LOG_ERR, "Video stream PID %x with bad stream_id %x", 		   es_pid->pid.pid,		   es_pid->stream_id);    return 0;  }#endif  // note - one thing that we're not handling correctly is the  // extra 0 byte before the access header.  That's okay for now, but  // may run into problems later.  while (buflen > 0) {    es_pid->header <<= 8;    es_pid->header |= *esptr;    have_header = false;    if ((es_pid->header & 0xffffff00) == 0x00000100) {      have_header = true;      header_value = es_pid->header;      mpeg2t_message(LOG_DEBUG, "header %x %x %d", es_pid->header, 		     header_value,		     es_pid->work_state);    }    switch (es_pid->work_state) {    case 0:      if (have_header == false) break;      /*       * Work state 0 - looking for any header       */      // have a header.      if (es_pid->work_max_size < 4096) es_pid->work_max_size = 4096;      // always do this in state 0 to get the psts at the start      mpeg2t_malloc_es_work(es_pid, es_pid->work_max_size);      if (es_pid->work == NULL) return framesfinished;            // Store header      es_pid->work->flags = 0;      es_pid->work->frame[0] = 0;      es_pid->work->frame[1] = 0;      es_pid->work->frame[2] = 1;      es_pid->work_loaded = 3;      es_pid->work_state = 1; // looking for VOP#if 1      mpeg2t_message(LOG_DEBUG, "video - state 0 header %x state %d", es_pid->header, 		     es_pid->work_state);#endif      // fall into:    case 1:    case 2:      /*       * Work state 1 - looking for VOP       */      if (es_pid->work_loaded >= es_pid->work_max_size - 5) {	uint8_t *frameptr;	es_pid->work_max_size += 1024;	frameptr = 	  (uint8_t *)realloc(es_pid->work,			     sizeof(mpeg2t_frame_t) + 			     es_pid->work_max_size);	if (frameptr == NULL) {	  es_pid->work = NULL;	  es_pid->work_state = 0;	  es_pid->header = 0;	  buflen--;	  esptr++;	  break;	} else {	  es_pid->work = (mpeg2t_frame_t *)frameptr;	  frameptr += sizeof(mpeg2t_frame_t);	  es_pid->work->frame = frameptr;	}      }	      es_pid->work->frame[es_pid->work_loaded] = *esptr;      es_pid->work_loaded++;      if (have_header) {	if (es_pid->work_state == 2) {	  // we're finished with this frame	  es_pid->work->frame_type = 1;	  //printf("hi %d\n", es_pid->work->frame_type);	  mpeg2t_message(LOG_DEBUG, "finished work %d", es_pid->work_loaded);	  // -4 might have to be -5 in the case of zero byte	  mpeg2t_finished_es_work(es_pid, es_pid->work_loaded - 4);	  es_pid->have_seq_header = 0;	  mpeg2t_malloc_es_work(es_pid, es_pid->work_max_size);	  if (es_pid->work != NULL) {	    // Put the header we just found at the start of the frame,	    // then set the work state accordingly.	    es_pid->work->frame[0] = 0;	    es_pid->work->frame[1] = 0;	    es_pid->work->frame[2] = 1;	    es_pid->work->frame[3] = *esptr;	    es_pid->work_loaded = 4;	    es_pid->work->flags = 0;	    es_pid->work_state = 1;	  } else {	    es_pid->work_state = 0;	    es_pid->header = 0;	    return framesfinished;	  }	} 	// now, figure out what state to do based on header	if (header_value == MP4AV_MPEG4_VOP_START){ 	  // now, we're reading until the next header	  es_pid->work_state = 2;	  if (es_pid->info_loaded == 0) {	    // read the VOL	    if ((es_pid->work->flags & HAVE_SEQ_HEADER) == HAVE_SEQ_HEADER) {	      u_int8_t TimeBits;	      u_int16_t TimeTicks;	      u_int16_t FrameDuration;	      u_int16_t FrameWidth;	      u_int16_t FrameHeight;	      	      if (MP4AV_Mpeg4ParseVol(es_pid->work->frame + es_pid->work->seq_header_offset,				      es_pid->work_loaded - es_pid->work->seq_header_offset,				      &TimeBits, 				      &TimeTicks, 				      &FrameDuration, 				      &FrameWidth,				      &FrameHeight, 				      NULL, 				      NULL, 				      NULL)) { 		es_pid->info_loaded = 1;		es_pid->h = FrameHeight;		es_pid->w = FrameWidth;		mpeg2t_message(LOG_DEBUG, "parsed mpeg4 vol");	      }	    }	  } 	} else {	  // we only really care about VOL headers	  if (header_value >= MP4AV_MPEG4_VOL_START &&		header_value < MP4AV_MPEG4_VOL_START + 0xf) {	      // have VOL	      es_pid->work->seq_header_offset = es_pid->work_loaded - 4;	      es_pid->work->flags |= HAVE_SEQ_HEADER;	      mpeg2t_message(LOG_DEBUG, "have mpeg4 vol");	    }	}      }      break;    }    esptr++;    buflen--;  }  return framesfinished;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -