示例#1
0
bool
xtr_hevc_c::write_nal(binary const *data,
                      size_t &pos,
                      size_t data_size,
                      size_t write_nal_size_size) {
  if (write_nal_size_size > data_size)
    return false;

  auto nal_size  = get_uint_be(&data[pos], write_nal_size_size);
  pos           += write_nal_size_size;

  if ((pos + nal_size) > data_size) {
    mxwarn(boost::format(Y("Track %1%: NAL too big. Size according to header field: %2%, available bytes in packet: %3%. This NAL is defect and will be skipped.\n")) % m_tid % nal_size % (data_size - pos));
    return false;
  }

  auto nal_unit_type   = (data[pos] >> 1) & 0x3f;
  auto start_code_size = m_first_nalu || (HEVC_NALU_TYPE_VIDEO_PARAM == nal_unit_type) || (HEVC_NALU_TYPE_SEQ_PARAM == nal_unit_type) || (HEVC_NALU_TYPE_PIC_PARAM == nal_unit_type) ? 4 : 3;
  m_first_nalu         = false;

  m_out->write(ms_start_code + (4 - start_code_size), start_code_size);
  m_out->write(data + pos, nal_size);

  pos += nal_size;

  return true;
}
示例#2
0
void
mpeg4_p10_video_packetizer_c::change_nalu_size_len(packet_cptr packet) {
  unsigned char *src = packet->data->get_buffer();
  int size           = packet->data->get_size();

  if (!src || !size)
    return;

  std::vector<int> nalu_sizes;

  int src_pos = 0;

  // Find all NALU sizes in this packet.
  while (src_pos < size) {
    if ((size - src_pos) < m_nalu_size_len_src)
      break;

    int nalu_size = get_uint_be(&src[src_pos], m_nalu_size_len_src);
    nalu_size     = std::min<int>(nalu_size, size - src_pos - m_nalu_size_len_src);

    if (nalu_size > m_max_nalu_size)
      mxerror_tid(m_ti.m_fname, m_ti.m_id, boost::format(Y("The chosen NALU size length of %1% is too small. Try using '4'.\n")) % m_nalu_size_len_dst);

    src_pos += m_nalu_size_len_src + nalu_size;

    nalu_sizes.push_back(nalu_size);
  }

  // Allocate memory if the new NALU size length is greater
  // than the previous one. Otherwise reuse the existing memory.
  if (m_nalu_size_len_dst > m_nalu_size_len_src) {
    int new_size = size + nalu_sizes.size() * (m_nalu_size_len_dst - m_nalu_size_len_src);
    packet->data = memory_cptr(new memory_c((unsigned char *)safemalloc(new_size), new_size, true));
  }

  // Copy the NALUs and write the new sized length field.
  unsigned char *dst = packet->data->get_buffer();
  src_pos            = 0;
  int dst_pos        = 0;

  size_t i;
  for (i = 0; nalu_sizes.size() > i; ++i) {
    int nalu_size = nalu_sizes[i];

    put_uint_be(&dst[dst_pos], nalu_size, m_nalu_size_len_dst);

    memmove(&dst[dst_pos + m_nalu_size_len_dst], &src[src_pos + m_nalu_size_len_src], nalu_size);

    src_pos += m_nalu_size_len_src + nalu_size;
    dst_pos += m_nalu_size_len_dst + nalu_size;
  }

  packet->data->set_size(dst_pos);
}
示例#3
0
void
mpeg4_p10_video_packetizer_c::remove_filler_nalus(memory_c &data)
  const {
  auto ptr        = data.get_buffer();
  auto total_size = data.get_size();
  auto idx        = 0u;

  while ((idx + m_nalu_size_len_dst) < total_size) {
    auto nalu_size = get_uint_be(&ptr[idx], m_nalu_size_len_dst) + m_nalu_size_len_dst;

    if ((idx + nalu_size) > total_size)
      break;

    if (ptr[idx + m_nalu_size_len_dst] == NALU_TYPE_FILLER_DATA) {
      memmove(&ptr[idx], &ptr[idx + nalu_size], total_size - idx - nalu_size);
      total_size -= nalu_size;
      continue;
    }

    idx += nalu_size;
  }

  data.resize(total_size);
}
示例#4
0
file_status_e
avi_reader_c::read_video() {
  if (m_video_frames_read >= m_max_video_frames)
    return flush_packetizer(m_vptzr);

  memory_cptr chunk;
  int key                   = 0;
  int old_video_frames_read = m_video_frames_read;

  int size, num_read;

  int dropped_frames_here   = 0;

  do {
    size  = AVI_frame_size(m_avi, m_video_frames_read);
    chunk = memory_c::alloc(size);
    num_read = AVI_read_frame(m_avi, reinterpret_cast<char *>(chunk->get_buffer()), &key);

    ++m_video_frames_read;

    if (0 > num_read) {
      // Error reading the frame: abort
      m_video_frames_read = m_max_video_frames;
      return flush_packetizer(m_vptzr);

    } else if (0 == num_read)
      ++dropped_frames_here;

  } while ((0 == num_read) && (m_video_frames_read < m_max_video_frames));

  if (0 == num_read)
    // This is only the case if the AVI contains dropped frames only.
    return flush_packetizer(m_vptzr);

  size_t i;
  for (i = m_video_frames_read; i < m_max_video_frames; ++i) {
    if (0 != AVI_frame_size(m_avi, i))
      break;

    int dummy_key;
    AVI_read_frame(m_avi, nullptr, &dummy_key);
    ++dropped_frames_here;
    ++m_video_frames_read;
  }

  int64_t timestamp       = static_cast<int64_t>(static_cast<int64_t>(old_video_frames_read)   * 1000000000ll / m_fps);
  int64_t duration        = static_cast<int64_t>(static_cast<int64_t>(dropped_frames_here + 1) * 1000000000ll / m_fps);

  m_dropped_video_frames += dropped_frames_here;

  // AVC with framed packets (without NALU start codes but with length fields)
  // or non-AVC video track?
  if (0 >= m_avc_nal_size_size)
    PTZR(m_vptzr)->process(new packet_t(chunk, timestamp, duration, key ? VFT_IFRAME : VFT_PFRAMEAUTOMATIC, VFT_NOBFRAME));

  else {
    // AVC video track without NALU start codes. Re-frame with NALU start codes.
    int offset = 0;

    while ((offset + m_avc_nal_size_size) < num_read) {
      int nalu_size  = get_uint_be(chunk->get_buffer() + offset, m_avc_nal_size_size);
      offset        += m_avc_nal_size_size;

      if ((offset + nalu_size) > num_read)
        break;

      memory_cptr nalu = memory_c::alloc(4 + nalu_size);
      put_uint32_be(nalu->get_buffer(), NALU_START_CODE);
      memcpy(nalu->get_buffer() + 4, chunk->get_buffer() + offset, nalu_size);
      offset += nalu_size;

      PTZR(m_vptzr)->process(new packet_t(nalu, timestamp, duration, key ? VFT_IFRAME : VFT_PFRAMEAUTOMATIC, VFT_NOBFRAME));
    }
  }

  m_bytes_processed += num_read;

  return m_video_frames_read >= m_max_video_frames ? flush_packetizer(m_vptzr) :  FILE_STATUS_MOREDATA;
}