1d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org/* 2d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org * Copyright (c) 2013 The WebM project authors. All Rights Reserved. 3d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org * 4d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org * Use of this source code is governed by a BSD-style license 5d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org * that can be found in the LICENSE file in the root of the source 6d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org * tree. An additional intellectual property rights grant can be found 7d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org * in the file PATENTS. All contributing project authors may 8d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org * be found in the AUTHORS file in the root of the source tree. 9d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org */ 10d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org 11d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org#include <stdio.h> 12d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org#include <stdlib.h> 13dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org#include <string.h> 14dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org 15411971f94253c85e1866c281860d6344f6aa0c78fgalligan@chromium.org#include "vpx_ports/mem_ops.h" 16411971f94253c85e1866c281860d6344f6aa0c78fgalligan@chromium.org 17dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org#include "./ivfdec.h" 18dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org 19dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.orgstatic const char *IVF_SIGNATURE = "DKIF"; 20dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org 21dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.orgstatic void fix_framerate(int *num, int *den) { 22dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org // Some versions of vpxenc used 1/(2*fps) for the timebase, so 23dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org // we can guess the framerate using only the timebase in this 24dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org // case. Other files would require reading ahead to guess the 25dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org // timebase, like we do for webm. 26dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org if (*num < 1000) { 27dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org // Correct for the factor of 2 applied to the timebase in the encoder. 28dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org if (*num & 1) 29dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org *den *= 2; 30dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org else 31dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org *num /= 2; 32dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org } else { 33dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org // Don't know FPS for sure, and don't have readahead code 34dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org // (yet?), so just default to 30fps. 35dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org *num = 30; 36dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org *den = 1; 37dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org } 38dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org} 39d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org 40d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.orgint file_is_ivf(struct VpxInputContext *input_ctx) { 41d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org char raw_hdr[32]; 42d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org int is_ivf = 0; 43d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org 44d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org if (fread(raw_hdr, 1, 32, input_ctx->file) == 32) { 45dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org if (memcmp(IVF_SIGNATURE, raw_hdr, 4) == 0) { 46d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org is_ivf = 1; 47d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org 48d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org if (mem_get_le16(raw_hdr + 4) != 0) { 49d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org fprintf(stderr, "Error: Unrecognized IVF version! This file may not" 50d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org " decode properly."); 51d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org } 52d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org 53d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org input_ctx->fourcc = mem_get_le32(raw_hdr + 8); 54d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org input_ctx->width = mem_get_le16(raw_hdr + 12); 55d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org input_ctx->height = mem_get_le16(raw_hdr + 14); 56d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org input_ctx->framerate.numerator = mem_get_le32(raw_hdr + 16); 57d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org input_ctx->framerate.denominator = mem_get_le32(raw_hdr + 20); 58dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org fix_framerate(&input_ctx->framerate.numerator, 59dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org &input_ctx->framerate.denominator); 60d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org } 61d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org } 62d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org 63d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org if (!is_ivf) { 64d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org rewind(input_ctx->file); 65d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org input_ctx->detect.buf_read = 0; 66d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org } else { 67d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org input_ctx->detect.position = 4; 68d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org } 69d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org return is_ivf; 70d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org} 71d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org 72dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.orgint ivf_read_frame(FILE *infile, uint8_t **buffer, 73dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org size_t *bytes_read, size_t *buffer_size) { 74d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org char raw_header[IVF_FRAME_HDR_SZ] = {0}; 75d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org size_t frame_size = 0; 76d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org 77d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org if (fread(raw_header, IVF_FRAME_HDR_SZ, 1, infile) != 1) { 78d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org if (!feof(infile)) 79d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org warn("Failed to read frame size\n"); 80d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org } else { 81d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org frame_size = mem_get_le32(raw_header); 82d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org 83d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org if (frame_size > 256 * 1024 * 1024) { 84d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org warn("Read invalid frame size (%u)\n", (unsigned int)frame_size); 85d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org frame_size = 0; 86d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org } 87d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org 88d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org if (frame_size > *buffer_size) { 89d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org uint8_t *new_buffer = realloc(*buffer, 2 * frame_size); 90d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org 91d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org if (new_buffer) { 92d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org *buffer = new_buffer; 93d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org *buffer_size = 2 * frame_size; 94d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org } else { 95d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org warn("Failed to allocate compressed data buffer\n"); 96d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org frame_size = 0; 97d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org } 98d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org } 99d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org } 100d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org 101d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org if (!feof(infile)) { 102d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org if (fread(*buffer, 1, frame_size, infile) != frame_size) { 103d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org warn("Failed to read full frame\n"); 104d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org return 1; 105d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org } 106d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org 107d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org *bytes_read = frame_size; 108d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org return 0; 109d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org } 110d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org 111d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org return 1; 112d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org} 113