176e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org/*
276e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org *  Copyright (c) 2014 The WebM project authors. All Rights Reserved.
376e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org *
476e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org *  Use of this source code is governed by a BSD-style license
576e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org *  that can be found in the LICENSE file in the root of the source
676e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org *  tree. An additional intellectual property rights grant can be found
776e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org *  in the file PATENTS.  All contributing project authors may
876e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org *  be found in the AUTHORS file in the root of the source tree.
976e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org */
1076e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org
1176e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org#include <stdlib.h>
1276e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org#include <string.h>
1376e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org
1476e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org#include "./ivfdec.h"
1576e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org#include "./video_reader.h"
1676e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org
17411971f94253c85e1866c281860d6344f6aa0c78fgalligan@chromium.org#include "vpx_ports/mem_ops.h"
18411971f94253c85e1866c281860d6344f6aa0c78fgalligan@chromium.org
1976e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.orgstatic const char *const kIVFSignature = "DKIF";
2076e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org
2176e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.orgstruct VpxVideoReaderStruct {
2276e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org  VpxVideoInfo info;
2376e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org  FILE *file;
2476e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org  uint8_t *buffer;
2576e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org  size_t buffer_size;
2676e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org  size_t frame_size;
2776e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org};
2876e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org
2976e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.orgVpxVideoReader *vpx_video_reader_open(const char *filename) {
3076e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org  char header[32];
3176e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org  VpxVideoReader *reader = NULL;
3276e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org  FILE *const file = fopen(filename, "rb");
3376e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org  if (!file)
3476e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org    return NULL;  // Can't open file
3576e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org
3676e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org  if (fread(header, 1, 32, file) != 32)
3776e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org    return NULL;  // Can't read file header
3876e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org
3976e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org  if (memcmp(kIVFSignature, header, 4) != 0)
4076e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org    return NULL;  // Wrong IVF signature
4176e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org
4276e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org  if (mem_get_le16(header + 4) != 0)
4376e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org    return NULL;  // Wrong IVF version
4476e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org
4576e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org  reader = calloc(1, sizeof(*reader));
4676e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org  if (!reader)
4776e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org    return NULL;  // Can't allocate VpxVideoReader
4876e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org
4976e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org  reader->file = file;
5076e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org  reader->info.codec_fourcc = mem_get_le32(header + 8);
5176e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org  reader->info.frame_width = mem_get_le16(header + 12);
5276e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org  reader->info.frame_height = mem_get_le16(header + 14);
5376e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org  reader->info.time_base.numerator = mem_get_le32(header + 16);
5476e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org  reader->info.time_base.denominator = mem_get_le32(header + 20);
5576e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org
5676e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org  return reader;
5776e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org}
5876e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org
5976e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.orgvoid vpx_video_reader_close(VpxVideoReader *reader) {
6076e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org  if (reader) {
6176e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org    fclose(reader->file);
6276e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org    free(reader->buffer);
6376e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org    free(reader);
6476e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org  }
6576e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org}
6676e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org
6776e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.orgint vpx_video_reader_read_frame(VpxVideoReader *reader) {
6876e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org  return !ivf_read_frame(reader->file, &reader->buffer, &reader->frame_size,
6976e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org                         &reader->buffer_size);
7076e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org}
7176e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org
7276e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.orgconst uint8_t *vpx_video_reader_get_frame(VpxVideoReader *reader,
7376e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org                                          size_t *size) {
7476e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org  if (size)
7576e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org    *size = reader->frame_size;
7676e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org
7776e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org  return reader->buffer;
7876e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org}
7976e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org
8076e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.orgconst VpxVideoInfo *vpx_video_reader_get_info(VpxVideoReader *reader) {
8176e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org  return &reader->info;
8276e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org}
8376e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org
84