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

📄 main.cpp

📁 完整的RTP RTSP代码库
💻 CPP
📖 第 1 页 / 共 3 页
字号:
static uint32_t remove_03 (uint8_t *bptr, uint32_t len){  uint32_t nal_len = 0;  while (nal_len + 2 < len) {    if (bptr[0] == 0 && bptr[1] == 0 && bptr[2] == 3) {      bptr += 2;      nal_len += 2;      len--;      memmove(bptr, bptr + 1, len - nal_len);    } else {      bptr++;      nal_len++;    }  }  return len;}static const char *nal[] = {  "Coded slice of non-IDR picture", // 1  "Coded slice data partition A",   // 2  "Coded slice data partition B",   // 3  "Coded slice data partition C",   // 4  "Coded slice of an IDR picture",  // 5  "SEI",                            // 6  "Sequence parameter set",         // 7  "Picture parameter set",          // 8  "Access unit delimeter",          // 9  "End of Sequence",                // 10  "end of stream",                  // 11  "filler data",                    // 12  "Sequence parameter set extension", // 13};static const char *nal_unit_type (uint8_t type){  if (type == 0 || type >= 24) {    return "unspecified";  }  if (type < 14) {    return nal[type - 1];  }  return "reserved";}const char *slice_type[] = {  "P",   "B",   "I",   "SP",   "SI",   "P",   "B",   "I",  "SP",  "SI",};void h264_slice_header (h264_decode_t *dec, CBitstream *bs){  uint32_t temp;  printf("   first_mb_in_slice: %u\n", h264_ue(bs));  temp = h264_ue(bs);  printf("   slice_type: %u (%s)\n", temp, temp < 10 ? slice_type[temp] : "invalid");  printf("   pic_parameter_set_id: %u\n", h264_ue(bs));  dec->frame_num = bs->GetBits(dec->log2_max_frame_num_minus4 + 4);  printf("   frame_num: %u (%u bits)\n", 	 dec->frame_num, 	 dec->log2_max_frame_num_minus4 + 4);  // these are defaults  dec->field_pic_flag = 0;  dec->bottom_field_flag = 0;  dec->delta_pic_order_cnt[0] = 0;  dec->delta_pic_order_cnt[1] = 0;  if (!dec->frame_mbs_only_flag) {    dec->field_pic_flag = bs->GetBits(1);    printf("   field_pic_flag: %u\n", dec->field_pic_flag);    if (dec->field_pic_flag) {      dec->bottom_field_flag = bs->GetBits(1);      printf("    bottom_field_flag: %u\n", dec->bottom_field_flag);    }  }  if (dec->nal_unit_type == H264_NAL_TYPE_IDR_SLICE) {    dec->idr_pic_id = h264_ue(bs);    printf("   idr_pic_id: %u\n", dec->idr_pic_id);  }  switch (dec->pic_order_cnt_type) {  case 0:    dec->pic_order_cnt_lsb = bs->GetBits(dec->log2_max_pic_order_cnt_lsb_minus4 + 4);    printf("   pic_order_cnt_lsb: %u\n", dec->pic_order_cnt_lsb);    if (dec->pic_order_present_flag && !dec->field_pic_flag) {      dec->delta_pic_order_cnt_bottom = h264_se(bs);      printf("   delta_pic_order_cnt_bottom: %d\n", 	     dec->delta_pic_order_cnt_bottom);    }    break;  case 1:    if (!dec->delta_pic_order_always_zero_flag) {      dec->delta_pic_order_cnt[0] = h264_se(bs);      printf("   delta_pic_order_cnt[0]: %d\n", 	     dec->delta_pic_order_cnt[0]);    }    if (dec->pic_order_present_flag && !dec->field_pic_flag) {      dec->delta_pic_order_cnt[1] = h264_se(bs);      printf("   delta_pic_order_cnt[1]: %d\n", 	     dec->delta_pic_order_cnt[1]);    }    break;  }  }    void h264_slice_layer_without_partitioning (h264_decode_t *dec, 					    CBitstream *bs){  h264_slice_header(dec, bs);}uint8_t h264_parse_nal (h264_decode_t *dec, CBitstream *bs){  uint8_t type = 0;  try {    if (bs->GetBits(24) == 0) bs->GetBits(8);    h264_check_0s(bs, 1);    dec->nal_ref_idc = bs->GetBits(2);    dec->nal_unit_type = type = bs->GetBits(5);    printf(" ref %u type %u %s\n", dec->nal_ref_idc, type, nal_unit_type(type));    switch (type) {    case H264_NAL_TYPE_NON_IDR_SLICE:    case H264_NAL_TYPE_IDR_SLICE:      h264_slice_layer_without_partitioning(dec, bs);      break;    case H264_NAL_TYPE_SEQ_PARAM:      h264_parse_sequence_parameter_set(dec, bs);      break;    case H264_NAL_TYPE_PIC_PARAM:      h264_parse_pic_parameter_set(dec, bs);      break;    case H264_NAL_TYPE_SEI:      h264_parse_sei(dec, bs);      break;    case H264_NAL_TYPE_ACCESS_UNIT:      printf("   primary_pic_type: %u\n", bs->GetBits(3));      break;    case H264_NAL_TYPE_SEQ_EXTENSION:      h264_parse_seq_ext(dec, bs);      break;    }  } catch (BitstreamErr_t err) {    printf("\nERROR reading bitstream %s\n\n", err == BITSTREAM_PAST_END ?	   "read past NAL end" : "too many bits requested");  }  return type;}  // false if different picture, true if nal is the same picturebool compare_boundary (h264_decode_t *prev, h264_decode_t *on){  if (prev->frame_num != on->frame_num) {    return false;  }  if (prev->field_pic_flag != on->field_pic_flag) {    return false;  }  if (prev->nal_ref_idc != on->nal_ref_idc &&      (prev->nal_ref_idc == 0 ||       on->nal_ref_idc == 0)) {    return false;  }    if (prev->frame_num == on->frame_num &&      prev->pic_order_cnt_type == on->pic_order_cnt_type) {    if (prev->pic_order_cnt_type == 0) {      if (prev->pic_order_cnt_lsb != on->pic_order_cnt_lsb) {	return false;      }      if (prev->delta_pic_order_cnt_bottom != on->delta_pic_order_cnt_bottom) {	return false;      }    } else if (prev->pic_order_cnt_type == 1) {      if (prev->delta_pic_order_cnt[0] != on->delta_pic_order_cnt[0]) {	return false;      }      if (prev->delta_pic_order_cnt[1] != on->delta_pic_order_cnt[1]) {	return false;      }    }  }  if (prev->nal_unit_type == H264_NAL_TYPE_IDR_SLICE &&      on->nal_unit_type == H264_NAL_TYPE_IDR_SLICE) {    if (prev->idr_pic_id != on->idr_pic_id) {      return false;    }  }  return true;  }int main (int argc, char **argv){#define MAX_BUFFER (65536 * 4)  const char* usageString =     "[-version] <file-name>\n";  const char *ProgName = argv[0];  while (true) {    int c = -1;    int option_index = 0;    static struct option long_options[] = {      { "version", 0, 0, 'v' },      { NULL, 0, 0, 0 }    };    c = getopt_long_only(argc, argv, "v",			 long_options, &option_index);    if (c == -1)      break;    switch (c) {    case '?':      fprintf(stderr, "usage: %s %s", ProgName, usageString);      exit(0);    case 'v':      fprintf(stderr, "%s - %s version %s\n", 	      ProgName, MPEG4IP_PACKAGE, MPEG4IP_VERSION);      exit(0);    default:      fprintf(stderr, "%s: unknown option specified, ignoring: %c\n", 	      ProgName, c);    }  }  /* check that we have at least one non-option argument */  if ((argc - optind) < 1) {    fprintf(stderr, "usage: %s %s", ProgName, usageString);    exit(1);  }  uint8_t buffer[MAX_BUFFER];  uint32_t buffer_on, buffer_size;  uint64_t bytes = 0;  FILE *m_file;  h264_decode_t dec, prevdec;  bool have_prevdec = false;  memset(&dec, 0, sizeof(dec));#if 0  uint8_t count = 0;  // this prints out the 8-bit to # of zero bit array that we use  // to decode ue(v)  for (uint32_t ix = 0; ix <= 255; ix++) {    uint8_t ij;    uint8_t bit = 0x80;    for (ij = 0;	 (bit & ix) == 0 && ij < 8; 	 ij++, bit >>= 1);    printf("%d, ", ij);    count++;    if (count > 16) {      printf("\n");      count = 0;    }  }  printf("\n");#endif  fprintf(stdout, "%s - %s version %s\n", 	  ProgName, MPEG4IP_PACKAGE, MPEG4IP_VERSION);  m_file = fopen(argv[optind], FOPEN_READ_BINARY);  if (m_file == NULL) {    fprintf(stderr, "file %s not found\n", *argv);    exit(-1);  }  buffer_on = buffer_size = 0;  while (!feof(m_file)) {    bytes += buffer_on;    if (buffer_on != 0) {      buffer_on = buffer_size - buffer_on;      memmove(buffer, &buffer[buffer_size - buffer_on], buffer_on);    }    buffer_size = fread(buffer + buffer_on, 			1, 			MAX_BUFFER - buffer_on, 			m_file);    buffer_size += buffer_on;    buffer_on = 0;    bool done = false;    CBitstream ourbs;    do {      uint32_t ret;      ret = h264_find_next_start_code(buffer + buffer_on, 				      buffer_size - buffer_on);      if (ret == 0) {	done = true;	if (buffer_on == 0) {	  fprintf(stderr, "couldn't find start code in buffer from 0\n");	  exit(-1);	}      } else {	// have a complete NAL from buffer_on to end	if (ret > 3) {	  uint32_t nal_len;	  nal_len = remove_03(buffer + buffer_on, ret);#if 0	  printf("Nal length %u start code %u bytes "U64"\n", nal_len, 		 buffer[buffer_on + 2] == 1 ? 3 : 4, bytes + buffer_on);#else	  printf("Nal length %u start code %u bytes \n", nal_len, 		 buffer[buffer_on + 2] == 1 ? 3 : 4);#endif	  ourbs.init(buffer + buffer_on, nal_len * 8);	  uint8_t type;	  type = h264_parse_nal(&dec, &ourbs);	  if (type >= 1 && type <= 5) {	    if (have_prevdec) {	      // compare the 2	      bool bound;	      bound = compare_boundary(&prevdec, &dec);	      printf("Nal is %s\n", bound ? "part of last picture" : "new picture");	    }	    memcpy(&prevdec, &dec, sizeof(dec));	    have_prevdec = true;	  } else if (type >= 9 && type <= 11) {	    have_prevdec = false; // don't need to check	  }	}#if 0	printf("buffer on "X64" "X64" %u len %u %02x %02x %02x %02x\n",	       bytes + buffer_on, 	       bytes + buffer_on + ret,	       buffer_on, 	       ret,	       buffer[buffer_on],	       buffer[buffer_on+1],	       buffer[buffer_on+2],	       buffer[buffer_on+3]);#endif	buffer_on += ret; // buffer_on points to next code      }    } while (done == false);  }  fclose(m_file);  return 0;}

⌨️ 快捷键说明

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