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