Vignesh Venkatasubramanian | 2dcbf8c | 2014-03-19 11:56:02 -0700 | [diff] [blame] | 1 | /* |
Yaowu Xu | 9c01aa1 | 2016-09-01 14:32:49 -0700 | [diff] [blame] | 2 | * Copyright (c) 2016, Alliance for Open Media. All rights reserved |
Vignesh Venkatasubramanian | 2dcbf8c | 2014-03-19 11:56:02 -0700 | [diff] [blame] | 3 | * |
Yaowu Xu | 9c01aa1 | 2016-09-01 14:32:49 -0700 | [diff] [blame] | 4 | * This source code is subject to the terms of the BSD 2 Clause License and |
| 5 | * the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License |
| 6 | * was not distributed with this source code in the LICENSE file, you can |
| 7 | * obtain it at www.aomedia.org/license/software. If the Alliance for Open |
| 8 | * Media Patent License 1.0 was not distributed with this source code in the |
| 9 | * PATENTS file, you can obtain it at www.aomedia.org/license/patent. |
| 10 | */ |
| 11 | |
Vignesh Venkatasubramanian | 2dcbf8c | 2014-03-19 11:56:02 -0700 | [diff] [blame] | 12 | #include "./webmenc.h" |
| 13 | |
| 14 | #include <string> |
| 15 | |
Tom Finegan | 4317ba5 | 2016-03-24 13:12:51 -0700 | [diff] [blame] | 16 | #include "third_party/libwebm/mkvmuxer/mkvmuxer.h" |
| 17 | #include "third_party/libwebm/mkvmuxer/mkvmuxerutil.h" |
| 18 | #include "third_party/libwebm/mkvmuxer/mkvwriter.h" |
Vignesh Venkatasubramanian | 2dcbf8c | 2014-03-19 11:56:02 -0700 | [diff] [blame] | 19 | |
| 20 | namespace { |
| 21 | const uint64_t kDebugTrackUid = 0xDEADBEEF; |
| 22 | const int kVideoTrackNumber = 1; |
| 23 | } // namespace |
| 24 | |
Vignesh Venkatasubramanian | 9441f10 | 2016-04-25 13:28:24 -0700 | [diff] [blame] | 25 | void write_webm_file_header(struct WebmOutputContext *webm_ctx, |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 26 | const aom_codec_enc_cfg_t *cfg, |
clang-format | 01f4c71 | 2016-08-12 15:10:25 -0700 | [diff] [blame] | 27 | stereo_format_t stereo_fmt, unsigned int fourcc, |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 28 | const struct AvxRational *par) { |
Vignesh Venkatasubramanian | 9441f10 | 2016-04-25 13:28:24 -0700 | [diff] [blame] | 29 | mkvmuxer::MkvWriter *const writer = new mkvmuxer::MkvWriter(webm_ctx->stream); |
Vignesh Venkatasubramanian | 2dcbf8c | 2014-03-19 11:56:02 -0700 | [diff] [blame] | 30 | mkvmuxer::Segment *const segment = new mkvmuxer::Segment(); |
| 31 | segment->Init(writer); |
| 32 | segment->set_mode(mkvmuxer::Segment::kFile); |
| 33 | segment->OutputCues(true); |
| 34 | |
| 35 | mkvmuxer::SegmentInfo *const info = segment->GetSegmentInfo(); |
| 36 | const uint64_t kTimecodeScale = 1000000; |
| 37 | info->set_timecode_scale(kTimecodeScale); |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 38 | std::string version = "aomenc"; |
Vignesh Venkatasubramanian | 9441f10 | 2016-04-25 13:28:24 -0700 | [diff] [blame] | 39 | if (!webm_ctx->debug) { |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 40 | version.append(std::string(" ") + aom_codec_version_str()); |
Vignesh Venkatasubramanian | 2dcbf8c | 2014-03-19 11:56:02 -0700 | [diff] [blame] | 41 | } |
| 42 | info->set_writing_app(version.c_str()); |
| 43 | |
| 44 | const uint64_t video_track_id = |
| 45 | segment->AddVideoTrack(static_cast<int>(cfg->g_w), |
clang-format | 01f4c71 | 2016-08-12 15:10:25 -0700 | [diff] [blame] | 46 | static_cast<int>(cfg->g_h), kVideoTrackNumber); |
| 47 | mkvmuxer::VideoTrack *const video_track = static_cast<mkvmuxer::VideoTrack *>( |
| 48 | segment->GetTrackByNumber(video_track_id)); |
Vignesh Venkatasubramanian | 2dcbf8c | 2014-03-19 11:56:02 -0700 | [diff] [blame] | 49 | video_track->SetStereoMode(stereo_fmt); |
Yaowu Xu | 3d1bb97 | 2015-08-14 12:30:10 -0700 | [diff] [blame] | 50 | const char *codec_id; |
| 51 | switch (fourcc) { |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 52 | case AV1_FOURCC: codec_id = "V_AV1"; break; |
| 53 | default: codec_id = "V_AV1"; break; |
Yaowu Xu | 3d1bb97 | 2015-08-14 12:30:10 -0700 | [diff] [blame] | 54 | } |
| 55 | video_track->set_codec_id(codec_id); |
Frank Galligan | 09acd26 | 2015-06-01 10:20:58 -0700 | [diff] [blame] | 56 | if (par->numerator > 1 || par->denominator > 1) { |
| 57 | // TODO(fgalligan): Add support of DisplayUnit, Display Aspect Ratio type |
| 58 | // to WebM format. |
clang-format | 01f4c71 | 2016-08-12 15:10:25 -0700 | [diff] [blame] | 59 | const uint64_t display_width = static_cast<uint64_t>( |
| 60 | ((cfg->g_w * par->numerator * 1.0) / par->denominator) + .5); |
Frank Galligan | 09acd26 | 2015-06-01 10:20:58 -0700 | [diff] [blame] | 61 | video_track->set_display_width(display_width); |
| 62 | video_track->set_display_height(cfg->g_h); |
| 63 | } |
Vignesh Venkatasubramanian | 9441f10 | 2016-04-25 13:28:24 -0700 | [diff] [blame] | 64 | if (webm_ctx->debug) { |
Vignesh Venkatasubramanian | 2dcbf8c | 2014-03-19 11:56:02 -0700 | [diff] [blame] | 65 | video_track->set_uid(kDebugTrackUid); |
| 66 | } |
Vignesh Venkatasubramanian | 9441f10 | 2016-04-25 13:28:24 -0700 | [diff] [blame] | 67 | webm_ctx->writer = writer; |
| 68 | webm_ctx->segment = segment; |
Vignesh Venkatasubramanian | 2dcbf8c | 2014-03-19 11:56:02 -0700 | [diff] [blame] | 69 | } |
| 70 | |
Vignesh Venkatasubramanian | 9441f10 | 2016-04-25 13:28:24 -0700 | [diff] [blame] | 71 | void write_webm_block(struct WebmOutputContext *webm_ctx, |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 72 | const aom_codec_enc_cfg_t *cfg, |
| 73 | const aom_codec_cx_pkt_t *pkt) { |
Vignesh Venkatasubramanian | 2dcbf8c | 2014-03-19 11:56:02 -0700 | [diff] [blame] | 74 | mkvmuxer::Segment *const segment = |
clang-format | 01f4c71 | 2016-08-12 15:10:25 -0700 | [diff] [blame] | 75 | reinterpret_cast<mkvmuxer::Segment *>(webm_ctx->segment); |
| 76 | int64_t pts_ns = pkt->data.frame.pts * 1000000000ll * cfg->g_timebase.num / |
| 77 | cfg->g_timebase.den; |
| 78 | if (pts_ns <= webm_ctx->last_pts_ns) pts_ns = webm_ctx->last_pts_ns + 1000000; |
Vignesh Venkatasubramanian | 9441f10 | 2016-04-25 13:28:24 -0700 | [diff] [blame] | 79 | webm_ctx->last_pts_ns = pts_ns; |
Vignesh Venkatasubramanian | 2dcbf8c | 2014-03-19 11:56:02 -0700 | [diff] [blame] | 80 | |
clang-format | 01f4c71 | 2016-08-12 15:10:25 -0700 | [diff] [blame] | 81 | segment->AddFrame(static_cast<uint8_t *>(pkt->data.frame.buf), |
| 82 | pkt->data.frame.sz, kVideoTrackNumber, pts_ns, |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 83 | pkt->data.frame.flags & AOM_FRAME_IS_KEY); |
Vignesh Venkatasubramanian | 2dcbf8c | 2014-03-19 11:56:02 -0700 | [diff] [blame] | 84 | } |
| 85 | |
Vignesh Venkatasubramanian | 9441f10 | 2016-04-25 13:28:24 -0700 | [diff] [blame] | 86 | void write_webm_file_footer(struct WebmOutputContext *webm_ctx) { |
Vignesh Venkatasubramanian | 2dcbf8c | 2014-03-19 11:56:02 -0700 | [diff] [blame] | 87 | mkvmuxer::MkvWriter *const writer = |
clang-format | 01f4c71 | 2016-08-12 15:10:25 -0700 | [diff] [blame] | 88 | reinterpret_cast<mkvmuxer::MkvWriter *>(webm_ctx->writer); |
Vignesh Venkatasubramanian | 2dcbf8c | 2014-03-19 11:56:02 -0700 | [diff] [blame] | 89 | mkvmuxer::Segment *const segment = |
clang-format | 01f4c71 | 2016-08-12 15:10:25 -0700 | [diff] [blame] | 90 | reinterpret_cast<mkvmuxer::Segment *>(webm_ctx->segment); |
Vignesh Venkatasubramanian | 2dcbf8c | 2014-03-19 11:56:02 -0700 | [diff] [blame] | 91 | segment->Finalize(); |
| 92 | delete segment; |
| 93 | delete writer; |
Vignesh Venkatasubramanian | 9441f10 | 2016-04-25 13:28:24 -0700 | [diff] [blame] | 94 | webm_ctx->writer = NULL; |
| 95 | webm_ctx->segment = NULL; |
Vignesh Venkatasubramanian | 2dcbf8c | 2014-03-19 11:56:02 -0700 | [diff] [blame] | 96 | } |