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

📄 h264.cpp

📁 完整的RTP RTSP代码库
💻 CPP
📖 第 1 页 / 共 2 页
字号:
	dec->delta_pic_order_cnt[1] = h264_se(&bs);      }      break;    }  } catch (...) {    return -1;  }  return 0;}static void h264_compute_poc( h264_decode_t *dec ) {  const int max_frame_num = 1 << (dec->log2_max_frame_num_minus4 + 4);  int field_poc[2] = {0,0};  enum {    H264_PICTURE_FRAME,    H264_PICTURE_FIELD_TOP,    H264_PICTURE_FIELD_BOTTOM,  } pic_type;  /* FIXME FIXME it doesn't handle the case where there is a MMCO == 5   * (MMCO 5 "emulates" an idr) */    /* picture type */  if (dec->frame_mbs_only_flag || !dec->field_pic_flag)    pic_type = H264_PICTURE_FRAME;  else if (dec->bottom_field_flag)    pic_type = H264_PICTURE_FIELD_BOTTOM;  else    pic_type = H264_PICTURE_FIELD_TOP;  /* frame_num_offset */  if (dec->nal_unit_type == H264_NAL_TYPE_IDR_SLICE) {    dec->pic_order_cnt_lsb_prev = 0;    dec->pic_order_cnt_msb_prev = 0;    dec->frame_num_offset = 0;  } else {    if (dec->frame_num < dec->frame_num_prev)      dec->frame_num_offset = dec->frame_num_offset_prev + max_frame_num;    else      dec->frame_num_offset = dec->frame_num_offset_prev;  }  /* */  if(dec->pic_order_cnt_type == 0) {    const unsigned int max_poc_lsb = 1 << (dec->log2_max_pic_order_cnt_lsb_minus4 + 4);    if (dec->pic_order_cnt_lsb < dec->pic_order_cnt_lsb_prev &&        dec->pic_order_cnt_lsb_prev - dec->pic_order_cnt_lsb >= max_poc_lsb / 2)      dec->pic_order_cnt_msb = dec->pic_order_cnt_msb_prev + max_poc_lsb;    else if (dec->pic_order_cnt_lsb > dec->pic_order_cnt_lsb_prev &&             dec->pic_order_cnt_lsb - dec->pic_order_cnt_lsb_prev > max_poc_lsb / 2)      dec->pic_order_cnt_msb = dec->pic_order_cnt_msb_prev - max_poc_lsb;    else      dec->pic_order_cnt_msb = dec->pic_order_cnt_msb_prev;    field_poc[0] = dec->pic_order_cnt_msb + dec->pic_order_cnt_lsb;    field_poc[1] = field_poc[0];    if (pic_type == H264_PICTURE_FRAME)      field_poc[1] += dec->delta_pic_order_cnt_bottom;  } else if (dec->pic_order_cnt_type == 1) {    int abs_frame_num, expected_delta_per_poc_cycle, expected_poc;    if (dec->pic_order_cnt_cycle_length != 0)      abs_frame_num = dec->frame_num_offset + dec->frame_num;    else      abs_frame_num = 0;    if (dec->nal_ref_idc == 0 && abs_frame_num > 0)      abs_frame_num--;    expected_delta_per_poc_cycle = 0;    for (int i = 0; i < (int)dec->pic_order_cnt_cycle_length; i++ )      expected_delta_per_poc_cycle += dec->offset_for_ref_frame[i];    if (abs_frame_num > 0) {      const int poc_cycle_cnt = ( abs_frame_num - 1 ) / dec->pic_order_cnt_cycle_length;      const int frame_num_in_poc_cycle = ( abs_frame_num - 1 ) % dec->pic_order_cnt_cycle_length;      expected_poc = poc_cycle_cnt * expected_delta_per_poc_cycle;      for (int i = 0; i <= frame_num_in_poc_cycle; i++)        expected_poc += dec->offset_for_ref_frame[i];    } else {      expected_poc = 0;    }    if (dec->nal_ref_idc == 0)      expected_poc += dec->offset_for_non_ref_pic;    field_poc[0] = expected_poc + dec->delta_pic_order_cnt[0];    field_poc[1] = field_poc[0] + dec->offset_for_top_to_bottom_field;    if (pic_type == H264_PICTURE_FRAME)      field_poc[1] += dec->delta_pic_order_cnt[1];  } else if (dec->pic_order_cnt_type == 2) {    int poc;    if (dec->nal_unit_type == H264_NAL_TYPE_IDR_SLICE) {      poc = 0;    } else {      const int abs_frame_num = dec->frame_num_offset + dec->frame_num;      if (dec->nal_ref_idc != 0)        poc = 2 * abs_frame_num;      else        poc = 2 * abs_frame_num - 1;    }    field_poc[0] = poc;    field_poc[1] = poc;  }  /* */  if (pic_type == H264_PICTURE_FRAME)    dec->pic_order_cnt = MIN(field_poc[0], field_poc[1] );  else if (pic_type == H264_PICTURE_FIELD_TOP)    dec->pic_order_cnt = field_poc[0];  else    dec->pic_order_cnt = field_poc[1];}extern "C" int h264_detect_boundary (const uint8_t *buffer, 				     uint32_t buflen, 				     h264_decode_t *decode){  uint8_t temp;  h264_decode_t new_decode;  int ret;  int slice = 0;  memcpy(&new_decode, decode, sizeof(new_decode));  temp = new_decode.nal_unit_type = h264_nal_unit_type(buffer);  new_decode.nal_ref_idc = h264_nal_ref_idc(buffer);  ret = 0;  switch (temp) {  case H264_NAL_TYPE_ACCESS_UNIT:  case H264_NAL_TYPE_END_OF_SEQ:  case H264_NAL_TYPE_END_OF_STREAM:#ifdef BOUND_VERBOSE    printf("nal type %d\n", temp);#endif    ret = 1;    break;  case H264_NAL_TYPE_NON_IDR_SLICE:  case H264_NAL_TYPE_DP_A_SLICE:  case H264_NAL_TYPE_DP_B_SLICE:  case H264_NAL_TYPE_DP_C_SLICE:  case H264_NAL_TYPE_IDR_SLICE:    slice = 1;    // slice buffer - read the info into the new_decode, and compare.    if (h264_read_slice_info(buffer, buflen, &new_decode) < 0) {      // need more memory      return -1;    }    if (decode->nal_unit_type > H264_NAL_TYPE_IDR_SLICE || 	decode->nal_unit_type < H264_NAL_TYPE_NON_IDR_SLICE) {      break;    }    if (decode->frame_num != new_decode.frame_num) {#ifdef BOUND_VERBOSE      printf("frame num values different %u %u\n", decode->frame_num, 	     new_decode.frame_num);#endif      ret = 1;      break;    }    if (decode->field_pic_flag != new_decode.field_pic_flag) {      ret = 1;#ifdef BOUND_VERBOSE      printf("field pic values different\n");#endif      break;    }    if (decode->nal_ref_idc != new_decode.nal_ref_idc &&	(decode->nal_ref_idc == 0 ||	 new_decode.nal_ref_idc == 0)) {#ifdef BOUND_VERBOSE      printf("nal ref idc values differ\n");#endif      ret = 1;      break;    }    if (decode->frame_num == new_decode.frame_num &&	decode->pic_order_cnt_type == new_decode.pic_order_cnt_type) {      if (decode->pic_order_cnt_type == 0) {	if (decode->pic_order_cnt_lsb != new_decode.pic_order_cnt_lsb) {#ifdef BOUND_VERBOSE	  printf("pic order 1\n");#endif	  ret = 1;	  break;	}	if (decode->delta_pic_order_cnt_bottom != new_decode.delta_pic_order_cnt_bottom) {	  ret = 1;#ifdef BOUND_VERBOSE	  printf("delta pic order cnt bottom 1\n");#endif	  break;	}      } else if (decode->pic_order_cnt_type == 1) {	if (decode->delta_pic_order_cnt[0] != new_decode.delta_pic_order_cnt[0]) {	  ret =1;#ifdef BOUND_VERBOSE	  printf("delta pic order cnt [0]\n");#endif	  break;	}	if (decode->delta_pic_order_cnt[1] != new_decode.delta_pic_order_cnt[1]) {	  ret = 1;#ifdef BOUND_VERBOSE	  printf("delta pic order cnt [1]\n");#endif	  break;	  	}      }    }    if (decode->nal_unit_type == H264_NAL_TYPE_IDR_SLICE &&	new_decode.nal_unit_type == H264_NAL_TYPE_IDR_SLICE) {      if (decode->idr_pic_id != new_decode.idr_pic_id) {#ifdef BOUND_VERBOSE	printf("idr_pic id\n");#endif		ret = 1;	break;      }    }    break;  case H264_NAL_TYPE_SEQ_PARAM:    if (h264_read_seq_info(buffer, buflen, &new_decode) < 0) {      return -1;    }    // fall through  default:    if (decode->nal_unit_type <= H264_NAL_TYPE_IDR_SLICE) ret = 1;    else ret = 0;  }   /* save _prev values */  if (ret)  {    new_decode.frame_num_offset_prev = decode->frame_num_offset;    if (decode->pic_order_cnt_type != 2 || decode->nal_ref_idc != 0)      new_decode.frame_num_prev = decode->frame_num;    if (decode->nal_ref_idc != 0)    {      new_decode.pic_order_cnt_lsb_prev = decode->pic_order_cnt_lsb;      new_decode.pic_order_cnt_msb_prev = decode->pic_order_cnt_msb;    }  }  if( slice ) {  // XXX we compute poc for every slice in a picture (but it's not needed)    h264_compute_poc( &new_decode );  }  // other types (6, 7, 8, #ifdef BOUND_VERBOSE  if (ret == 0) {    printf("no change\n");  }#endif  memcpy(decode, &new_decode, sizeof(*decode));  return ret;}uint32_t h264_read_sei_value (const uint8_t *buffer, uint32_t *size) {  uint32_t ret = 0;  *size = 1;  while (buffer[*size] == 0xff) {    ret += 255;    *size = *size + 1;  }  ret += *buffer;  return ret;}extern "C" const char *h264_get_slice_name (const uint8_t slice_type){  if (H264_TYPE_IS_P(slice_type)) return "P";    if (H264_TYPE_IS_B(slice_type)) return "B";    if (H264_TYPE_IS_I(slice_type)) return "I";  if (H264_TYPE_IS_SI(slice_type)) return "SI";  if (H264_TYPE_IS_SP(slice_type)) return "SP";  return "UNK";}extern "C" bool h264_access_unit_is_sync (const uint8_t *pNal, uint32_t len){  uint8_t nal_type;  h264_decode_t dec;  uint32_t offset;  do {    nal_type = h264_nal_unit_type(pNal);    if (nal_type == H264_NAL_TYPE_SEQ_PARAM) return true;    if (nal_type == H264_NAL_TYPE_PIC_PARAM) return true;    if (nal_type == H264_NAL_TYPE_IDR_SLICE) return true;    if (h264_nal_unit_type_is_slice(nal_type)) {      if (h264_read_slice_info(pNal, len, &dec) < 0) return false;      if (H264_TYPE_IS_I(dec.slice_type) ||	  H264_TYPE_IS_SI(dec.slice_type)) return true;      return false;    }    offset = h264_find_next_start_code(pNal, len);    if (offset == 0 || offset > len) return false;    pNal += offset;    len -= offset;  } while (len > 0);  return false;}extern "C" char *h264_get_profile_level_string (const uint8_t profile, 						const uint8_t level){  const char *pro;  char profileb[20], levelb[20];  if (profile == 66) {    pro = "Baseline";  } else if (profile == 77) {    pro = "Main";  } else if (profile == 88) {    pro =  "Extended";  } else if (profile == 100) {    pro = "High";  } else if (profile == 110) {    pro =  "High 10";  } else if (profile == 122) {    pro = "High 4:2:2";  } else if (profile == 144) {    pro = "High 4:4:4";  } else {    snprintf(profileb, sizeof(profileb), "Unknown Profile %x", profile);    pro = profileb;  }   switch (level) {  case 10: case 20: case 30: case 40: case 50:    snprintf(levelb, sizeof(levelb), "%u", level / 10);    break;  case 11: case 12: case 13:  case 21: case 22:  case 31: case 32:  case 41: case 42:  case 51:    snprintf(levelb, sizeof(levelb), "%u.%u", level / 10, level % 10);    break;  default:    snprintf(levelb, sizeof(levelb), "unknown level %x", level);    break;  }  uint len =    1 + strlen("H.264 @") + strlen(pro) + strlen(levelb);  char *typebuffer =     (char *)malloc(len);  if (typebuffer == NULL) return NULL;  snprintf(typebuffer, len,  "H.264 %s@%s", pro, levelb);  return typebuffer;}

⌨️ 快捷键说明

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