1/* 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, 24 const vpx_codec_enc_cfg_t *cfg, 25 const struct vpx_rational *fps, 26 stereo_format_t stereo_fmt, 27 unsigned int fourcc) { 28 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); 37 std::string version = "vpxenc"; 38 if (!glob->debug) { 39 version.append(std::string(" ") + vpx_codec_version_str()); 40 } 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), 45 static_cast<int>(cfg->g_h), 46 kVideoTrackNumber); 47 mkvmuxer::VideoTrack* const video_track = 48 static_cast<mkvmuxer::VideoTrack*>( 49 segment->GetTrackByNumber(video_track_id)); 50 video_track->SetStereoMode(stereo_fmt); 51 video_track->set_codec_id(fourcc == VP8_FOURCC ? "V_VP8" : "V_VP9"); 52 if (glob->debug) { 53 video_track->set_uid(kDebugTrackUid); 54 } 55 glob->writer = writer; 56 glob->segment = segment; 57} 58 59void write_webm_block(struct EbmlGlobal *glob, 60 const vpx_codec_enc_cfg_t *cfg, 61 const vpx_codec_cx_pkt_t *pkt) { 62 mkvmuxer::Segment *const segment = 63 reinterpret_cast<mkvmuxer::Segment*>(glob->segment); 64 int64_t pts_ns = pkt->data.frame.pts * 1000000000ll * 65 cfg->g_timebase.num / cfg->g_timebase.den; 66 if (pts_ns <= glob->last_pts_ns) 67 pts_ns = glob->last_pts_ns + 1000000; 68 glob->last_pts_ns = pts_ns; 69 70 segment->AddFrame(static_cast<uint8_t*>(pkt->data.frame.buf), 71 pkt->data.frame.sz, 72 kVideoTrackNumber, 73 pts_ns, 74 pkt->data.frame.flags & VPX_FRAME_IS_KEY); 75} 76 77void write_webm_file_footer(struct EbmlGlobal *glob) { 78 mkvmuxer::MkvWriter *const writer = 79 reinterpret_cast<mkvmuxer::MkvWriter*>(glob->writer); 80 mkvmuxer::Segment *const segment = 81 reinterpret_cast<mkvmuxer::Segment*>(glob->segment); 82 segment->Finalize(); 83 delete segment; 84 delete writer; 85 glob->writer = NULL; 86 glob->segment = NULL; 87} 88