1233d2500723e5594f3e7c70896ffeeef32b9c950ywan/*
2233d2500723e5594f3e7c70896ffeeef32b9c950ywan *  Copyright (c) 2014 The WebM project authors. All Rights Reserved.
3233d2500723e5594f3e7c70896ffeeef32b9c950ywan *
4233d2500723e5594f3e7c70896ffeeef32b9c950ywan *  Use of this source code is governed by a BSD-style license
5233d2500723e5594f3e7c70896ffeeef32b9c950ywan *  that can be found in the LICENSE file in the root of the source
6233d2500723e5594f3e7c70896ffeeef32b9c950ywan *  tree. An additional intellectual property rights grant can be found
7233d2500723e5594f3e7c70896ffeeef32b9c950ywan *  in the file PATENTS.  All contributing project authors may
8233d2500723e5594f3e7c70896ffeeef32b9c950ywan *  be found in the AUTHORS file in the root of the source tree.
9233d2500723e5594f3e7c70896ffeeef32b9c950ywan */
10233d2500723e5594f3e7c70896ffeeef32b9c950ywan
11233d2500723e5594f3e7c70896ffeeef32b9c950ywan#include <stdlib.h>
12233d2500723e5594f3e7c70896ffeeef32b9c950ywan
13233d2500723e5594f3e7c70896ffeeef32b9c950ywan#include "./ivfenc.h"
14233d2500723e5594f3e7c70896ffeeef32b9c950ywan#include "./video_writer.h"
15233d2500723e5594f3e7c70896ffeeef32b9c950ywan#include "vpx/vpx_encoder.h"
16233d2500723e5594f3e7c70896ffeeef32b9c950ywan
17233d2500723e5594f3e7c70896ffeeef32b9c950ywanstruct VpxVideoWriterStruct {
18233d2500723e5594f3e7c70896ffeeef32b9c950ywan  VpxVideoInfo info;
19233d2500723e5594f3e7c70896ffeeef32b9c950ywan  FILE *file;
20233d2500723e5594f3e7c70896ffeeef32b9c950ywan  int frame_count;
21233d2500723e5594f3e7c70896ffeeef32b9c950ywan};
22233d2500723e5594f3e7c70896ffeeef32b9c950ywan
23233d2500723e5594f3e7c70896ffeeef32b9c950ywanstatic void write_header(FILE *file, const VpxVideoInfo *info,
24233d2500723e5594f3e7c70896ffeeef32b9c950ywan                         int frame_count) {
25233d2500723e5594f3e7c70896ffeeef32b9c950ywan  struct vpx_codec_enc_cfg cfg;
26233d2500723e5594f3e7c70896ffeeef32b9c950ywan  cfg.g_w = info->frame_width;
27233d2500723e5594f3e7c70896ffeeef32b9c950ywan  cfg.g_h = info->frame_height;
28233d2500723e5594f3e7c70896ffeeef32b9c950ywan  cfg.g_timebase.num = info->time_base.numerator;
29233d2500723e5594f3e7c70896ffeeef32b9c950ywan  cfg.g_timebase.den = info->time_base.denominator;
30233d2500723e5594f3e7c70896ffeeef32b9c950ywan
31233d2500723e5594f3e7c70896ffeeef32b9c950ywan  ivf_write_file_header(file, &cfg, info->codec_fourcc, frame_count);
32233d2500723e5594f3e7c70896ffeeef32b9c950ywan}
33233d2500723e5594f3e7c70896ffeeef32b9c950ywan
34233d2500723e5594f3e7c70896ffeeef32b9c950ywanVpxVideoWriter *vpx_video_writer_open(const char *filename,
35233d2500723e5594f3e7c70896ffeeef32b9c950ywan                                      VpxContainer container,
36233d2500723e5594f3e7c70896ffeeef32b9c950ywan                                      const VpxVideoInfo *info) {
37233d2500723e5594f3e7c70896ffeeef32b9c950ywan  if (container == kContainerIVF) {
38233d2500723e5594f3e7c70896ffeeef32b9c950ywan    VpxVideoWriter *writer = NULL;
39233d2500723e5594f3e7c70896ffeeef32b9c950ywan    FILE *const file = fopen(filename, "wb");
40233d2500723e5594f3e7c70896ffeeef32b9c950ywan    if (!file)
41233d2500723e5594f3e7c70896ffeeef32b9c950ywan      return NULL;
42233d2500723e5594f3e7c70896ffeeef32b9c950ywan
43233d2500723e5594f3e7c70896ffeeef32b9c950ywan    writer = malloc(sizeof(*writer));
44233d2500723e5594f3e7c70896ffeeef32b9c950ywan    if (!writer)
45233d2500723e5594f3e7c70896ffeeef32b9c950ywan      return NULL;
46233d2500723e5594f3e7c70896ffeeef32b9c950ywan
47233d2500723e5594f3e7c70896ffeeef32b9c950ywan    writer->frame_count = 0;
48233d2500723e5594f3e7c70896ffeeef32b9c950ywan    writer->info = *info;
49233d2500723e5594f3e7c70896ffeeef32b9c950ywan    writer->file = file;
50233d2500723e5594f3e7c70896ffeeef32b9c950ywan
51233d2500723e5594f3e7c70896ffeeef32b9c950ywan    write_header(writer->file, info, 0);
52233d2500723e5594f3e7c70896ffeeef32b9c950ywan
53233d2500723e5594f3e7c70896ffeeef32b9c950ywan    return writer;
54233d2500723e5594f3e7c70896ffeeef32b9c950ywan  }
55233d2500723e5594f3e7c70896ffeeef32b9c950ywan
56233d2500723e5594f3e7c70896ffeeef32b9c950ywan  return NULL;
57233d2500723e5594f3e7c70896ffeeef32b9c950ywan}
58233d2500723e5594f3e7c70896ffeeef32b9c950ywan
59233d2500723e5594f3e7c70896ffeeef32b9c950ywanvoid vpx_video_writer_close(VpxVideoWriter *writer) {
60233d2500723e5594f3e7c70896ffeeef32b9c950ywan  if (writer) {
61233d2500723e5594f3e7c70896ffeeef32b9c950ywan    // Rewriting frame header with real frame count
62233d2500723e5594f3e7c70896ffeeef32b9c950ywan    rewind(writer->file);
63233d2500723e5594f3e7c70896ffeeef32b9c950ywan    write_header(writer->file, &writer->info, writer->frame_count);
64233d2500723e5594f3e7c70896ffeeef32b9c950ywan
65233d2500723e5594f3e7c70896ffeeef32b9c950ywan    fclose(writer->file);
66233d2500723e5594f3e7c70896ffeeef32b9c950ywan    free(writer);
67233d2500723e5594f3e7c70896ffeeef32b9c950ywan  }
68233d2500723e5594f3e7c70896ffeeef32b9c950ywan}
69233d2500723e5594f3e7c70896ffeeef32b9c950ywan
70233d2500723e5594f3e7c70896ffeeef32b9c950ywanint vpx_video_writer_write_frame(VpxVideoWriter *writer,
71233d2500723e5594f3e7c70896ffeeef32b9c950ywan                                 const uint8_t *buffer, size_t size,
72233d2500723e5594f3e7c70896ffeeef32b9c950ywan                                 int64_t pts) {
73233d2500723e5594f3e7c70896ffeeef32b9c950ywan  ivf_write_frame_header(writer->file, pts, size);
74233d2500723e5594f3e7c70896ffeeef32b9c950ywan  if (fwrite(buffer, 1, size, writer->file) != size)
75233d2500723e5594f3e7c70896ffeeef32b9c950ywan    return 0;
76233d2500723e5594f3e7c70896ffeeef32b9c950ywan
77233d2500723e5594f3e7c70896ffeeef32b9c950ywan  ++writer->frame_count;
78233d2500723e5594f3e7c70896ffeeef32b9c950ywan
79233d2500723e5594f3e7c70896ffeeef32b9c950ywan  return 1;
80233d2500723e5594f3e7c70896ffeeef32b9c950ywan}
81