1ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian/*
2ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian *  Copyright (c) 2013 The WebM project authors. All Rights Reserved.
3ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian *
4ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian *  Use of this source code is governed by a BSD-style license
5ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian *  that can be found in the LICENSE file in the root of the source
6ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian *  tree. An additional intellectual property rights grant can be found
7ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian *  in the file PATENTS.  All contributing project authors may
8ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian *  be found in the AUTHORS file in the root of the source tree.
9ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian */
10ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian
11ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#include "./webmdec.h"
12ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian
13ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#include <cstring>
14ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#include <cstdio>
15ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian
16ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#include "third_party/libwebm/mkvparser.hpp"
17ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#include "third_party/libwebm/mkvreader.hpp"
18ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian
19ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramaniannamespace {
20ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian
21ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianvoid reset(struct WebmInputContext *const webm_ctx) {
22ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  if (webm_ctx->reader != NULL) {
23ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    mkvparser::MkvReader *const reader =
24ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian        reinterpret_cast<mkvparser::MkvReader*>(webm_ctx->reader);
25ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    delete reader;
26ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  }
27ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  if (webm_ctx->segment != NULL) {
28ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    mkvparser::Segment *const segment =
29ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian        reinterpret_cast<mkvparser::Segment*>(webm_ctx->segment);
30ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    delete segment;
31ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  }
32ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  if (webm_ctx->buffer != NULL) {
33ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    delete[] webm_ctx->buffer;
34ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  }
35ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  webm_ctx->reader = NULL;
36ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  webm_ctx->segment = NULL;
37ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  webm_ctx->buffer = NULL;
38ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  webm_ctx->cluster = NULL;
39ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  webm_ctx->block_entry = NULL;
40ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  webm_ctx->block = NULL;
41ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  webm_ctx->block_frame_index = 0;
42ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  webm_ctx->video_track_index = 0;
43ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  webm_ctx->timestamp_ns = 0;
44da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian  webm_ctx->is_key_frame = false;
45ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian}
46ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian
47ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianvoid get_first_cluster(struct WebmInputContext *const webm_ctx) {
48ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  mkvparser::Segment *const segment =
49ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian      reinterpret_cast<mkvparser::Segment*>(webm_ctx->segment);
50ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  const mkvparser::Cluster *const cluster = segment->GetFirst();
51ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  webm_ctx->cluster = cluster;
52ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian}
53ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian
54ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianvoid rewind_and_reset(struct WebmInputContext *const webm_ctx,
55ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian                      struct VpxInputContext *const vpx_ctx) {
56ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  rewind(vpx_ctx->file);
57ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  reset(webm_ctx);
58ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian}
59ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian
60ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian}  // namespace
61ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian
62ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianint file_is_webm(struct WebmInputContext *webm_ctx,
63ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian                 struct VpxInputContext *vpx_ctx) {
64ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  mkvparser::MkvReader *const reader = new mkvparser::MkvReader(vpx_ctx->file);
65ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  webm_ctx->reader = reader;
66da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian  webm_ctx->reached_eos = 0;
67ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian
68ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  mkvparser::EBMLHeader header;
69ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  long long pos = 0;
70ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  if (header.Parse(reader, pos) < 0) {
71ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    rewind_and_reset(webm_ctx, vpx_ctx);
72ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    return 0;
73ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  }
74ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian
75ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  mkvparser::Segment* segment;
76ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  if (mkvparser::Segment::CreateInstance(reader, pos, segment)) {
77ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    rewind_and_reset(webm_ctx, vpx_ctx);
78ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    return 0;
79ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  }
80ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  webm_ctx->segment = segment;
81ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  if (segment->Load() < 0) {
82ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    rewind_and_reset(webm_ctx, vpx_ctx);
83ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    return 0;
84ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  }
85ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian
86ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  const mkvparser::Tracks *const tracks = segment->GetTracks();
87ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  const mkvparser::VideoTrack* video_track = NULL;
88ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  for (unsigned long i = 0; i < tracks->GetTracksCount(); ++i) {
89ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    const mkvparser::Track* const track = tracks->GetTrackByIndex(i);
90ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    if (track->GetType() == mkvparser::Track::kVideo) {
91ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian      video_track = static_cast<const mkvparser::VideoTrack*>(track);
92ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian      webm_ctx->video_track_index = track->GetNumber();
93ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian      break;
94ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    }
95ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  }
96ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian
972263fc984bdc858ee931d3e35c87c404de923950Johann  if (video_track == NULL || video_track->GetCodecId() == NULL) {
98ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    rewind_and_reset(webm_ctx, vpx_ctx);
99ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    return 0;
100ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  }
101ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian
102ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  if (!strncmp(video_track->GetCodecId(), "V_VP8", 5)) {
103ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    vpx_ctx->fourcc = VP8_FOURCC;
104ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  } else if (!strncmp(video_track->GetCodecId(), "V_VP9", 5)) {
105ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    vpx_ctx->fourcc = VP9_FOURCC;
106da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian  } else if (!strncmp(video_track->GetCodecId(), "V_VP10", 6)) {
107da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian    vpx_ctx->fourcc = VP10_FOURCC;
108ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  } else {
109ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    rewind_and_reset(webm_ctx, vpx_ctx);
110ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    return 0;
111ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  }
112ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian
113ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  vpx_ctx->framerate.denominator = 0;
114ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  vpx_ctx->framerate.numerator = 0;
115ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  vpx_ctx->width = static_cast<uint32_t>(video_track->GetWidth());
116ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  vpx_ctx->height = static_cast<uint32_t>(video_track->GetHeight());
117ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian
118ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  get_first_cluster(webm_ctx);
119ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian
120ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  return 1;
121ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian}
122ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian
123ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianint webm_read_frame(struct WebmInputContext *webm_ctx,
124ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian                    uint8_t **buffer,
125ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian                    size_t *bytes_in_buffer,
126ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian                    size_t *buffer_size) {
127da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian  // This check is needed for frame parallel decoding, in which case this
128da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian  // function could be called even after it has reached end of input stream.
129da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian  if (webm_ctx->reached_eos) {
130da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian    return 1;
131da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian  }
132ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  mkvparser::Segment *const segment =
133ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian      reinterpret_cast<mkvparser::Segment*>(webm_ctx->segment);
134ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  const mkvparser::Cluster* cluster =
135ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian      reinterpret_cast<const mkvparser::Cluster*>(webm_ctx->cluster);
136ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  const mkvparser::Block *block =
137ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian      reinterpret_cast<const mkvparser::Block*>(webm_ctx->block);
138ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  const mkvparser::BlockEntry *block_entry =
139ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian      reinterpret_cast<const mkvparser::BlockEntry*>(webm_ctx->block_entry);
140ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  bool block_entry_eos = false;
141ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  do {
142ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    long status = 0;
143ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    bool get_new_block = false;
144ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    if (block_entry == NULL && !block_entry_eos) {
145ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian      status = cluster->GetFirst(block_entry);
146ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian      get_new_block = true;
147ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    } else if (block_entry_eos || block_entry->EOS()) {
148ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian      cluster = segment->GetNext(cluster);
149ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian      if (cluster == NULL || cluster->EOS()) {
150ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian        *bytes_in_buffer = 0;
151da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian        webm_ctx->reached_eos = 1;
152ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian        return 1;
153ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian      }
154ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian      status = cluster->GetFirst(block_entry);
155ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian      block_entry_eos = false;
156ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian      get_new_block = true;
157ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    } else if (block == NULL ||
158ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian               webm_ctx->block_frame_index == block->GetFrameCount() ||
159ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian               block->GetTrackNumber() != webm_ctx->video_track_index) {
160ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian      status = cluster->GetNext(block_entry, block_entry);
161ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian      if (block_entry == NULL || block_entry->EOS()) {
162ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian        block_entry_eos = true;
163ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian        continue;
164ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian      }
165ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian      get_new_block = true;
166ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    }
167ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    if (status) {
168ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian      return -1;
169ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    }
170ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    if (get_new_block) {
171ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian      block = block_entry->GetBlock();
172ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian      webm_ctx->block_frame_index = 0;
173ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    }
174ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  } while (block->GetTrackNumber() != webm_ctx->video_track_index ||
175ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian           block_entry_eos);
176ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian
177ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  webm_ctx->cluster = cluster;
178ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  webm_ctx->block_entry = block_entry;
179ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  webm_ctx->block = block;
180ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian
181ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  const mkvparser::Block::Frame& frame =
182ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian      block->GetFrame(webm_ctx->block_frame_index);
183ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  ++webm_ctx->block_frame_index;
184ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  if (frame.len > static_cast<long>(*buffer_size)) {
185ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    delete[] *buffer;
186ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    *buffer = new uint8_t[frame.len];
187ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    if (*buffer == NULL) {
188ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian      return -1;
189ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    }
190ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    *buffer_size = frame.len;
191ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    webm_ctx->buffer = *buffer;
192ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  }
193ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  *bytes_in_buffer = frame.len;
194ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  webm_ctx->timestamp_ns = block->GetTime(cluster);
195da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian  webm_ctx->is_key_frame = block->IsKey();
196ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian
197ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  mkvparser::MkvReader *const reader =
198ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian      reinterpret_cast<mkvparser::MkvReader*>(webm_ctx->reader);
199ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  return frame.Read(reader, *buffer) ? -1 : 0;
200ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian}
201ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian
202ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianint webm_guess_framerate(struct WebmInputContext *webm_ctx,
203ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian                         struct VpxInputContext *vpx_ctx) {
204ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  uint32_t i = 0;
205ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  uint8_t *buffer = NULL;
206ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  size_t bytes_in_buffer = 0;
207ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  size_t buffer_size = 0;
208ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  while (webm_ctx->timestamp_ns < 1000000000 && i < 50) {
209ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    if (webm_read_frame(webm_ctx, &buffer, &bytes_in_buffer, &buffer_size)) {
210ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian      break;
211ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    }
212ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    ++i;
213ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  }
214ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  vpx_ctx->framerate.numerator = (i - 1) * 1000000;
215ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  vpx_ctx->framerate.denominator =
216ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian      static_cast<int>(webm_ctx->timestamp_ns / 1000);
217ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  delete[] buffer;
218ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian
219ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  get_first_cluster(webm_ctx);
220ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  webm_ctx->block = NULL;
221ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  webm_ctx->block_entry = NULL;
222ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  webm_ctx->block_frame_index = 0;
223ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  webm_ctx->timestamp_ns = 0;
224da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian  webm_ctx->reached_eos = 0;
225ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian
226ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  return 0;
227ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian}
228ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian
229ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianvoid webm_free(struct WebmInputContext *webm_ctx) {
230ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  reset(webm_ctx);
231ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian}
232