Example #1
0
void
avi_reader_c::create_video_packetizer() {
  size_t i;

  mxverb_tid(4, m_ti.m_fname, 0, "frame sizes:\n");

  for (i = 0; i < m_max_video_frames; i++) {
    m_bytes_to_process += AVI_frame_size(m_avi, i);
    mxverb(4, boost::format("  %1%: %2%\n") % i % AVI_frame_size(m_avi, i));
  }

  if (m_avi->bitmap_info_header) {
    m_ti.m_private_data = memory_c::clone(m_avi->bitmap_info_header, get_uint32_le(&m_avi->bitmap_info_header->bi_size));

    mxverb(4, boost::format("track extra data size: %1%\n") % (m_ti.m_private_data->get_size() - sizeof(alBITMAPINFOHEADER)));

    if (sizeof(alBITMAPINFOHEADER) < m_ti.m_private_data->get_size())
      mxverb(4, boost::format("  %1%\n") % to_hex(m_ti.m_private_data->get_buffer() + sizeof(alBITMAPINFOHEADER), m_ti.m_private_data->get_size() - sizeof(alBITMAPINFOHEADER)));
  }

  const char *codec = AVI_video_compressor(m_avi);
  if (mpeg4::p2::is_v3_fourcc(codec))
    m_divx_type = DIVX_TYPE_V3;
  else if (mpeg4::p2::is_fourcc(codec))
    m_divx_type = DIVX_TYPE_MPEG4;

  if (map_has_key(m_ti.m_default_durations, 0))
    m_fps = 1000000000.0 / m_ti.m_default_durations[0];

  else if (map_has_key(m_ti.m_default_durations, -1))
    m_fps = 1000000000.0 / m_ti.m_default_durations[-1];

  m_ti.m_id = 0;                 // ID for the video track.
  if (DIVX_TYPE_MPEG4 == m_divx_type)
    create_mpeg4_p2_packetizer();

  else if (mpeg4::p10::is_avc_fourcc(codec) && !hack_engaged(ENGAGE_ALLOW_AVC_IN_VFW_MODE))
    create_mpeg4_p10_packetizer();

  else if (mpeg1_2::is_fourcc(get_uint32_le(codec)))
    create_mpeg1_2_packetizer();

  else if (FOURCC('V', 'P', '8', '0') == get_uint32_be(codec))
    create_vp8_packetizer();

  else
    create_standard_video_packetizer();
}
Example #2
0
/*
 * Class:     com_mcxiaoke_ndk_Native
 * Method:    init
 * Signature: (J)J
 */
JNIEXPORT jlong JNICALL Java_com_mcxiaoke_ndk_Native_init
(JNIEnv *env, jclass clazz, jlong avi)
{
    Instance* instance = 0;

    long frameSize = AVI_frame_size((avi_t*) avi, 0);
    if (0 >= frameSize)
    {
        ThrowException(env, "java/lang/RuntimeException",
                       "Unable to get the frame size.");
        goto exit;
    }

    instance = new Instance();
    if (0 == instance)
    {
        ThrowException(env, "java/lang/RuntimeException",
                       "Unable to allocate instance.");
        goto exit;
    }

    instance->buffer = (char*) malloc(frameSize);
    if (0 == instance->buffer)
    {
        ThrowException(env, "java/lang/RuntimeException",
                       "Unable to allocate buffer.");
        delete instance;
        instance = 0;
    }

exit:
    return (jlong) instance;
}
Example #3
0
void
avi_reader_c::extended_identify_mpeg4_l2(std::vector<std::string> &extended_info) {
  int size = AVI_frame_size(m_avi, 0);
  if (0 >= size)
    return;

  memory_cptr af_buffer = memory_c::alloc(size);
  unsigned char *buffer = af_buffer->get_buffer();
  int dummy_key;

  AVI_read_frame(m_avi, reinterpret_cast<char *>(buffer), &dummy_key);

  uint32_t par_num, par_den;
  if (mpeg4::p2::extract_par(buffer, size, par_num, par_den)) {
    int width          = AVI_video_width(m_avi);
    int height         = AVI_video_height(m_avi);
    float aspect_ratio = static_cast<float>(width) * par_num / height / par_den;

    int disp_width, disp_height;
    if (aspect_ratio > (static_cast<float>(width) / height)) {
      disp_width  = irnd(height * aspect_ratio);
      disp_height = height;

    } else {
      disp_width  = width;
      disp_height = irnd(width / aspect_ratio);
    }

    extended_info.push_back((boost::format("display_dimensions:%1%x%2%") % disp_width % disp_height).str());
  }
}
Example #4
0
void
avi_reader_c::set_avc_nal_size_size(mpeg4_p10_es_video_packetizer_c *ptzr) {
  m_avc_nal_size_size = ptzr->get_nalu_size_length();

  for (size_t i = 0; i < m_max_video_frames; ++i) {
    int size = AVI_frame_size(m_avi, i);
    if (0 == size)
      continue;

    memory_cptr buffer = memory_c::alloc(size);

    AVI_set_video_position(m_avi, i);
    int key = 0;
    size    = AVI_read_frame(m_avi, reinterpret_cast<char *>(buffer->get_buffer()), &key);

    if (   (4 <= size)
        && (   (get_uint32_be(buffer->get_buffer()) == NALU_START_CODE)
            || (get_uint24_be(buffer->get_buffer()) == NALU_START_CODE)))
      m_avc_nal_size_size = -1;

    break;
  }

  AVI_set_video_position(m_avi, 0);
}
Example #5
0
void
avi_reader_c::extended_identify_mpeg4_l2(mtx::id::info_c &info) {
  int size = AVI_frame_size(m_avi, 0);
  if (0 >= size)
    return;

  memory_cptr af_buffer = memory_c::alloc(size);
  unsigned char *buffer = af_buffer->get_buffer();
  int dummy_key;

  AVI_read_frame(m_avi, reinterpret_cast<char *>(buffer), &dummy_key);

  uint32_t par_num, par_den;
  if (mpeg4::p2::extract_par(buffer, size, par_num, par_den)) {
    auto aspect_ratio = static_cast<double>(m_video_width) * par_num / m_video_height / par_den;

    int disp_width, disp_height;
    if (aspect_ratio > (static_cast<double>(m_video_width) / m_video_height)) {
      disp_width  = std::llround(m_video_height * aspect_ratio);
      disp_height = m_video_height;

    } else {
      disp_width  = m_video_width;
      disp_height = std::llround(m_video_width / aspect_ratio);
    }

    info.add(mtx::id::display_dimensions, boost::format("%1%x%2%") % disp_width % disp_height);
  }
}
Example #6
0
void
avi_reader_c::debug_dump_video_index() {
  int num_video_frames = AVI_video_frames(m_avi), i;

  mxinfo(boost::format("AVI video index dump: %1% entries; frame rate: %2%\n") % num_video_frames % m_fps);
  for (i = 0; num_video_frames > i; ++i)
    mxinfo(boost::format("  %1%: %2% bytes\n") % i % AVI_frame_size(m_avi, i));
}
Example #7
0
void
avi_reader_c::create_mpeg1_2_packetizer() {
  std::shared_ptr<M2VParser> m2v_parser(new M2VParser);

  m2v_parser->SetProbeMode();
  if (m_ti.m_private_data && (m_ti.m_private_data->get_size() < sizeof(alBITMAPINFOHEADER)))
    m2v_parser->WriteData(m_ti.m_private_data->get_buffer() + sizeof(alBITMAPINFOHEADER), m_ti.m_private_data->get_size() - sizeof(alBITMAPINFOHEADER));

  unsigned int frame_number = 0;
  unsigned int state        = m2v_parser->GetState();
  while ((frame_number < std::min(m_max_video_frames, 100u)) && (MPV_PARSER_STATE_FRAME != state)) {
    ++frame_number;

    int size = AVI_frame_size(m_avi, frame_number - 1);
    if (0 == size)
      continue;

    AVI_set_video_position(m_avi, frame_number - 1);

    memory_cptr buffer = memory_c::alloc(size);
    int key      = 0;
    int num_read = AVI_read_frame(m_avi, reinterpret_cast<char *>(buffer->get_buffer()), &key);

    if (0 >= num_read)
      continue;

    m2v_parser->WriteData(buffer->get_buffer(), num_read);

    state = m2v_parser->GetState();
  }

  AVI_set_video_position(m_avi, 0);

  if (MPV_PARSER_STATE_FRAME != state)
    mxerror_tid(m_ti.m_fname, 0, Y("Could not extract the sequence header from this MPEG-1/2 track.\n"));

  MPEG2SequenceHeader seq_hdr = m2v_parser->GetSequenceHeader();
  std::shared_ptr<MPEGFrame> frame(m2v_parser->ReadFrame());
  if (!frame)
    mxerror_tid(m_ti.m_fname, 0, Y("Could not extract the sequence header from this MPEG-1/2 track.\n"));

  int display_width      = ((0 >= seq_hdr.aspectRatio) || (1 == seq_hdr.aspectRatio)) ? seq_hdr.width : static_cast<int>(seq_hdr.height * seq_hdr.aspectRatio);

  MPEGChunk *raw_seq_hdr = m2v_parser->GetRealSequenceHeader();
  if (raw_seq_hdr)
    m_ti.m_private_data  = memory_c::clone(raw_seq_hdr->GetPointer(), raw_seq_hdr->GetSize());
  else
    m_ti.m_private_data.reset();

  m_vptzr                = add_packetizer(new mpeg1_2_video_packetizer_c(this, m_ti, m2v_parser->GetMPEGVersion(), seq_hdr.frameOrFieldRate,
                                                                         seq_hdr.width, seq_hdr.height, display_width, seq_hdr.height, false));

  show_packetizer_info(0, PTZR(m_vptzr));
}
Example #8
0
void
avi_reader_c::debug_dump_video_index() {
  int num_video_frames = AVI_video_frames(m_avi), i;

  mxinfo(boost::format("AVI video index dump: %1% entries; frame rate: %2%\n") % num_video_frames % m_fps);
  for (i = 0; num_video_frames > i; ++i) {
    int key = 0;
    AVI_read_frame(m_avi, nullptr, &key);
    mxinfo(boost::format("  %1%: %2% bytes; key: %3%\n") % i % AVI_frame_size(m_avi, i) % key);
  }

  AVI_set_video_position(m_avi, 0);
}
Example #9
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;
}