177496404dc182c2f4a5f86ebabffe1d1ceb81e7ejohannkoenig@chromium.org/*
277496404dc182c2f4a5f86ebabffe1d1ceb81e7ejohannkoenig@chromium.org *  Copyright (c) 2013 The WebM project authors. All Rights Reserved.
377496404dc182c2f4a5f86ebabffe1d1ceb81e7ejohannkoenig@chromium.org *
477496404dc182c2f4a5f86ebabffe1d1ceb81e7ejohannkoenig@chromium.org *  Use of this source code is governed by a BSD-style license
577496404dc182c2f4a5f86ebabffe1d1ceb81e7ejohannkoenig@chromium.org *  that can be found in the LICENSE file in the root of the source
677496404dc182c2f4a5f86ebabffe1d1ceb81e7ejohannkoenig@chromium.org *  tree. An additional intellectual property rights grant can be found
777496404dc182c2f4a5f86ebabffe1d1ceb81e7ejohannkoenig@chromium.org *  in the file PATENTS.  All contributing project authors may
877496404dc182c2f4a5f86ebabffe1d1ceb81e7ejohannkoenig@chromium.org *  be found in the AUTHORS file in the root of the source tree.
977496404dc182c2f4a5f86ebabffe1d1ceb81e7ejohannkoenig@chromium.org */
1077496404dc182c2f4a5f86ebabffe1d1ceb81e7ejohannkoenig@chromium.org
1177496404dc182c2f4a5f86ebabffe1d1ceb81e7ejohannkoenig@chromium.org#include "./webmdec.h"
1277496404dc182c2f4a5f86ebabffe1d1ceb81e7ejohannkoenig@chromium.org
1377496404dc182c2f4a5f86ebabffe1d1ceb81e7ejohannkoenig@chromium.org#include <cstring>
1477496404dc182c2f4a5f86ebabffe1d1ceb81e7ejohannkoenig@chromium.org#include <cstdio>
1577496404dc182c2f4a5f86ebabffe1d1ceb81e7ejohannkoenig@chromium.org
1677496404dc182c2f4a5f86ebabffe1d1ceb81e7ejohannkoenig@chromium.org#include "third_party/libwebm/mkvparser.hpp"
1777496404dc182c2f4a5f86ebabffe1d1ceb81e7ejohannkoenig@chromium.org#include "third_party/libwebm/mkvreader.hpp"
1877496404dc182c2f4a5f86ebabffe1d1ceb81e7ejohannkoenig@chromium.org
1977496404dc182c2f4a5f86ebabffe1d1ceb81e7ejohannkoenig@chromium.orgnamespace {
2077496404dc182c2f4a5f86ebabffe1d1ceb81e7ejohannkoenig@chromium.org
2177496404dc182c2f4a5f86ebabffe1d1ceb81e7ejohannkoenig@chromium.orgvoid reset(struct WebmInputContext *const webm_ctx) {
2277496404dc182c2f4a5f86ebabffe1d1ceb81e7ejohannkoenig@chromium.org  if (webm_ctx->reader != NULL) {
2377496404dc182c2f4a5f86ebabffe1d1ceb81e7ejohannkoenig@chromium.org    mkvparser::MkvReader *const reader =
2477496404dc182c2f4a5f86ebabffe1d1ceb81e7ejohannkoenig@chromium.org        reinterpret_cast<mkvparser::MkvReader*>(webm_ctx->reader);
2577496404dc182c2f4a5f86ebabffe1d1ceb81e7ejohannkoenig@chromium.org    delete reader;
2677496404dc182c2f4a5f86ebabffe1d1ceb81e7ejohannkoenig@chromium.org  }
2777496404dc182c2f4a5f86ebabffe1d1ceb81e7ejohannkoenig@chromium.org  if (webm_ctx->segment != NULL) {
2877496404dc182c2f4a5f86ebabffe1d1ceb81e7ejohannkoenig@chromium.org    mkvparser::Segment *const segment =
2977496404dc182c2f4a5f86ebabffe1d1ceb81e7ejohannkoenig@chromium.org        reinterpret_cast<mkvparser::Segment*>(webm_ctx->segment);
3077496404dc182c2f4a5f86ebabffe1d1ceb81e7ejohannkoenig@chromium.org    delete segment;
3177496404dc182c2f4a5f86ebabffe1d1ceb81e7ejohannkoenig@chromium.org  }
3277496404dc182c2f4a5f86ebabffe1d1ceb81e7ejohannkoenig@chromium.org  if (webm_ctx->buffer != NULL) {
3377496404dc182c2f4a5f86ebabffe1d1ceb81e7ejohannkoenig@chromium.org    delete[] webm_ctx->buffer;
3477496404dc182c2f4a5f86ebabffe1d1ceb81e7ejohannkoenig@chromium.org  }
3577496404dc182c2f4a5f86ebabffe1d1ceb81e7ejohannkoenig@chromium.org  webm_ctx->reader = NULL;
3677496404dc182c2f4a5f86ebabffe1d1ceb81e7ejohannkoenig@chromium.org  webm_ctx->segment = NULL;
3777496404dc182c2f4a5f86ebabffe1d1ceb81e7ejohannkoenig@chromium.org  webm_ctx->buffer = NULL;
3877496404dc182c2f4a5f86ebabffe1d1ceb81e7ejohannkoenig@chromium.org  webm_ctx->cluster = NULL;
3977496404dc182c2f4a5f86ebabffe1d1ceb81e7ejohannkoenig@chromium.org  webm_ctx->block_entry = NULL;
4077496404dc182c2f4a5f86ebabffe1d1ceb81e7ejohannkoenig@chromium.org  webm_ctx->block = NULL;
4177496404dc182c2f4a5f86ebabffe1d1ceb81e7ejohannkoenig@chromium.org  webm_ctx->block_frame_index = 0;
4277496404dc182c2f4a5f86ebabffe1d1ceb81e7ejohannkoenig@chromium.org  webm_ctx->video_track_index = 0;
4377496404dc182c2f4a5f86ebabffe1d1ceb81e7ejohannkoenig@chromium.org  webm_ctx->timestamp_ns = 0;
4477496404dc182c2f4a5f86ebabffe1d1ceb81e7ejohannkoenig@chromium.org}
4577496404dc182c2f4a5f86ebabffe1d1ceb81e7ejohannkoenig@chromium.org
4677496404dc182c2f4a5f86ebabffe1d1ceb81e7ejohannkoenig@chromium.orgvoid get_first_cluster(struct WebmInputContext *const webm_ctx) {
4777496404dc182c2f4a5f86ebabffe1d1ceb81e7ejohannkoenig@chromium.org  mkvparser::Segment *const segment =
4877496404dc182c2f4a5f86ebabffe1d1ceb81e7ejohannkoenig@chromium.org      reinterpret_cast<mkvparser::Segment*>(webm_ctx->segment);
4977496404dc182c2f4a5f86ebabffe1d1ceb81e7ejohannkoenig@chromium.org  const mkvparser::Cluster *const cluster = segment->GetFirst();
5077496404dc182c2f4a5f86ebabffe1d1ceb81e7ejohannkoenig@chromium.org  webm_ctx->cluster = cluster;
5177496404dc182c2f4a5f86ebabffe1d1ceb81e7ejohannkoenig@chromium.org}
5277496404dc182c2f4a5f86ebabffe1d1ceb81e7ejohannkoenig@chromium.org
5377496404dc182c2f4a5f86ebabffe1d1ceb81e7ejohannkoenig@chromium.orgvoid rewind_and_reset(struct WebmInputContext *const webm_ctx,
5477496404dc182c2f4a5f86ebabffe1d1ceb81e7ejohannkoenig@chromium.org                      struct VpxInputContext *const vpx_ctx) {
5577496404dc182c2f4a5f86ebabffe1d1ceb81e7ejohannkoenig@chromium.org  rewind(vpx_ctx->file);
5677496404dc182c2f4a5f86ebabffe1d1ceb81e7ejohannkoenig@chromium.org  reset(webm_ctx);
5777496404dc182c2f4a5f86ebabffe1d1ceb81e7ejohannkoenig@chromium.org}
5877496404dc182c2f4a5f86ebabffe1d1ceb81e7ejohannkoenig@chromium.org
5977496404dc182c2f4a5f86ebabffe1d1ceb81e7ejohannkoenig@chromium.org}  // namespace
6077496404dc182c2f4a5f86ebabffe1d1ceb81e7ejohannkoenig@chromium.org
6177496404dc182c2f4a5f86ebabffe1d1ceb81e7ejohannkoenig@chromium.orgint file_is_webm(struct WebmInputContext *webm_ctx,
6277496404dc182c2f4a5f86ebabffe1d1ceb81e7ejohannkoenig@chromium.org                 struct VpxInputContext *vpx_ctx) {
6377496404dc182c2f4a5f86ebabffe1d1ceb81e7ejohannkoenig@chromium.org  mkvparser::MkvReader *const reader = new mkvparser::MkvReader(vpx_ctx->file);
6477496404dc182c2f4a5f86ebabffe1d1ceb81e7ejohannkoenig@chromium.org  webm_ctx->reader = reader;
6577496404dc182c2f4a5f86ebabffe1d1ceb81e7ejohannkoenig@chromium.org
6677496404dc182c2f4a5f86ebabffe1d1ceb81e7ejohannkoenig@chromium.org  mkvparser::EBMLHeader header;
6777496404dc182c2f4a5f86ebabffe1d1ceb81e7ejohannkoenig@chromium.org  long long pos = 0;
6877496404dc182c2f4a5f86ebabffe1d1ceb81e7ejohannkoenig@chromium.org  if (header.Parse(reader, pos) < 0) {
6977496404dc182c2f4a5f86ebabffe1d1ceb81e7ejohannkoenig@chromium.org    rewind_and_reset(webm_ctx, vpx_ctx);
7077496404dc182c2f4a5f86ebabffe1d1ceb81e7ejohannkoenig@chromium.org    return 0;
7177496404dc182c2f4a5f86ebabffe1d1ceb81e7ejohannkoenig@chromium.org  }
7277496404dc182c2f4a5f86ebabffe1d1ceb81e7ejohannkoenig@chromium.org
7377496404dc182c2f4a5f86ebabffe1d1ceb81e7ejohannkoenig@chromium.org  mkvparser::Segment* segment;
7477496404dc182c2f4a5f86ebabffe1d1ceb81e7ejohannkoenig@chromium.org  if (mkvparser::Segment::CreateInstance(reader, pos, segment)) {
7577496404dc182c2f4a5f86ebabffe1d1ceb81e7ejohannkoenig@chromium.org    rewind_and_reset(webm_ctx, vpx_ctx);
7677496404dc182c2f4a5f86ebabffe1d1ceb81e7ejohannkoenig@chromium.org    return 0;
7777496404dc182c2f4a5f86ebabffe1d1ceb81e7ejohannkoenig@chromium.org  }
7877496404dc182c2f4a5f86ebabffe1d1ceb81e7ejohannkoenig@chromium.org  webm_ctx->segment = segment;
7977496404dc182c2f4a5f86ebabffe1d1ceb81e7ejohannkoenig@chromium.org  if (segment->Load() < 0) {
8077496404dc182c2f4a5f86ebabffe1d1ceb81e7ejohannkoenig@chromium.org    rewind_and_reset(webm_ctx, vpx_ctx);
8177496404dc182c2f4a5f86ebabffe1d1ceb81e7ejohannkoenig@chromium.org    return 0;
8277496404dc182c2f4a5f86ebabffe1d1ceb81e7ejohannkoenig@chromium.org  }
8377496404dc182c2f4a5f86ebabffe1d1ceb81e7ejohannkoenig@chromium.org
8477496404dc182c2f4a5f86ebabffe1d1ceb81e7ejohannkoenig@chromium.org  const mkvparser::Tracks *const tracks = segment->GetTracks();
8577496404dc182c2f4a5f86ebabffe1d1ceb81e7ejohannkoenig@chromium.org  const mkvparser::VideoTrack* video_track = NULL;
8677496404dc182c2f4a5f86ebabffe1d1ceb81e7ejohannkoenig@chromium.org  for (unsigned long i = 0; i < tracks->GetTracksCount(); ++i) {
8777496404dc182c2f4a5f86ebabffe1d1ceb81e7ejohannkoenig@chromium.org    const mkvparser::Track* const track = tracks->GetTrackByIndex(i);
8877496404dc182c2f4a5f86ebabffe1d1ceb81e7ejohannkoenig@chromium.org    if (track->GetType() == mkvparser::Track::kVideo) {
8977496404dc182c2f4a5f86ebabffe1d1ceb81e7ejohannkoenig@chromium.org      video_track = static_cast<const mkvparser::VideoTrack*>(track);
9077496404dc182c2f4a5f86ebabffe1d1ceb81e7ejohannkoenig@chromium.org      webm_ctx->video_track_index = track->GetNumber();
9177496404dc182c2f4a5f86ebabffe1d1ceb81e7ejohannkoenig@chromium.org      break;
9277496404dc182c2f4a5f86ebabffe1d1ceb81e7ejohannkoenig@chromium.org    }
9377496404dc182c2f4a5f86ebabffe1d1ceb81e7ejohannkoenig@chromium.org  }
9477496404dc182c2f4a5f86ebabffe1d1ceb81e7ejohannkoenig@chromium.org
9577496404dc182c2f4a5f86ebabffe1d1ceb81e7ejohannkoenig@chromium.org  if (video_track == NULL) {
9677496404dc182c2f4a5f86ebabffe1d1ceb81e7ejohannkoenig@chromium.org    rewind_and_reset(webm_ctx, vpx_ctx);
9777496404dc182c2f4a5f86ebabffe1d1ceb81e7ejohannkoenig@chromium.org    return 0;
9877496404dc182c2f4a5f86ebabffe1d1ceb81e7ejohannkoenig@chromium.org  }
9977496404dc182c2f4a5f86ebabffe1d1ceb81e7ejohannkoenig@chromium.org
10077496404dc182c2f4a5f86ebabffe1d1ceb81e7ejohannkoenig@chromium.org  if (!strncmp(video_track->GetCodecId(), "V_VP8", 5)) {
10177496404dc182c2f4a5f86ebabffe1d1ceb81e7ejohannkoenig@chromium.org    vpx_ctx->fourcc = VP8_FOURCC;
10277496404dc182c2f4a5f86ebabffe1d1ceb81e7ejohannkoenig@chromium.org  } else if (!strncmp(video_track->GetCodecId(), "V_VP9", 5)) {
10377496404dc182c2f4a5f86ebabffe1d1ceb81e7ejohannkoenig@chromium.org    vpx_ctx->fourcc = VP9_FOURCC;
10477496404dc182c2f4a5f86ebabffe1d1ceb81e7ejohannkoenig@chromium.org  } else {
10577496404dc182c2f4a5f86ebabffe1d1ceb81e7ejohannkoenig@chromium.org    rewind_and_reset(webm_ctx, vpx_ctx);
10677496404dc182c2f4a5f86ebabffe1d1ceb81e7ejohannkoenig@chromium.org    return 0;
10777496404dc182c2f4a5f86ebabffe1d1ceb81e7ejohannkoenig@chromium.org  }
10877496404dc182c2f4a5f86ebabffe1d1ceb81e7ejohannkoenig@chromium.org
10977496404dc182c2f4a5f86ebabffe1d1ceb81e7ejohannkoenig@chromium.org  vpx_ctx->framerate.denominator = 0;
11077496404dc182c2f4a5f86ebabffe1d1ceb81e7ejohannkoenig@chromium.org  vpx_ctx->framerate.numerator = 0;
1115be267a803bbe61e0f4f1d5d878e02d3623182bcfgalligan@chromium.org  vpx_ctx->width = static_cast<uint32_t>(video_track->GetWidth());
1125be267a803bbe61e0f4f1d5d878e02d3623182bcfgalligan@chromium.org  vpx_ctx->height = static_cast<uint32_t>(video_track->GetHeight());
11377496404dc182c2f4a5f86ebabffe1d1ceb81e7ejohannkoenig@chromium.org
11477496404dc182c2f4a5f86ebabffe1d1ceb81e7ejohannkoenig@chromium.org  get_first_cluster(webm_ctx);
11577496404dc182c2f4a5f86ebabffe1d1ceb81e7ejohannkoenig@chromium.org
11677496404dc182c2f4a5f86ebabffe1d1ceb81e7ejohannkoenig@chromium.org  return 1;
11777496404dc182c2f4a5f86ebabffe1d1ceb81e7ejohannkoenig@chromium.org}
11877496404dc182c2f4a5f86ebabffe1d1ceb81e7ejohannkoenig@chromium.org
11977496404dc182c2f4a5f86ebabffe1d1ceb81e7ejohannkoenig@chromium.orgint webm_read_frame(struct WebmInputContext *webm_ctx,
12077496404dc182c2f4a5f86ebabffe1d1ceb81e7ejohannkoenig@chromium.org                    uint8_t **buffer,
12177496404dc182c2f4a5f86ebabffe1d1ceb81e7ejohannkoenig@chromium.org                    size_t *bytes_in_buffer,
12277496404dc182c2f4a5f86ebabffe1d1ceb81e7ejohannkoenig@chromium.org                    size_t *buffer_size) {
12377496404dc182c2f4a5f86ebabffe1d1ceb81e7ejohannkoenig@chromium.org  mkvparser::Segment *const segment =
12477496404dc182c2f4a5f86ebabffe1d1ceb81e7ejohannkoenig@chromium.org      reinterpret_cast<mkvparser::Segment*>(webm_ctx->segment);
12577496404dc182c2f4a5f86ebabffe1d1ceb81e7ejohannkoenig@chromium.org  const mkvparser::Cluster* cluster =
12677496404dc182c2f4a5f86ebabffe1d1ceb81e7ejohannkoenig@chromium.org      reinterpret_cast<const mkvparser::Cluster*>(webm_ctx->cluster);
12777496404dc182c2f4a5f86ebabffe1d1ceb81e7ejohannkoenig@chromium.org  const mkvparser::Block *block =
12877496404dc182c2f4a5f86ebabffe1d1ceb81e7ejohannkoenig@chromium.org      reinterpret_cast<const mkvparser::Block*>(webm_ctx->block);
12977496404dc182c2f4a5f86ebabffe1d1ceb81e7ejohannkoenig@chromium.org  const mkvparser::BlockEntry *block_entry =
13077496404dc182c2f4a5f86ebabffe1d1ceb81e7ejohannkoenig@chromium.org      reinterpret_cast<const mkvparser::BlockEntry*>(webm_ctx->block_entry);
13177496404dc182c2f4a5f86ebabffe1d1ceb81e7ejohannkoenig@chromium.org  bool block_entry_eos = false;
13277496404dc182c2f4a5f86ebabffe1d1ceb81e7ejohannkoenig@chromium.org  do {
13377496404dc182c2f4a5f86ebabffe1d1ceb81e7ejohannkoenig@chromium.org    long status = 0;
13477496404dc182c2f4a5f86ebabffe1d1ceb81e7ejohannkoenig@chromium.org    bool get_new_block = false;
13577496404dc182c2f4a5f86ebabffe1d1ceb81e7ejohannkoenig@chromium.org    if (block_entry == NULL && !block_entry_eos) {
13677496404dc182c2f4a5f86ebabffe1d1ceb81e7ejohannkoenig@chromium.org      status = cluster->GetFirst(block_entry);
13777496404dc182c2f4a5f86ebabffe1d1ceb81e7ejohannkoenig@chromium.org      get_new_block = true;
13877496404dc182c2f4a5f86ebabffe1d1ceb81e7ejohannkoenig@chromium.org    } else if (block_entry_eos || block_entry->EOS()) {
13977496404dc182c2f4a5f86ebabffe1d1ceb81e7ejohannkoenig@chromium.org      cluster = segment->GetNext(cluster);
14077496404dc182c2f4a5f86ebabffe1d1ceb81e7ejohannkoenig@chromium.org      if (cluster == NULL || cluster->EOS()) {
14177496404dc182c2f4a5f86ebabffe1d1ceb81e7ejohannkoenig@chromium.org        *bytes_in_buffer = 0;
14277496404dc182c2f4a5f86ebabffe1d1ceb81e7ejohannkoenig@chromium.org        return 1;
14377496404dc182c2f4a5f86ebabffe1d1ceb81e7ejohannkoenig@chromium.org      }
14477496404dc182c2f4a5f86ebabffe1d1ceb81e7ejohannkoenig@chromium.org      status = cluster->GetFirst(block_entry);
14577496404dc182c2f4a5f86ebabffe1d1ceb81e7ejohannkoenig@chromium.org      block_entry_eos = false;
14677496404dc182c2f4a5f86ebabffe1d1ceb81e7ejohannkoenig@chromium.org      get_new_block = true;
14777496404dc182c2f4a5f86ebabffe1d1ceb81e7ejohannkoenig@chromium.org    } else if (block == NULL ||
14877496404dc182c2f4a5f86ebabffe1d1ceb81e7ejohannkoenig@chromium.org               webm_ctx->block_frame_index == block->GetFrameCount() ||
14977496404dc182c2f4a5f86ebabffe1d1ceb81e7ejohannkoenig@chromium.org               block->GetTrackNumber() != webm_ctx->video_track_index) {
15077496404dc182c2f4a5f86ebabffe1d1ceb81e7ejohannkoenig@chromium.org      status = cluster->GetNext(block_entry, block_entry);
15177496404dc182c2f4a5f86ebabffe1d1ceb81e7ejohannkoenig@chromium.org      if (block_entry == NULL || block_entry->EOS()) {
15277496404dc182c2f4a5f86ebabffe1d1ceb81e7ejohannkoenig@chromium.org        block_entry_eos = true;
15377496404dc182c2f4a5f86ebabffe1d1ceb81e7ejohannkoenig@chromium.org        continue;
15477496404dc182c2f4a5f86ebabffe1d1ceb81e7ejohannkoenig@chromium.org      }
15577496404dc182c2f4a5f86ebabffe1d1ceb81e7ejohannkoenig@chromium.org      get_new_block = true;
15677496404dc182c2f4a5f86ebabffe1d1ceb81e7ejohannkoenig@chromium.org    }
15777496404dc182c2f4a5f86ebabffe1d1ceb81e7ejohannkoenig@chromium.org    if (status) {
15877496404dc182c2f4a5f86ebabffe1d1ceb81e7ejohannkoenig@chromium.org      return -1;
15977496404dc182c2f4a5f86ebabffe1d1ceb81e7ejohannkoenig@chromium.org    }
16077496404dc182c2f4a5f86ebabffe1d1ceb81e7ejohannkoenig@chromium.org    if (get_new_block) {
16177496404dc182c2f4a5f86ebabffe1d1ceb81e7ejohannkoenig@chromium.org      block = block_entry->GetBlock();
16277496404dc182c2f4a5f86ebabffe1d1ceb81e7ejohannkoenig@chromium.org      webm_ctx->block_frame_index = 0;
16377496404dc182c2f4a5f86ebabffe1d1ceb81e7ejohannkoenig@chromium.org    }
16477496404dc182c2f4a5f86ebabffe1d1ceb81e7ejohannkoenig@chromium.org  } while (block->GetTrackNumber() != webm_ctx->video_track_index ||
16577496404dc182c2f4a5f86ebabffe1d1ceb81e7ejohannkoenig@chromium.org           block_entry_eos);
16677496404dc182c2f4a5f86ebabffe1d1ceb81e7ejohannkoenig@chromium.org
16777496404dc182c2f4a5f86ebabffe1d1ceb81e7ejohannkoenig@chromium.org  webm_ctx->cluster = cluster;
16877496404dc182c2f4a5f86ebabffe1d1ceb81e7ejohannkoenig@chromium.org  webm_ctx->block_entry = block_entry;
16977496404dc182c2f4a5f86ebabffe1d1ceb81e7ejohannkoenig@chromium.org  webm_ctx->block = block;
17077496404dc182c2f4a5f86ebabffe1d1ceb81e7ejohannkoenig@chromium.org
17177496404dc182c2f4a5f86ebabffe1d1ceb81e7ejohannkoenig@chromium.org  const mkvparser::Block::Frame& frame =
17277496404dc182c2f4a5f86ebabffe1d1ceb81e7ejohannkoenig@chromium.org      block->GetFrame(webm_ctx->block_frame_index);
17377496404dc182c2f4a5f86ebabffe1d1ceb81e7ejohannkoenig@chromium.org  ++webm_ctx->block_frame_index;
17477496404dc182c2f4a5f86ebabffe1d1ceb81e7ejohannkoenig@chromium.org  if (frame.len > static_cast<long>(*buffer_size)) {
17577496404dc182c2f4a5f86ebabffe1d1ceb81e7ejohannkoenig@chromium.org    delete[] *buffer;
17677496404dc182c2f4a5f86ebabffe1d1ceb81e7ejohannkoenig@chromium.org    *buffer = new uint8_t[frame.len];
17777496404dc182c2f4a5f86ebabffe1d1ceb81e7ejohannkoenig@chromium.org    if (*buffer == NULL) {
17877496404dc182c2f4a5f86ebabffe1d1ceb81e7ejohannkoenig@chromium.org      return -1;
17977496404dc182c2f4a5f86ebabffe1d1ceb81e7ejohannkoenig@chromium.org    }
18077496404dc182c2f4a5f86ebabffe1d1ceb81e7ejohannkoenig@chromium.org    *buffer_size = frame.len;
18177496404dc182c2f4a5f86ebabffe1d1ceb81e7ejohannkoenig@chromium.org    webm_ctx->buffer = *buffer;
18277496404dc182c2f4a5f86ebabffe1d1ceb81e7ejohannkoenig@chromium.org  }
18377496404dc182c2f4a5f86ebabffe1d1ceb81e7ejohannkoenig@chromium.org  *bytes_in_buffer = frame.len;
18477496404dc182c2f4a5f86ebabffe1d1ceb81e7ejohannkoenig@chromium.org  webm_ctx->timestamp_ns = block->GetTime(cluster);
18577496404dc182c2f4a5f86ebabffe1d1ceb81e7ejohannkoenig@chromium.org
18677496404dc182c2f4a5f86ebabffe1d1ceb81e7ejohannkoenig@chromium.org  mkvparser::MkvReader *const reader =
18777496404dc182c2f4a5f86ebabffe1d1ceb81e7ejohannkoenig@chromium.org      reinterpret_cast<mkvparser::MkvReader*>(webm_ctx->reader);
18877496404dc182c2f4a5f86ebabffe1d1ceb81e7ejohannkoenig@chromium.org  return frame.Read(reader, *buffer) ? -1 : 0;
18977496404dc182c2f4a5f86ebabffe1d1ceb81e7ejohannkoenig@chromium.org}
19077496404dc182c2f4a5f86ebabffe1d1ceb81e7ejohannkoenig@chromium.org
19177496404dc182c2f4a5f86ebabffe1d1ceb81e7ejohannkoenig@chromium.orgint webm_guess_framerate(struct WebmInputContext *webm_ctx,
19277496404dc182c2f4a5f86ebabffe1d1ceb81e7ejohannkoenig@chromium.org                         struct VpxInputContext *vpx_ctx) {
19377496404dc182c2f4a5f86ebabffe1d1ceb81e7ejohannkoenig@chromium.org  uint32_t i = 0;
19477496404dc182c2f4a5f86ebabffe1d1ceb81e7ejohannkoenig@chromium.org  uint8_t *buffer = NULL;
19577496404dc182c2f4a5f86ebabffe1d1ceb81e7ejohannkoenig@chromium.org  size_t bytes_in_buffer = 0;
19677496404dc182c2f4a5f86ebabffe1d1ceb81e7ejohannkoenig@chromium.org  size_t buffer_size = 0;
19777496404dc182c2f4a5f86ebabffe1d1ceb81e7ejohannkoenig@chromium.org  while (webm_ctx->timestamp_ns < 1000000000 && i < 50) {
19877496404dc182c2f4a5f86ebabffe1d1ceb81e7ejohannkoenig@chromium.org    if (webm_read_frame(webm_ctx, &buffer, &bytes_in_buffer, &buffer_size)) {
19977496404dc182c2f4a5f86ebabffe1d1ceb81e7ejohannkoenig@chromium.org      break;
20077496404dc182c2f4a5f86ebabffe1d1ceb81e7ejohannkoenig@chromium.org    }
20177496404dc182c2f4a5f86ebabffe1d1ceb81e7ejohannkoenig@chromium.org    ++i;
20277496404dc182c2f4a5f86ebabffe1d1ceb81e7ejohannkoenig@chromium.org  }
20377496404dc182c2f4a5f86ebabffe1d1ceb81e7ejohannkoenig@chromium.org  vpx_ctx->framerate.numerator = (i - 1) * 1000000;
20477496404dc182c2f4a5f86ebabffe1d1ceb81e7ejohannkoenig@chromium.org  vpx_ctx->framerate.denominator =
20577496404dc182c2f4a5f86ebabffe1d1ceb81e7ejohannkoenig@chromium.org      static_cast<int>(webm_ctx->timestamp_ns / 1000);
20677496404dc182c2f4a5f86ebabffe1d1ceb81e7ejohannkoenig@chromium.org  delete[] buffer;
20777496404dc182c2f4a5f86ebabffe1d1ceb81e7ejohannkoenig@chromium.org
20877496404dc182c2f4a5f86ebabffe1d1ceb81e7ejohannkoenig@chromium.org  get_first_cluster(webm_ctx);
20977496404dc182c2f4a5f86ebabffe1d1ceb81e7ejohannkoenig@chromium.org  webm_ctx->block = NULL;
21077496404dc182c2f4a5f86ebabffe1d1ceb81e7ejohannkoenig@chromium.org  webm_ctx->block_entry = NULL;
21177496404dc182c2f4a5f86ebabffe1d1ceb81e7ejohannkoenig@chromium.org  webm_ctx->block_frame_index = 0;
21277496404dc182c2f4a5f86ebabffe1d1ceb81e7ejohannkoenig@chromium.org  webm_ctx->timestamp_ns = 0;
21377496404dc182c2f4a5f86ebabffe1d1ceb81e7ejohannkoenig@chromium.org
21477496404dc182c2f4a5f86ebabffe1d1ceb81e7ejohannkoenig@chromium.org  return 0;
21577496404dc182c2f4a5f86ebabffe1d1ceb81e7ejohannkoenig@chromium.org}
21677496404dc182c2f4a5f86ebabffe1d1ceb81e7ejohannkoenig@chromium.org
21777496404dc182c2f4a5f86ebabffe1d1ceb81e7ejohannkoenig@chromium.orgvoid webm_free(struct WebmInputContext *webm_ctx) {
21877496404dc182c2f4a5f86ebabffe1d1ceb81e7ejohannkoenig@chromium.org  reset(webm_ctx);
21977496404dc182c2f4a5f86ebabffe1d1ceb81e7ejohannkoenig@chromium.org}
220