summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--build/make/Makefile11
-rwxr-xr-xconfigure12
-rw-r--r--examples.mk16
-rw-r--r--vpxenc.c64
-rw-r--r--webmenc.c331
-rw-r--r--webmenc.cc86
-rw-r--r--webmenc.h48
7 files changed, 126 insertions, 442 deletions
diff --git a/build/make/Makefile b/build/make/Makefile
index dd7fb4a21..0c5ff64f4 100644
--- a/build/make/Makefile
+++ b/build/make/Makefile
@@ -147,6 +147,15 @@ $(BUILD_PFX)%.cc.o: %.cc
$(if $(quiet),@echo " [CXX] $@")
$(qexec)$(CXX) $(INTERNAL_CFLAGS) $(CXXFLAGS) -c -o $@ $<
+$(BUILD_PFX)%.cpp.d: %.cpp
+ $(if $(quiet),@echo " [DEP] $@")
+ $(qexec)mkdir -p $(dir $@)
+ $(qexec)$(CXX) $(INTERNAL_CFLAGS) $(CXXFLAGS) -M $< | $(fmt_deps) > $@
+
+$(BUILD_PFX)%.cpp.o: %.cpp
+ $(if $(quiet),@echo " [CXX] $@")
+ $(qexec)$(CXX) $(INTERNAL_CFLAGS) $(CXXFLAGS) -c -o $@ $<
+
$(BUILD_PFX)%.asm.d: %.asm
$(if $(quiet),@echo " [DEP] $@")
$(qexec)mkdir -p $(dir $@)
@@ -218,7 +227,7 @@ cond_enabled=$(if $(filter yes,$($(1))), $(call enabled,$(2)))
find_file1=$(word 1,$(wildcard $(subst //,/,$(addsuffix /$(1),$(2)))))
find_file=$(foreach f,$(1),$(call find_file1,$(strip $(f)),$(strip $(2))) )
-obj_pats=.c=.c.o $(AS_SFX)=$(AS_SFX).o .cc=.cc.o
+obj_pats=.c=.c.o $(AS_SFX)=$(AS_SFX).o .cc=.cc.o .cpp=.cpp.o
objs=$(addprefix $(BUILD_PFX),$(foreach p,$(obj_pats),$(filter %.o,$(1:$(p))) ))
install_map_templates=$(eval $(call install_map_template,$(1),$(2)))
diff --git a/configure b/configure
index ff350cc3e..01c421d34 100755
--- a/configure
+++ b/configure
@@ -704,13 +704,11 @@ process_toolchain() {
enabled postproc || die "postproc_visualizer requires postproc to be enabled"
fi
- # Enable WebM IO by default.
- soft_enable webm_io
-
# Enable unit tests by default if we have a working C++ compiler.
case "$toolchain" in
*-vs*)
soft_enable unit_tests
+ soft_enable webm_io
;;
*-android-*)
# GTestLog must be modified to use Android logging utilities.
@@ -726,13 +724,21 @@ process_toolchain() {
check_cxx "$@" <<EOF && soft_enable unit_tests
int z;
EOF
+ check_cxx "$@" <<EOF && soft_enable webm_io
+int z;
+EOF
;;
*)
enabled pthread_h && check_cxx "$@" <<EOF && soft_enable unit_tests
int z;
EOF
+ check_cxx "$@" <<EOF && soft_enable webm_io
+int z;
+EOF
;;
esac
+ # libwebm needs to be linked with C++ standard library
+ enabled webm_io && LD=${CXX}
}
diff --git a/examples.mk b/examples.mk
index 87be5a8c9..f091c2de4 100644
--- a/examples.mk
+++ b/examples.mk
@@ -15,6 +15,16 @@ LIBYUV_SRCS += third_party/libyuv/include/libyuv/basic_types.h \
third_party/libyuv/source/scale.c \
third_party/libyuv/source/cpu_id.c
+LIBWEBM_MUXER_SRCS += third_party/libwebm/mkvmuxer.cpp \
+ third_party/libwebm/mkvmuxerutil.cpp \
+ third_party/libwebm/mkvwriter.cpp \
+ third_party/libwebm/mkvmuxer.hpp \
+ third_party/libwebm/mkvmuxertypes.hpp \
+ third_party/libwebm/mkvmuxerutil.hpp \
+ third_party/libwebm/mkvparser.hpp \
+ third_party/libwebm/mkvwriter.hpp \
+ third_party/libwebm/webmids.hpp
+
# List of examples to build. UTILS are tools meant for distribution
# while EXAMPLES demonstrate specific portions of the API.
UTILS-$(CONFIG_DECODERS) += vpxdec.c
@@ -53,10 +63,8 @@ vpxenc.SRCS += vpx_ports/vpx_timer.h
vpxenc.SRCS += vpxstats.c vpxstats.h
vpxenc.SRCS += $(LIBYUV_SRCS)
ifeq ($(CONFIG_WEBM_IO),yes)
- vpxenc.SRCS += third_party/libmkv/EbmlIDs.h
- vpxenc.SRCS += third_party/libmkv/EbmlWriter.c
- vpxenc.SRCS += third_party/libmkv/EbmlWriter.h
- vpxenc.SRCS += webmenc.c webmenc.h
+ vpxenc.SRCS += $(LIBWEBM_MUXER_SRCS)
+ vpxenc.SRCS += webmenc.cc webmenc.h
endif
vpxenc.GUID = 548DEC74-7A15-4B2B-AFC3-AA102E7C25C1
vpxenc.DESCRIPTION = Full featured encoder
diff --git a/vpxenc.c b/vpxenc.c
index 1cd5e9232..f1c9c9a7b 100644
--- a/vpxenc.c
+++ b/vpxenc.c
@@ -123,55 +123,6 @@ int fourcc_is_ivf(const char detect[4]) {
return 0;
}
-#if CONFIG_WEBM_IO
-/* Murmur hash derived from public domain reference implementation at
- * http:// sites.google.com/site/murmurhash/
- */
-static unsigned int murmur(const void *key, int len, unsigned int seed) {
- const unsigned int m = 0x5bd1e995;
- const int r = 24;
-
- unsigned int h = seed ^ len;
-
- const unsigned char *data = (const unsigned char *)key;
-
- while (len >= 4) {
- unsigned int k;
-
- k = (unsigned int)data[0];
- k |= (unsigned int)data[1] << 8;
- k |= (unsigned int)data[2] << 16;
- k |= (unsigned int)data[3] << 24;
-
- k *= m;
- k ^= k >> r;
- k *= m;
-
- h *= m;
- h ^= k;
-
- data += 4;
- len -= 4;
- }
-
- switch (len) {
- case 3:
- h ^= data[2] << 16;
- case 2:
- h ^= data[1] << 8;
- case 1:
- h ^= data[0];
- h *= m;
- };
-
- h ^= h >> 13;
- h *= m;
- h ^= h >> 15;
-
- return h;
-}
-#endif // CONFIG_WEBM_IO
-
static const arg_def_t debugmode = ARG_DEF("D", "debug", 0,
"Debug mode (makes output deterministic)");
static const arg_def_t outputfile = ARG_DEF("o", "output", 1,
@@ -614,7 +565,6 @@ struct stream_state {
FILE *file;
struct rate_hist *rate_hist;
struct EbmlGlobal ebml;
- uint32_t hash;
uint64_t psnr_sse_total;
uint64_t psnr_samples_total;
double psnr_totals[4];
@@ -836,7 +786,9 @@ static struct stream_state *new_stream(struct VpxEncoderConfig *global,
stream->config.stereo_fmt = STEREO_FORMAT_MONO;
stream->config.write_webm = 1;
#if CONFIG_WEBM_IO
- stream->ebml.last_pts_ms = -1;
+ stream->ebml.last_pts_ns = -1;
+ stream->ebml.writer = NULL;
+ stream->ebml.segment = NULL;
#endif
/* Allows removal of the application version from the EBML tags */
@@ -1171,9 +1123,7 @@ static void close_output_file(struct stream_state *stream,
#if CONFIG_WEBM_IO
if (stream->config.write_webm) {
- write_webm_file_footer(&stream->ebml, stream->hash);
- free(stream->ebml.cue_list);
- stream->ebml.cue_list = NULL;
+ write_webm_file_footer(&stream->ebml);
}
#endif
@@ -1329,12 +1279,6 @@ static void get_cx_data(struct stream_state *stream,
update_rate_histogram(stream->rate_hist, cfg, pkt);
#if CONFIG_WEBM_IO
if (stream->config.write_webm) {
- /* Update the hash */
- if (!stream->ebml.debug)
- stream->hash = murmur(pkt->data.frame.buf,
- (int)pkt->data.frame.sz,
- stream->hash);
-
write_webm_block(&stream->ebml, cfg, pkt);
}
#endif
diff --git a/webmenc.c b/webmenc.c
deleted file mode 100644
index 17bbeec78..000000000
--- a/webmenc.c
+++ /dev/null
@@ -1,331 +0,0 @@
-/*
- * Copyright (c) 2013 The WebM project authors. All Rights Reserved.
- *
- * Use of this source code is governed by a BSD-style license
- * that can be found in the LICENSE file in the root of the source
- * tree. An additional intellectual property rights grant can be found
- * in the file PATENTS. All contributing project authors may
- * be found in the AUTHORS file in the root of the source tree.
- */
-#include "webmenc.h"
-
-#include <limits.h>
-#include <string.h>
-
-#include "third_party/libmkv/EbmlWriter.h"
-#include "third_party/libmkv/EbmlIDs.h"
-
-void Ebml_Write(struct EbmlGlobal *glob,
- const void *buffer_in,
- unsigned long len) {
- (void) fwrite(buffer_in, 1, len, glob->stream);
-}
-
-#define WRITE_BUFFER(s) \
-for (i = len - 1; i >= 0; i--) { \
- x = (char)(*(const s *)buffer_in >> (i * CHAR_BIT)); \
- Ebml_Write(glob, &x, 1); \
-}
-
-void Ebml_Serialize(struct EbmlGlobal *glob,
- const void *buffer_in,
- int buffer_size,
- unsigned long len) {
- char x;
- int i;
-
- /* buffer_size:
- * 1 - int8_t;
- * 2 - int16_t;
- * 3 - int32_t;
- * 4 - int64_t;
- */
- switch (buffer_size) {
- case 1:
- WRITE_BUFFER(int8_t)
- break;
- case 2:
- WRITE_BUFFER(int16_t)
- break;
- case 4:
- WRITE_BUFFER(int32_t)
- break;
- case 8:
- WRITE_BUFFER(int64_t)
- break;
- default:
- break;
- }
-}
-#undef WRITE_BUFFER
-
-/* Need a fixed size serializer for the track ID. libmkv provides a 64 bit
- * one, but not a 32 bit one.
- */
-static void Ebml_SerializeUnsigned32(struct EbmlGlobal *glob,
- unsigned int class_id,
- uint64_t ui) {
- const unsigned char sizeSerialized = 4 | 0x80;
- Ebml_WriteID(glob, class_id);
- Ebml_Serialize(glob, &sizeSerialized, sizeof(sizeSerialized), 1);
- Ebml_Serialize(glob, &ui, sizeof(ui), 4);
-}
-
-static void Ebml_StartSubElement(struct EbmlGlobal *glob,
- EbmlLoc *ebmlLoc,
- unsigned int class_id) {
- const uint64_t kEbmlUnknownLength = LITERALU64(0x01FFFFFF, 0xFFFFFFFF);
- Ebml_WriteID(glob, class_id);
- *ebmlLoc = ftello(glob->stream);
- Ebml_Serialize(glob, &kEbmlUnknownLength, sizeof(kEbmlUnknownLength), 8);
-}
-
-static void Ebml_EndSubElement(struct EbmlGlobal *glob, EbmlLoc *ebmlLoc) {
- off_t pos;
- uint64_t size;
-
- /* Save the current stream pointer. */
- pos = ftello(glob->stream);
-
- /* Calculate the size of this element. */
- size = pos - *ebmlLoc - 8;
- size |= LITERALU64(0x01000000, 0x00000000);
-
- /* Seek back to the beginning of the element and write the new size. */
- fseeko(glob->stream, *ebmlLoc, SEEK_SET);
- Ebml_Serialize(glob, &size, sizeof(size), 8);
-
- /* Reset the stream pointer. */
- fseeko(glob->stream, pos, SEEK_SET);
-}
-
-void write_webm_seek_element(struct EbmlGlobal *ebml,
- unsigned int id,
- off_t pos) {
- uint64_t offset = pos - ebml->position_reference;
- EbmlLoc start;
- Ebml_StartSubElement(ebml, &start, Seek);
- Ebml_SerializeBinary(ebml, SeekID, id);
- Ebml_SerializeUnsigned64(ebml, SeekPosition, offset);
- Ebml_EndSubElement(ebml, &start);
-}
-
-void write_webm_seek_info(struct EbmlGlobal *ebml) {
- off_t pos;
- EbmlLoc start;
- EbmlLoc startInfo;
- uint64_t frame_time;
- char version_string[64];
-
- /* Save the current stream pointer. */
- pos = ftello(ebml->stream);
-
- if (ebml->seek_info_pos)
- fseeko(ebml->stream, ebml->seek_info_pos, SEEK_SET);
- else
- ebml->seek_info_pos = pos;
-
- Ebml_StartSubElement(ebml, &start, SeekHead);
- write_webm_seek_element(ebml, Tracks, ebml->track_pos);
- write_webm_seek_element(ebml, Cues, ebml->cue_pos);
- write_webm_seek_element(ebml, Info, ebml->segment_info_pos);
- Ebml_EndSubElement(ebml, &start);
-
- /* Create and write the Segment Info. */
- if (ebml->debug) {
- strcpy(version_string, "vpxenc");
- } else {
- strcpy(version_string, "vpxenc ");
- strncat(version_string,
- vpx_codec_version_str(),
- sizeof(version_string) - 1 - strlen(version_string));
- }
-
- frame_time = (uint64_t)1000 * ebml->framerate.den
- / ebml->framerate.num;
- ebml->segment_info_pos = ftello(ebml->stream);
- Ebml_StartSubElement(ebml, &startInfo, Info);
- Ebml_SerializeUnsigned(ebml, TimecodeScale, 1000000);
- Ebml_SerializeFloat(ebml, Segment_Duration,
- (double)(ebml->last_pts_ms + frame_time));
- Ebml_SerializeString(ebml, 0x4D80, version_string);
- Ebml_SerializeString(ebml, 0x5741, version_string);
- Ebml_EndSubElement(ebml, &startInfo);
-}
-
-void write_webm_file_header(struct EbmlGlobal *glob,
- const vpx_codec_enc_cfg_t *cfg,
- const struct vpx_rational *fps,
- stereo_format_t stereo_fmt,
- unsigned int fourcc) {
- EbmlLoc start;
- EbmlLoc trackStart;
- EbmlLoc videoStart;
- unsigned int trackNumber = 1;
- uint64_t trackID = 0;
- unsigned int pixelWidth = cfg->g_w;
- unsigned int pixelHeight = cfg->g_h;
-
- /* Write the EBML header. */
- Ebml_StartSubElement(glob, &start, EBML);
- Ebml_SerializeUnsigned(glob, EBMLVersion, 1);
- Ebml_SerializeUnsigned(glob, EBMLReadVersion, 1);
- Ebml_SerializeUnsigned(glob, EBMLMaxIDLength, 4);
- Ebml_SerializeUnsigned(glob, EBMLMaxSizeLength, 8);
- Ebml_SerializeString(glob, DocType, "webm");
- Ebml_SerializeUnsigned(glob, DocTypeVersion, 2);
- Ebml_SerializeUnsigned(glob, DocTypeReadVersion, 2);
- Ebml_EndSubElement(glob, &start);
-
- /* Open and begin writing the segment element. */
- Ebml_StartSubElement(glob, &glob->startSegment, Segment);
- glob->position_reference = ftello(glob->stream);
- glob->framerate = *fps;
- write_webm_seek_info(glob);
-
- /* Open and write the Tracks element. */
- glob->track_pos = ftello(glob->stream);
- Ebml_StartSubElement(glob, &trackStart, Tracks);
-
- /* Open and write the Track entry. */
- Ebml_StartSubElement(glob, &start, TrackEntry);
- Ebml_SerializeUnsigned(glob, TrackNumber, trackNumber);
- glob->track_id_pos = ftello(glob->stream);
- Ebml_SerializeUnsigned32(glob, TrackUID, trackID);
- Ebml_SerializeUnsigned(glob, TrackType, 1);
- Ebml_SerializeString(glob, CodecID,
- fourcc == VP8_FOURCC ? "V_VP8" : "V_VP9");
- Ebml_StartSubElement(glob, &videoStart, Video);
- Ebml_SerializeUnsigned(glob, PixelWidth, pixelWidth);
- Ebml_SerializeUnsigned(glob, PixelHeight, pixelHeight);
- Ebml_SerializeUnsigned(glob, StereoMode, stereo_fmt);
- Ebml_EndSubElement(glob, &videoStart);
-
- /* Close Track entry. */
- Ebml_EndSubElement(glob, &start);
-
- /* Close Tracks element. */
- Ebml_EndSubElement(glob, &trackStart);
-
- /* Segment element remains open. */
-}
-
-void write_webm_block(struct EbmlGlobal *glob,
- const vpx_codec_enc_cfg_t *cfg,
- const vpx_codec_cx_pkt_t *pkt) {
- unsigned int block_length;
- unsigned char track_number;
- uint16_t block_timecode = 0;
- unsigned char flags;
- int64_t pts_ms;
- int start_cluster = 0, is_keyframe;
-
- /* Calculate the PTS of this frame in milliseconds. */
- pts_ms = pkt->data.frame.pts * 1000
- * (uint64_t)cfg->g_timebase.num / (uint64_t)cfg->g_timebase.den;
-
- if (pts_ms <= glob->last_pts_ms)
- pts_ms = glob->last_pts_ms + 1;
-
- glob->last_pts_ms = pts_ms;
-
- /* Calculate the relative time of this block. */
- if (pts_ms - glob->cluster_timecode > SHRT_MAX)
- start_cluster = 1;
- else
- block_timecode = (uint16_t)pts_ms - glob->cluster_timecode;
-
- is_keyframe = (pkt->data.frame.flags & VPX_FRAME_IS_KEY);
- if (start_cluster || is_keyframe) {
- if (glob->cluster_open)
- Ebml_EndSubElement(glob, &glob->startCluster);
-
- /* Open the new cluster. */
- block_timecode = 0;
- glob->cluster_open = 1;
- glob->cluster_timecode = (uint32_t)pts_ms;
- glob->cluster_pos = ftello(glob->stream);
- Ebml_StartSubElement(glob, &glob->startCluster, Cluster);
- Ebml_SerializeUnsigned(glob, Timecode, glob->cluster_timecode);
-
- /* Save a cue point if this is a keyframe. */
- if (is_keyframe) {
- struct cue_entry *cue, *new_cue_list;
-
- new_cue_list = realloc(glob->cue_list,
- (glob->cues + 1) * sizeof(struct cue_entry));
- if (new_cue_list)
- glob->cue_list = new_cue_list;
- else
- fatal("Failed to realloc cue list.");
-
- cue = &glob->cue_list[glob->cues];
- cue->time = glob->cluster_timecode;
- cue->loc = glob->cluster_pos;
- glob->cues++;
- }
- }
-
- /* Write the Simple Block. */
- Ebml_WriteID(glob, SimpleBlock);
-
- block_length = (unsigned int)pkt->data.frame.sz + 4;
- block_length |= 0x10000000;
- Ebml_Serialize(glob, &block_length, sizeof(block_length), 4);
-
- track_number = 1;
- track_number |= 0x80;
- Ebml_Write(glob, &track_number, 1);
-
- Ebml_Serialize(glob, &block_timecode, sizeof(block_timecode), 2);
-
- flags = 0;
- if (is_keyframe)
- flags |= 0x80;
- if (pkt->data.frame.flags & VPX_FRAME_IS_INVISIBLE)
- flags |= 0x08;
- Ebml_Write(glob, &flags, 1);
-
- Ebml_Write(glob, pkt->data.frame.buf, (unsigned int)pkt->data.frame.sz);
-}
-
-void write_webm_file_footer(struct EbmlGlobal *glob, int hash) {
- EbmlLoc start_cues;
- EbmlLoc start_cue_point;
- EbmlLoc start_cue_tracks;
- unsigned int i;
-
- if (glob->cluster_open)
- Ebml_EndSubElement(glob, &glob->startCluster);
-
- glob->cue_pos = ftello(glob->stream);
- Ebml_StartSubElement(glob, &start_cues, Cues);
-
- for (i = 0; i < glob->cues; i++) {
- struct cue_entry *cue = &glob->cue_list[i];
- Ebml_StartSubElement(glob, &start_cue_point, CuePoint);
- Ebml_SerializeUnsigned(glob, CueTime, cue->time);
-
- Ebml_StartSubElement(glob, &start_cue_tracks, CueTrackPositions);
- Ebml_SerializeUnsigned(glob, CueTrack, 1);
- Ebml_SerializeUnsigned64(glob, CueClusterPosition,
- cue->loc - glob->position_reference);
- Ebml_EndSubElement(glob, &start_cue_tracks);
-
- Ebml_EndSubElement(glob, &start_cue_point);
- }
-
- Ebml_EndSubElement(glob, &start_cues);
-
- /* Close the Segment. */
- Ebml_EndSubElement(glob, &glob->startSegment);
-
- /* Patch up the seek info block. */
- write_webm_seek_info(glob);
-
- /* Patch up the track id. */
- fseeko(glob->stream, glob->track_id_pos, SEEK_SET);
- Ebml_SerializeUnsigned32(glob, TrackUID, glob->debug ? 0xDEADBEEF : hash);
-
- fseeko(glob->stream, 0, SEEK_END);
-}
diff --git a/webmenc.cc b/webmenc.cc
new file mode 100644
index 000000000..6a3374d02
--- /dev/null
+++ b/webmenc.cc
@@ -0,0 +1,86 @@
+/*
+ * Copyright (c) 2014 The WebM project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+#include "./webmenc.h"
+
+#include <string>
+
+#include "third_party/libwebm/mkvmuxer.hpp"
+#include "third_party/libwebm/mkvmuxerutil.hpp"
+#include "third_party/libwebm/mkvwriter.hpp"
+
+namespace {
+const uint64_t kDebugTrackUid = 0xDEADBEEF;
+const int kVideoTrackNumber = 1;
+} // namespace
+
+void write_webm_file_header(struct EbmlGlobal *glob,
+ const vpx_codec_enc_cfg_t *cfg,
+ const struct vpx_rational *fps,
+ stereo_format_t stereo_fmt,
+ unsigned int fourcc) {
+ mkvmuxer::MkvWriter *const writer = new mkvmuxer::MkvWriter(glob->stream);
+ mkvmuxer::Segment *const segment = new mkvmuxer::Segment();
+ segment->Init(writer);
+ segment->set_mode(mkvmuxer::Segment::kFile);
+ segment->OutputCues(true);
+
+ mkvmuxer::SegmentInfo *const info = segment->GetSegmentInfo();
+ const uint64_t kTimecodeScale = 1000000;
+ info->set_timecode_scale(kTimecodeScale);
+ std::string version = "vpxenc";
+ if (!glob->debug) {
+ version.append(std::string(" ") + vpx_codec_version_str());
+ }
+ info->set_writing_app(version.c_str());
+
+ const int video_track_id = segment->AddVideoTrack(static_cast<int>(cfg->g_w),
+ static_cast<int>(cfg->g_h),
+ kVideoTrackNumber);
+ mkvmuxer::VideoTrack* const video_track =
+ static_cast<mkvmuxer::VideoTrack*>(
+ segment->GetTrackByNumber(video_track_id));
+ video_track->SetStereoMode(stereo_fmt);
+ video_track->set_codec_id(fourcc == VP8_FOURCC ? "V_VP8" : "V_VP9");
+ if (glob->debug) {
+ video_track->set_uid(kDebugTrackUid);
+ }
+ glob->writer = writer;
+ glob->segment = segment;
+}
+
+void write_webm_block(struct EbmlGlobal *glob,
+ const vpx_codec_enc_cfg_t *cfg,
+ const vpx_codec_cx_pkt_t *pkt) {
+ mkvmuxer::Segment *const segment =
+ reinterpret_cast<mkvmuxer::Segment*>(glob->segment);
+ int64_t pts_ns = pkt->data.frame.pts * 1000000000ll *
+ cfg->g_timebase.num / cfg->g_timebase.den;
+ if (pts_ns <= glob->last_pts_ns)
+ pts_ns = glob->last_pts_ns + 1000000;
+ glob->last_pts_ns = pts_ns;
+
+ segment->AddFrame(static_cast<uint8_t*>(pkt->data.frame.buf),
+ pkt->data.frame.sz,
+ kVideoTrackNumber,
+ pts_ns,
+ pkt->data.frame.flags & VPX_FRAME_IS_KEY);
+}
+
+void write_webm_file_footer(struct EbmlGlobal *glob) {
+ mkvmuxer::MkvWriter *const writer =
+ reinterpret_cast<mkvmuxer::MkvWriter*>(glob->writer);
+ mkvmuxer::Segment *const segment =
+ reinterpret_cast<mkvmuxer::Segment*>(glob->segment);
+ segment->Finalize();
+ delete segment;
+ delete writer;
+ glob->writer = NULL;
+ glob->segment = NULL;
+}
diff --git a/webmenc.h b/webmenc.h
index 362aa895f..0ac606be4 100644
--- a/webmenc.h
+++ b/webmenc.h
@@ -13,13 +13,6 @@
#include <stdio.h>
#include <stdlib.h>
-#if defined(_MSC_VER)
-/* MSVS doesn't define off_t */
-typedef __int64 off_t;
-#else
-#include <stdint.h>
-#endif
-
#include "tools_common.h"
#include "vpx/vpx_encoder.h"
@@ -27,40 +20,13 @@ typedef __int64 off_t;
extern "C" {
#endif
-typedef off_t EbmlLoc;
-
-struct cue_entry {
- unsigned int time;
- uint64_t loc;
-};
-
+/* TODO(vigneshv): Rename this struct */
struct EbmlGlobal {
int debug;
-
FILE *stream;
- int64_t last_pts_ms;
- vpx_rational_t framerate;
-
- /* These pointers are to the start of an element */
- off_t position_reference;
- off_t seek_info_pos;
- off_t segment_info_pos;
- off_t track_pos;
- off_t cue_pos;
- off_t cluster_pos;
-
- /* This pointer is to a specific element to be serialized */
- off_t track_id_pos;
-
- /* These pointers are to the size field of the element */
- EbmlLoc startSegment;
- EbmlLoc startCluster;
-
- uint32_t cluster_timecode;
- int cluster_open;
-
- struct cue_entry *cue_list;
- unsigned int cues;
+ int64_t last_pts_ns;
+ void *writer;
+ void *segment;
};
/* Stereo 3D packed frame format */
@@ -72,10 +38,6 @@ typedef enum stereo_format {
STEREO_FORMAT_RIGHT_LEFT = 11
} stereo_format_t;
-void write_webm_seek_element(struct EbmlGlobal *ebml,
- unsigned int id,
- off_t pos);
-
void write_webm_file_header(struct EbmlGlobal *glob,
const vpx_codec_enc_cfg_t *cfg,
const struct vpx_rational *fps,
@@ -86,7 +48,7 @@ void write_webm_block(struct EbmlGlobal *glob,
const vpx_codec_enc_cfg_t *cfg,
const vpx_codec_cx_pkt_t *pkt);
-void write_webm_file_footer(struct EbmlGlobal *glob, int hash);
+void write_webm_file_footer(struct EbmlGlobal *glob);
#ifdef __cplusplus
} // extern "C"