blob: 75cceeb74ba6c246dfb01887c23f47675f257caf [file] [log] [blame]
Vignesh Venkatasubramanian2dcbf8c2014-03-19 11:56:02 -07001/*
2 * Copyright (c) 2014 The WebM project authors. All Rights Reserved.
3 *
4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
9 */
10#include "./webmenc.h"
11
12#include <string>
13
14#include "third_party/libwebm/mkvmuxer.hpp"
15#include "third_party/libwebm/mkvmuxerutil.hpp"
16#include "third_party/libwebm/mkvwriter.hpp"
17
18namespace {
19const uint64_t kDebugTrackUid = 0xDEADBEEF;
20const int kVideoTrackNumber = 1;
21} // namespace
22
23void write_webm_file_header(struct EbmlGlobal *glob,
Adrian Grangecebe6f02016-03-25 12:11:05 -070024 const aom_codec_enc_cfg_t *cfg,
25 const struct aom_rational *fps,
clang-format99e28b82016-01-27 12:42:45 -080026 stereo_format_t stereo_fmt, unsigned int fourcc,
Frank Galligan09acd262015-06-01 10:20:58 -070027 const struct VpxRational *par) {
Vignesh Venkatasubramanian2dcbf8c2014-03-19 11:56:02 -070028 mkvmuxer::MkvWriter *const writer = new mkvmuxer::MkvWriter(glob->stream);
29 mkvmuxer::Segment *const segment = new mkvmuxer::Segment();
30 segment->Init(writer);
31 segment->set_mode(mkvmuxer::Segment::kFile);
32 segment->OutputCues(true);
33
34 mkvmuxer::SegmentInfo *const info = segment->GetSegmentInfo();
35 const uint64_t kTimecodeScale = 1000000;
36 info->set_timecode_scale(kTimecodeScale);
Adrian Grangecebe6f02016-03-25 12:11:05 -070037 std::string version = "aomenc";
Vignesh Venkatasubramanian2dcbf8c2014-03-19 11:56:02 -070038 if (!glob->debug) {
Adrian Grangecebe6f02016-03-25 12:11:05 -070039 version.append(std::string(" ") + aom_codec_version_str());
Vignesh Venkatasubramanian2dcbf8c2014-03-19 11:56:02 -070040 }
41 info->set_writing_app(version.c_str());
42
43 const uint64_t video_track_id =
44 segment->AddVideoTrack(static_cast<int>(cfg->g_w),
clang-format99e28b82016-01-27 12:42:45 -080045 static_cast<int>(cfg->g_h), kVideoTrackNumber);
46 mkvmuxer::VideoTrack *const video_track = static_cast<mkvmuxer::VideoTrack *>(
47 segment->GetTrackByNumber(video_track_id));
Vignesh Venkatasubramanian2dcbf8c2014-03-19 11:56:02 -070048 video_track->SetStereoMode(stereo_fmt);
Yaowu Xu3d1bb972015-08-14 12:30:10 -070049 const char *codec_id;
50 switch (fourcc) {
clang-format99e28b82016-01-27 12:42:45 -080051 case VP8_FOURCC: codec_id = "V_VP8"; break;
52 case VP9_FOURCC: codec_id = "V_VP9"; break;
Yaowu Xu01dee0b2016-03-25 12:43:01 -070053 case AV1_FOURCC: codec_id = "V_AV1"; break;
54 default: codec_id = "V_AV1"; break;
Yaowu Xu3d1bb972015-08-14 12:30:10 -070055 }
56 video_track->set_codec_id(codec_id);
Frank Galligan09acd262015-06-01 10:20:58 -070057 if (par->numerator > 1 || par->denominator > 1) {
58 // TODO(fgalligan): Add support of DisplayUnit, Display Aspect Ratio type
59 // to WebM format.
clang-format99e28b82016-01-27 12:42:45 -080060 const uint64_t display_width = static_cast<uint64_t>(
61 ((cfg->g_w * par->numerator * 1.0) / par->denominator) + .5);
Frank Galligan09acd262015-06-01 10:20:58 -070062 video_track->set_display_width(display_width);
63 video_track->set_display_height(cfg->g_h);
64 }
Vignesh Venkatasubramanian2dcbf8c2014-03-19 11:56:02 -070065 if (glob->debug) {
66 video_track->set_uid(kDebugTrackUid);
67 }
68 glob->writer = writer;
69 glob->segment = segment;
70}
71
Adrian Grangecebe6f02016-03-25 12:11:05 -070072void write_webm_block(struct EbmlGlobal *glob, const aom_codec_enc_cfg_t *cfg,
73 const aom_codec_cx_pkt_t *pkt) {
Vignesh Venkatasubramanian2dcbf8c2014-03-19 11:56:02 -070074 mkvmuxer::Segment *const segment =
clang-format99e28b82016-01-27 12:42:45 -080075 reinterpret_cast<mkvmuxer::Segment *>(glob->segment);
76 int64_t pts_ns = pkt->data.frame.pts * 1000000000ll * cfg->g_timebase.num /
77 cfg->g_timebase.den;
78 if (pts_ns <= glob->last_pts_ns) pts_ns = glob->last_pts_ns + 1000000;
Vignesh Venkatasubramanian2dcbf8c2014-03-19 11:56:02 -070079 glob->last_pts_ns = pts_ns;
80
clang-format99e28b82016-01-27 12:42:45 -080081 segment->AddFrame(static_cast<uint8_t *>(pkt->data.frame.buf),
82 pkt->data.frame.sz, kVideoTrackNumber, pts_ns,
Vignesh Venkatasubramanian2dcbf8c2014-03-19 11:56:02 -070083 pkt->data.frame.flags & VPX_FRAME_IS_KEY);
84}
85
86void write_webm_file_footer(struct EbmlGlobal *glob) {
87 mkvmuxer::MkvWriter *const writer =
clang-format99e28b82016-01-27 12:42:45 -080088 reinterpret_cast<mkvmuxer::MkvWriter *>(glob->writer);
Vignesh Venkatasubramanian2dcbf8c2014-03-19 11:56:02 -070089 mkvmuxer::Segment *const segment =
clang-format99e28b82016-01-27 12:42:45 -080090 reinterpret_cast<mkvmuxer::Segment *>(glob->segment);
Vignesh Venkatasubramanian2dcbf8c2014-03-19 11:56:02 -070091 segment->Finalize();
92 delete segment;
93 delete writer;
94 glob->writer = NULL;
95 glob->segment = NULL;
96}