Compare commits

..

87 Commits

Author SHA1 Message Date
Tom Finegan
25025a5471 Add dependency checks to Makefile.
Avoid unfortunate things like breaking the library because the make file
was not previously checking dependencies.

Change-Id: Iab20c3cfa0d1475dfb5c54127646b351df1c4c50
2013-08-19 19:32:37 -07:00
Tom Finegan
f72dc7b052 Ignore dependency files and build products.
Change-Id: I4e9da395b8e06a696e77389d0bc863b8837eceee
2013-08-19 11:02:23 -07:00
Tom Finegan
c5892de23b Fix mkvmuxer::Track::set_uid().
Modifying const variables doesn't work.

Change-Id: Ie1aa9ce1779002973ec93f808ba5e86c569b9df4
2013-08-19 11:01:49 -07:00
Tom Finegan
15a708e416 Add set_uid() to mkvmuxer::Track.
Allow users of libwebm's MKV muxer to control the Track UID. This,
for example, allows creation of tests that rely on checksum comparisons
to verify output from the library.

Change-Id: I8b052e6dd5af734d76122b2a1b6b16382ffba214
2013-08-16 10:58:17 -07:00
Vignesh Venkatasubramanian
8206558561 Handling chunking_ being set to true on repositioning cues.
CopyAndMoveCuesBeforeClusters should return false (fail gracefully)
if chunking_ is set to true.

Change-Id: Idf4d573e3f15b59c25ee0774a7875e5dfda9c02e
2013-06-27 11:30:17 -07:00
Vignesh Venkatasubramanian
d782edd68e Update Segment size if Cues size changes on repositioning
Files created with Segment::CopyAndMoveCuesBeforeClusters can't be parsed by
libwebm because the Segment size was not updated to account for the change
in Cue size. Fixing that.

Change-Id: I993f63e5c279f131cd39c54bee40163da00b8cbd
2013-06-24 11:55:53 -07:00
Vignesh Venkatasubramanian
4ac7b755f4 Repositing Cues before Clusters
A whole new approach to repositioning Cues before Clusters. This
patchset adds a new function CopyAndMoveCuesBeforeClusters to the
Segment class. This function should be called after
Segment::Finalize() to obtain a copy of the same output file with
Cues positioned before the Clusters.

Removing everything else that was added to accomplish the same in
the previous few commits.

Also, adding std:: qualifier to one of the variables in
sample_muxer_metadata which was missed accidentally in the previous
commit.

Change-Id: I2810d06a6251325add2f5e54d32d1da6e2fe143f
2013-06-14 13:01:48 -07:00
Vignesh Venkatasubramanian
09dd90fcc7 Fully qualifiying usage of std::string
Replacing "using std::string" with fully qualified namespace on
each occurance of string in sample_muxer_metadata.cc and
webvttparser.cc.

Also fixing a formatting nit in mkvwriteeofreader.cpp

Change-Id: Icf713f9e489fbdc9af14e83d0cb7ba2e89e65ab4
2013-06-12 11:23:35 -07:00
Vignesh Venkatasubramanian
54ca052b1c Changing IMkvReadableWriter to IMkvWriteEOFReader
Changing the IMkvReadableWriter interface to IMkvWriteEOFReader.
Also changing the default implementation.

Change-Id: Id37ffd7ef0af2ff7a392fb4fb0b1b134664ab20f
2013-06-11 15:11:18 -07:00
Vignesh Venkatasubramanian
74e5f0fa1d Adding mkvreadablewriter
Adding mkvreadablewriter files which was missed from previous commit.

Change-Id: I84363ca897ebe758a42538c179ad60c2adfe9247
2013-06-03 14:26:20 -07:00
Vignesh Venkatasubramanian
9b42d039ad Support for placing Cues before Clusters
Adding support for placing Cues element before the Cluster element. We
recompute the new offsets using a recursive algorithm and update the Cues and
Seek Heads with the updates offsets.

Change-Id: I038f1a403b1defa853b9026bd3e48f4ad1006866
2013-06-03 10:27:27 -07:00
Vignesh Venkatasubramanian
3f7681d11e Merge "Fixing mistyped element name in mkvmuxerutil" 2013-05-20 17:11:11 -07:00
Vignesh Venkatasubramanian
7a64466954 Fixing mistyped element name in mkvmuxerutil
Replacing correct element name in mkvmuxerutil that was mistyped
in a previous commit.

Change-Id: Ic34f544aeeb124f0950c3f45e7b638d4616f8b86
2013-05-20 16:46:33 -07:00
Vignesh Venkatasubramanian
05912e8a96 Merge "Elements and functions to support BlockAdditional" 2013-05-07 14:17:43 -07:00
Patrik2 Carlsson
a9f43fe8e7 mkvparser: Get frame default duration
Track::GetDefaultDuration is implemented as an alternative
to VideoTrack::GetFrameRate which seems to be deprecated.

Change-Id: I2c7a6d56a232125b8632d87eab75b9600c5451e1
2013-05-02 16:04:34 +02:00
Vignesh Venkatasubramanian
5af56bb9ee Elements and functions to support BlockAdditional
Adding elements and functions to support muxing of BlockAdditional element.
This is required for supporting muxing of streams with Alpha Channel (where the
Alpha data goes into BlockAdditional). Detailed design doc of Alpha Channel can
be found here: http://goo.gl/wCP1y

Change-Id: Idac144d9588de16685734850585ab7115ddd08a4
2013-04-24 16:16:14 -07:00
Frank Galligan
64cee42b85 libwebm: Remove STL dependency from Android build.
Change-Id: Id2f378f2fa8350aae97394bd8b21918cff4d179a
2013-04-15 10:24:34 -07:00
Frank Galligan
d5cb6c7fa4 libwebm: Fix random number generation on Android.
Change-Id: I593561128aaeb5806f8f015e2de3b4c9aa4411fc
2013-04-15 09:27:34 -07:00
Frank Galligan
252bd24950 libwebm: Update Android build
- Change to libwebm.
- Add muxer support.
- Remove sample app.

Change-Id: I39c31ecbff573f86214e85b3ac08e0dcdfe22ae2
2013-04-15 09:13:07 -07:00
Michael Szal
9cb9ee4efa Removed IsOpen because it should not have been there.
Change-Id: I4d5149de362e50a8f15ebfd382e39218ca2ca560
2013-03-29 11:44:28 -07:00
Patrik Carlsson
3af8d02ca1 mkvparser: support seek for generic tracks (subtitles)
To support seek in generic tracks with subtitles the audio track
implementation of seek is made generic and inherited by audio track.

Change-Id: Ic88d2e859d077a1054b2af7d7680cfddfba8a589
2013-02-28 15:47:04 +01:00
Patrik Carlsson
0d5b3fc5ae mkvparser: add support for compression elements
ContentCompression elements are now parsed.

Change-Id: I9a67ae444ed929e49c7ea223a16c13c9d16a4c13
2013-02-28 15:46:58 +01:00
Patrik Carlsson
3980cf4159 mkvparser: read track language information
Track::GetLanguageAsUTF8 is implemented to allow the user to
choose between available audio and subtitle tracks.

Change-Id: I5ec9b1c1c00182da759681ba486cbace46e9b63f
2013-02-27 15:40:33 +01:00
Matthew Heaney
1274be1184 libwebm: fixed compilation error
Change-Id: I2dfa93f3a2470e016ca905caee33c3dceb789b57
2013-01-31 14:13:33 -08:00
Matthew Heaney
43178b4c9a libwebm: fixed rand() on windows
Change-Id: Ie17445072f10f91bdaabfba74a1be58764d78b94
2013-01-24 17:29:23 -08:00
Matthew Heaney
8376a8e9d7 mkvparser: liberalize parsing of bad elements
Normally, if a sub-element of a cluster reports a size
that lies beyond the end of its enclosing cluster, we
would treat this as a malformed stream and immediately
terminate the parse.

However, if the sub-element is not a simple block or block
group, we would ignore the (sub)element anyway, so there
doesn't appear to be any harm in just concontinuing to
ignore the (sub)element, and treating this case as if
we had reached the end-of-cluster in the normal way.

Change-Id: I16c0a44f7458823ed579612d917b09ee08a8d90a
2013-01-10 19:24:21 -08:00
David Schalig
2b09f9b53a mkvparser: ignore 0-size elements in TrackEntry
ParseTrackEntry handled MKVs with 0-sized EBML elements
as malformed. Relaxing this and allow empty elements to allow
parsing such MKV content.

Change-Id: I7e430e9b2d177df7fe1e656546f63ee8673e784e
2012-12-11 17:08:22 +09:00
Matthew Heaney
28222b4927 Add support for WebVTT cue identifier line
Modified the mkvmuxer to write the ChapterStringUID
sub-element of the Chapter Atom element.

Modified the mkvparser to read the ChapterStringUID
sub-element of the chapter atom.

Modified the vttdemux app to write the Cue Identifier
line of the WebVTT cue.

Change-Id: I06fe386f44897ada3fe10cbf89096df104dcf779
2012-11-13 12:44:06 -08:00
Matthew Heaney
0fcf5e5a40 Merge "vttdemux: add support for WebVTT chapters" 2012-11-13 09:38:29 -08:00
Matthew Heaney
c26db03d5a vttdemux: add support for WebVTT chapters
Change-Id: If5e12ff7057ce4217907ef91d493e1bcd8a72656
2012-11-12 11:52:15 -08:00
Frank Galligan
baefebcf1c libwebm: Fix BlockNumber on CuePoint
- libwebm was writing the BlockNumber of the next Block instead
  of the Block that was just written.

Change-Id: I344800fcea919a82d7f0a04a54cf510be3851ec6
2012-11-12 08:35:39 -08:00
Matthew Heaney
386928d8b8 mkvparser: add missing definitions
Change-Id: I043a6d974bdf146a8726d090722159943eb20752
2012-11-08 18:12:30 -08:00
Matthew Heaney
50ee255b8c mkvparser: add support for MKV chapters
Change-Id: I2404b6886ed592fe505ee973bf05c769a9d134b1
2012-11-02 14:42:40 -07:00
Matthew Heaney
ad54bfb572 sample_muxer: added support for WebVTT chapters
Change-Id: Ic5ab8097c0981ef300eadc4a3c151f63b2aad81d
2012-11-02 14:20:43 -07:00
Matthew Heaney
c99838a5fe Merge "mkvmuxer: add support for WebVTT chapters" 2012-10-31 18:03:59 -07:00
Matthew Heaney
2c5836837e mkvmuxer: add support for WebVTT chapters
Change-Id: I469ce3bd79a9b50b82e00ac8c63fc3d1db220887
2012-10-30 17:07:38 -07:00
Frank Galligan
50afbea946 muxer: Add support to force Cluster placement.
Change-Id: I7d4653561ca760885ba6926825ba6b80cdbea8ab
2012-10-29 09:24:41 -07:00
Matthew Heaney
25ee621061 mkvmuxer: add MakeUID utility function
Change-Id: I3fb57438767ddcc8f9e17c050d494f48ff203e58
2012-10-22 16:50:48 -07:00
Matthew Heaney
ac238c0c5c webvttparser: check intermediate values while parsing int
Change-Id: I145529097246f75c27ff2d29cf091416ba1c437d
2012-10-16 11:32:42 -07:00
Matthew Heaney
4a5141344e vttdemux: initial revision
vttdemux is a tool for demuxing a webm file containing
WebVTT metadata tracks, extracting the embedded metadata
from each track and storing it as a standalone WebVTT file.

Change-Id: I8897b3dc502c49c92f5b79925939baa5a9490aaa
2012-10-12 11:00:24 -07:00
Matthew Heaney
2fc496a0d6 mkvparser: create generic track objects
Formerly, it was only possible to create instances of
the Track subclasses, VideoTrack and AudioTrack.  However,
we now populate WebM files with WebVTT metadata blocks,
so we must allow for a third kind of track object.

We now enable instances of type Track to be created,
by providing a new factory function, Track::Create, and
making all Track methods non-pure and with a generic
implementation.

Change-Id: I7d4c965eb566b9fc2f5ceefe1d43723cf8c1e5f0
2012-10-10 16:51:21 -07:00
Matthew Heaney
cb8899a920 sample_muxer: clean-up to conform to style guide
Change-Id: I77a4657d71359777a8f55f40346014f90051e02d
2012-10-08 12:52:55 -07:00
Matthew Heaney
49078292b4 webvttparser: added LineReader class
Previously the Parser class had an internal function to parse
the character stream into separate lines.  This functionality
was separated out into its own class, LineReader, in order
to make this functionality available to clients too.

Change-Id: Ic5a1b0b73d7a253cf21cb6b4804b4941fd69c8ab
2012-10-02 18:14:51 -07:00
Matthew Heaney
4f494f6dd4 mkvparser: implemented BlockGroup::GetDuration method
Change-Id: Ib0106df3823c29e45a8fe59669c0fa65dd13a123
2012-09-28 14:55:24 -07:00
Matthew Heaney
7ef225de9f sample_muxer: added WebVTT support
Change-Id: If72d31ca4828adf39e4637003979a314e5dda98e
2012-09-28 10:38:19 -07:00
Frank Galligan
8f0c3333d1 Merge "mkvparser: Version 1.0.0.26 mkvmuxer: Version 0.2.0.0" 2012-09-27 10:06:58 -07:00
Frank Galligan
bf664baf05 mkvparser: Version 1.0.0.26 mkvmuxer: Version 0.2.0.0
Change-Id: I6875b1c10adea41c45762d82b7dd2f9551f5b7ca
2012-09-27 09:56:24 -07:00
James Zern
232bae0d50 Merge "Added a rule to the Makefile to build libwebm as a shared library." 2012-09-26 13:37:17 -07:00
Michael Szal
69c9348f07 Added a rule to the Makefile to build libwebm as a shared
library.

I'm building two different object files now: the ones for
libwebm.a are compiled normally (*_a.o), and the ones for
libwebm.so are compiled with -fPIC and linked with -shared
(*_so.o).

Change-Id: I76471ab225a006c7e169bc0d69df9a0731ff6681
2012-09-26 13:15:10 -07:00
Matthew Heaney
711af0c505 mkvmuxer: add operations for muxing metadata
Change-Id: Ia17166ee9133b4841f7d206aa7d5ec81f800e994
2012-09-24 12:13:45 -07:00
Matthew Heaney
38173f9d49 add operation to add generic track
Change-Id: I34e4ab14c0a5b022b77b98d9403125550024e730
2012-09-21 16:37:30 -07:00
Frank Galligan
21a2bd14c7 Make AddCuePoint function public.
Change-Id: I08df2b604185d6ae1d63eb360e68e84efa2cebfa
2012-09-21 16:21:03 -07:00
Frank Galligan
9ec562f72d Add Track number to AddCuePoint function.
Change-Id: I67fd8db3d436f8931f5d50deeb1f1d41cfdc0836
2012-09-21 15:42:57 -07:00
Frank Galligan
e6e2b6b387 Merge "Fix set_writing_app." 2012-09-21 14:08:43 -07:00
Frank Galligan
a2ca300513 Merge "mkvmuxer: default track_num to 0 in AddTrack" 2012-09-21 14:08:08 -07:00
Frank Galligan
6cf00207c0 Fix set_writing_app.
Change-Id: Idbb0522b10184072802be710088f0ec0bf008277
2012-09-21 12:20:43 -07:00
Frank Galligan
4df02ce68b libwebm: Add support for setting muxing app.
Change-Id: I78f4d08142aeeaacf5f9c175bab6a4993b917b1b
2012-09-21 12:17:03 -07:00
Matthew Heaney
4ffb162798 mkvmuxer: default track_num to 0 in AddTrack
Change-Id: I484cb56df7be7677a821db262c75cf8bdf1d30af
2012-09-21 11:55:47 -07:00
Matthew Heaney
76d9cf9cf4 mkvmuxer: handle large gaps in frame timestamps
Change-Id: If223a03cc37f2f373893c914e417475f62949717
2012-09-20 14:58:45 -07:00
Frank Galligan
20f64ff979 Merge "Fix incremental parsing in CreateInstance" 2012-09-14 11:18:27 -07:00
Frank Galligan
537da82f37 Fix incremental parsing in CreateInstance
- Segment::CreateInstance was treating the available data as EOF
  and returning errors.
- Added a check for potential underflow if the segment was not the
  first element after the EBML header.

Change-Id: I481bf0eea71eeb3def3bf54ec251be0b2ae13536
2012-09-14 11:05:18 -07:00
Matthew Heaney
db20aaa2b1 mkvmuxer: refactored code that creates a new cluster
Change-Id: I5db03b0e1ea23f45820dd47b7be9e4b0422f3e6a
2012-09-14 10:17:09 -07:00
Matthew Heaney
c9e284b9e7 refactor code to make a new cluster
Change-Id: Ifa7938134494e3524d6479bd026aea6d1b309d52
2012-09-13 10:15:59 -07:00
Matthew Heaney
07ac1947f0 Change return type of Segment::WriteFramesAll()
Change-Id: I7fb45f1779c384bcc1cdea507f1f2f51c28dd827
2012-09-12 10:29:40 -07:00
Matthew Heaney
0edf087bbb Refactor Cluster::AddFrame member function
Change-Id: Ibff460918243647eb76785508bb50490bc1d8561
2012-09-11 14:58:56 -07:00
Matthew Heaney
c425e965aa add operation to write metadata block
Change-Id: I08f6c7f71dbc9b0d9ce15c08cf288f4918b2c22a
2012-09-05 15:44:45 -07:00
Matthew Heaney
ed6282b2d6 webvttparser more closely conforms to style rules
A few adjustments we made such that the webvttparser
now conforms more closely to the Google C++ style guide.

Change-Id: Iefb2242678ceea6ab5b9daa3a046980deb6cd91c
2012-08-30 15:24:20 -07:00
Matthew Heaney
282a67599c added dumpvtt app
Change-Id: I9eba00412bbd05641dafd1a6cfc4656bda8bb8c2
2012-08-23 14:00:57 -07:00
Matthew Heaney
adebb53754 added webvtt parser
Change-Id: Icef6d484e8fe6e2c63dc69ab02b6ab37ffcabbd8
2012-08-16 16:39:07 -07:00
Frank Galligan
a320f5be63 Add CTR encryption.
- Added ContentEncAESSettings, AESSettingsCipherMode,
  AESSettingsCipherInitData elements to the parser and muxer.
- Changed ParseContentEncodingsEntry, ParseContentEncodingEntry,
  and ParseEncryptionEntry to use PasreElementHeader.
- Added ParseContentEncAESSettingsEntry function.
- PS6 removed AESSettingsCipherInitData.
- PS9 Addressed comments, Fixed some LINT issues, and converted
  mkvwriter.h/.cpp to Unix line endings.
- PS10 Addressed comments.

Change-Id: I9d96a0c194f74a6c9bf0001aa0286196e410f07e
2012-07-27 09:34:31 -07:00
Frank Galligan
c4d2b27b7a Add support for DLL configurations.
- Added "Release DLL" which uses /MTd and "Debug DLL" which
  uses /MDd.

Change-Id: Ibdaf58995e5ee94c34d52ece64e2f8f01524e9cd
2012-07-25 08:41:01 -07:00
Frank Galligan
13a90600ea Muxer fix for chunking file names on Linux.
Change-Id: Ica2dbfc7af64a83fc8f08d35196eabf1dd69f2f0
2012-07-12 08:01:55 -07:00
matthewjheaney
478b524df3 version 1.0.0.25
Change-Id: I438d43572f450bb6e151d4a1ede077ff22252d1f
2012-05-30 15:42:33 -04:00
Tom Finegan
010a457bc9 Add Visual Studio 2010 projects and solution.
Change-Id: I6387f1e6d68b05b8f605f155784c1025f85c1a5b
2012-05-30 14:18:23 -04:00
Tom Finegan
47a09523b2 Ignore visual studio 2010 temporary files.
Change-Id: I18d214b5ba032ff71af2fa67e72a92715636513c
2012-05-30 14:18:22 -04:00
Tom Finegan
84bf4a41dc Move build output outside the repository directory.
Change vs2008 output and intermediate directories to:
1. Avoid build output collisions when using vs2008 and vs2010 on the
   same system (makes no difference until subsequent commit adding
   vs2010 support).
2. Keep the tree clean.

Change-Id: Ie819e57421b7df90244eebffc0f5e608bc135930
2012-05-30 14:18:22 -04:00
Tom Finegan
177df33d25 Move the muxer sample source file and project.
They now reside in the same place as the parser sample.

Change-Id: Idb4471ea81a3d91eeeaf1b36053187203de9a21f
2012-05-30 14:18:08 -04:00
Tom Finegan
4fff53441d Remove visual studio 2005 projects and solution.
Change-Id: I1d4d8cffeb8997eee415246753ea3c29c1af45ec
2012-05-30 11:36:31 -04:00
Tom Finegan
ca13a5bae0 Rename sample_muxer.vcproj to sample_muxer_2008.vcproj.
Also update the solution file path to the project.

Change-Id: I7e83b99893bcde5429e6de03772c61369b29d332
2012-05-29 10:55:00 -04:00
Tom Finegan
cb69e608b4 Enable auto CRLF for visual studio project and solution files.
Change-Id: I23ca85442173eec7a144c001080ca8a3b41609f3
2012-05-29 10:45:59 -04:00
Tom Finegan
f6b0408aba Use LF as EoL in visual studio solutions and projects.
Makes files easier to read in gitweb, and prevents conflict with
upcoming .gitattributes change.

Change-Id: I185e496d8df8efb4987bfb848a582f7d0da81fb8
2012-05-29 10:43:40 -04:00
matthewjheaney
9a561ab4dd libwebm: handle negative time for a block
Change-Id: Iafa0254fb1554621b42635cb99d40b2c0177468f
2012-05-11 11:53:23 -04:00
Frank Galligan
0568dd63a6 Memory Leak Fix in Muxer.
- Track language_ and name_ member variables were not properly
  deleted.
- http://code.google.com/p/webm/issues/detail?id=416

Change-Id: Id0da669c347270cd355ad0b5e1e45ebf6415e367
2012-04-17 15:28:28 -04:00
Frank Galligan
56488f73ef Merge "sample_muxer: Fixed bug with outputting audio cues." 2012-03-16 08:06:54 -07:00
Frank Galligan
f270ddaeb8 sample_muxer: Fixed bug with outputting audio cues.
- For muxed content with default settings the cues was getting
  output on the audio track when it should be on the video track
  by default.
- Added check to command line parameter parsing to make sure
  there are enough parameters.
- If Cues are set to output on one type of track the other type
  is now disabled.

Change-Id: I96ef1978dc3f442f34364f6dee6cfb01571c7289
2012-03-16 09:26:28 -04:00
matthewjheaney
041a5c5811 Parse headers outside of constructor
In several cases, the parser would parse a header
(say, a track header, or the segment info header)
in the constructor for the type.  The parser had
assumed (incorrectly) that the file was well-formed,
but this turned out to be an incorrect assumption.

The parse errors triggered some assertion failures,
but this is not acceptable in a production system.

The parser solved that problem by separating the
construction of the header object from the parsing
of the file.  There is now a separate parse method
to be called after construction of the object,
which returns a status whether the parse was
successful.

This change fixes the bugs from the following
tracker issues:

http://code.google.com/p/webm/issues/detail?id=399
http://code.google.com/p/webm/issues/detail?id=400

Change-Id: Idb09154ae7008429d8613ce3b3e8294f5a12de86
2012-03-13 14:40:17 -04:00
matthewjheaney
6fa7c7611c Block parsing is now robust
Previously, parsing of a Block element was done inside its
constructor.  Parsing errors were handled via assertion checks,
but this only works in practice if there are no actual errors
in the file.

We did come across a file, however, that used EMBL-style lacing,
but the lacing was done incorrectly and so the parse asserted.
This isn't acceptable for a production system, and more a graceful
handling of parse errors was needed.

The code was restructured such that the Block object's ctor does
only trivial initialization of member variables.  A separate Parse
method was added, that is called after the object is constructed.
If the parse succeeds all is well, otherwise the object is destroyed
and the error is reported to the caller.

This commit fixes bug tracker issue #398, described here:

http://code.google.com/p/webm/issues/detail?id=398

Change-Id: Ib95ca95d0eec08cf670b308c461e42ed8345e890
2012-02-28 14:03:21 -05:00
39 changed files with 9194 additions and 3506 deletions

4
.gitattributes vendored Normal file
View File

@@ -0,0 +1,4 @@
*.sln eol=crlf
*.vcproj eol=crlf
*.vsprops eol=crlf
*.vcxproj eol=crlf

10
.gitignore vendored
View File

@@ -2,6 +2,7 @@
*.MKV
core
*.a
*.d
*.so*
*.o
*~
@@ -12,4 +13,11 @@ core
*.exe
*.webm
Debug
Release
Release
*.sdf
*.opensdf
ipch
dumpvtt
sample
samplemuxer
vttdemux

View File

@@ -1,13 +1,10 @@
LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE:= libmkvparser
LOCAL_MODULE:= libwebm
LOCAL_SRC_FILES:= mkvparser.cpp \
mkvreader.cpp
mkvreader.cpp \
mkvmuxer.cpp \
mkvmuxerutil.cpp \
mkvwriter.cpp
include $(BUILD_STATIC_LIBRARY)
include $(CLEAR_VARS)
LOCAL_MODULE:= mkvparser
LOCAL_SRC_FILES:= sample.cpp
LOCAL_STATIC_LIBRARIES:= libmkvparser
include $(BUILD_EXECUTABLE)

View File

@@ -1,25 +1,53 @@
CXX := g++
CXXFLAGS := -W -Wall -g
LIBWEBM := libwebm.a
WEBMOBJS := mkvparser.o mkvreader.o mkvmuxer.o mkvmuxerutil.o mkvwriter.o
OBJECTS1 := $(PARSEOBJ) sample.o
OBJECTS2 := $(PARSEOBJ) $(MUXEROBJ) sample_muxer/sample_muxer.o
INCLUDES := -I.
EXES := samplemuxer sample
CXX := g++
CXXFLAGS := -W -Wall -g -MMD -MP
LIBWEBMA := libwebm.a
LIBWEBMSO := libwebm.so
WEBMOBJS := mkvparser.o mkvreader.o mkvmuxer.o mkvmuxerutil.o mkvwriter.o
OBJSA := $(WEBMOBJS:.o=_a.o)
OBJSSO := $(WEBMOBJS:.o=_so.o)
OBJECTS1 := sample.o
OBJECTS2 := sample_muxer.o vttreader.o webvttparser.o sample_muxer_metadata.o
OBJECTS3 := dumpvtt.o vttreader.o webvttparser.o
OBJECTS4 := vttdemux.o webvttparser.o
INCLUDES := -I.
DEPS := $(WEBMOBJS:.o=.d) $(OBJECTS1:.o=.d) $(OBJECTS2:.o=.d)
DEPS += $(OBJECTS3:.o=.d) $(OBJECTS4:.o=.d)
EXES := samplemuxer sample dumpvtt vttdemux
all: $(EXES)
sample: sample.o $(LIBWEBM)
sample: sample.o $(LIBWEBMA)
$(CXX) $^ -o $@
samplemuxer: sample_muxer/sample_muxer.o $(LIBWEBM)
samplemuxer: $(OBJECTS2) $(LIBWEBMA)
$(CXX) $^ -o $@
libwebm.a: $(WEBMOBJS)
dumpvtt: $(OBJECTS3)
$(CXX) $^ -o $@
shared: $(LIBWEBMSO)
vttdemux: $(OBJECTS4) $(LIBWEBMA)
$(CXX) $^ -o $@
libwebm.a: $(OBJSA)
$(AR) rcs $@ $^
libwebm.so: $(OBJSSO)
$(CXX) $(CXXFLAGS) -shared $(OBJSSO) -o $(LIBWEBMSO)
%.o: %.cpp
$(CXX) -c $(CXXFLAGS) $(INCLUDES) $< -o $@
%_a.o: %.cpp
$(CXX) -c $(CXXFLAGS) $(INCLUDES) $< -o $@
%_so.o: %.cpp
$(CXX) -c $(CXXFLAGS) -fPIC $(INCLUDES) $< -o $@
clean:
$(RM) -f $(OBJECTS1) $(OBJECTS2) $(WEBMOBJS) $(LIBWEBM) $(EXES) Makefile.bak
$(RM) -f $(OBJECTS1) $(OBJECTS2) $(OBJECTS3) $(OBJECTS4) $(OBJSA) $(OBJSSO) $(LIBWEBMA) $(LIBWEBMSO) $(EXES) $(DEPS) Makefile.bak
ifneq ($(MAKECMDGOALS), clean)
-include $(DEPS)
endif

98
dumpvtt.cc Normal file
View File

@@ -0,0 +1,98 @@
// Copyright (c) 2012 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 <cstdio>
#include <cstdlib>
#include "./vttreader.h"
#include "./webvttparser.h"
int main(int argc, const char* argv[]) {
if (argc != 2) {
fprintf(stdout, "usage: dumpvtt <vtt file>\n");
return EXIT_SUCCESS;
}
libwebvtt::VttReader reader;
const char* const filename = argv[1];
if (int e = reader.Open(filename)) {
(void)e;
fprintf(stderr, "open failed\n");
return EXIT_FAILURE;
}
libwebvtt::Parser parser(&reader);
if (int e = parser.Init()) {
(void)e;
fprintf(stderr, "parser init failed\n");
return EXIT_FAILURE;
}
for (libwebvtt::Cue cue;;) {
const int e = parser.Parse(&cue);
if (e < 0) { // error
fprintf(stderr, "error parsing cue\n");
return EXIT_FAILURE;
}
if (e > 0) // EOF
return EXIT_SUCCESS;
fprintf(stdout, "cue identifier: \"%s\"\n", cue.identifier.c_str());
const libwebvtt::Time& st = cue.start_time;
fprintf(stdout, "cue start time: \"HH=%i MM=%i SS=%i SSS=%i\"\n",
st.hours,
st.minutes,
st.seconds,
st.milliseconds);
const libwebvtt::Time& sp = cue.stop_time;
fprintf(stdout, "cue stop time: \"HH=%i MM=%i SS=%i SSS=%i\"\n",
sp.hours,
sp.minutes,
sp.seconds,
sp.milliseconds);
{
typedef libwebvtt::Cue::settings_t::const_iterator iter_t;
iter_t i = cue.settings.begin();
const iter_t j = cue.settings.end();
if (i == j) {
fprintf(stdout, "cue setting: <no settings present>\n");
} else {
while (i != j) {
const libwebvtt::Setting& setting = *i++;
fprintf(stdout, "cue setting: name=%s value=%s\n",
setting.name.c_str(),
setting.value.c_str());
}
}
}
{
typedef libwebvtt::Cue::payload_t::const_iterator iter_t;
iter_t i = cue.payload.begin();
const iter_t j = cue.payload.end();
int idx = 1;
while (i != j) {
const std::string& payload = *i++;
const char* const payload_str = payload.c_str();
fprintf(stdout, "cue payload[%i]: \"%s\"\n", idx, payload_str);
++idx;
}
}
fprintf(stdout, "\n");
fflush(stdout);
}
}

View File

@@ -1,37 +0,0 @@

Microsoft Visual Studio Solution File, Format Version 9.00
# Visual Studio 2005
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libwebm", "libwebm_2005.vcproj", "{F9128EC6-C008-41AD-B38F-0E70D549D9F4}"
ProjectSection(WebsiteProperties) = preProject
Debug.AspNetCompiler.Debug = "True"
Release.AspNetCompiler.Debug = "False"
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "sample", "sample_2005.vcproj", "{0CB5681F-6065-490C-98C8-05531732ED7E}"
ProjectSection(ProjectDependencies) = postProject
{F9128EC6-C008-41AD-B38F-0E70D549D9F4} = {F9128EC6-C008-41AD-B38F-0E70D549D9F4}
EndProjectSection
ProjectSection(WebsiteProperties) = preProject
Debug.AspNetCompiler.Debug = "True"
Release.AspNetCompiler.Debug = "False"
EndProjectSection
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Win32 = Debug|Win32
Release|Win32 = Release|Win32
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{F9128EC6-C008-41AD-B38F-0E70D549D9F4}.Debug|Win32.ActiveCfg = Debug|Win32
{F9128EC6-C008-41AD-B38F-0E70D549D9F4}.Debug|Win32.Build.0 = Debug|Win32
{F9128EC6-C008-41AD-B38F-0E70D549D9F4}.Release|Win32.ActiveCfg = Release|Win32
{F9128EC6-C008-41AD-B38F-0E70D549D9F4}.Release|Win32.Build.0 = Release|Win32
{0CB5681F-6065-490C-98C8-05531732ED7E}.Debug|Win32.ActiveCfg = Debug|Win32
{0CB5681F-6065-490C-98C8-05531732ED7E}.Debug|Win32.Build.0 = Debug|Win32
{0CB5681F-6065-490C-98C8-05531732ED7E}.Release|Win32.ActiveCfg = Release|Win32
{0CB5681F-6065-490C-98C8-05531732ED7E}.Release|Win32.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal

View File

@@ -1,204 +0,0 @@
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="8.00"
Name="libwebm"
ProjectGUID="{F9128EC6-C008-41AD-B38F-0E70D549D9F4}"
RootNamespace="mkvparser"
Keyword="Win32Proj"
>
<Platforms>
<Platform
Name="Win32"
/>
</Platforms>
<ToolFiles>
</ToolFiles>
<Configurations>
<Configuration
Name="Debug|Win32"
OutputDirectory="$(SolutionDir)$(ConfigurationName)"
IntermediateDirectory="$(ConfigurationName)"
ConfigurationType="4"
UseOfMFC="0"
CharacterSet="1"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
PreprocessorDefinitions="WIN32;_DEBUG;_LIB"
MinimalRebuild="false"
BasicRuntimeChecks="3"
RuntimeLibrary="1"
UsePrecompiledHeader="0"
WarningLevel="3"
Detect64BitPortabilityProblems="true"
DebugInformationFormat="1"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLibrarianTool"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
<Configuration
Name="Release|Win32"
OutputDirectory="$(SolutionDir)$(ConfigurationName)"
IntermediateDirectory="$(ConfigurationName)"
ConfigurationType="4"
CharacterSet="1"
WholeProgramOptimization="1"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
PreprocessorDefinitions="WIN32;NDEBUG;_LIB"
RuntimeLibrary="0"
UsePrecompiledHeader="0"
WarningLevel="3"
Detect64BitPortabilityProblems="true"
DebugInformationFormat="1"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLibrarianTool"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
</Configurations>
<References>
</References>
<Files>
<Filter
Name="Source Files"
Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
>
<File
RelativePath=".\mkvmuxerutil.cpp"
>
</File>
<File
RelativePath=".\mkvparser.cpp"
>
</File>
<File
RelativePath=".\mkvreader.cpp"
>
</File>
<File
RelativePath=".\mkvwriter.cpp"
>
</File>
</Filter>
<Filter
Name="Header Files"
Filter="h;hpp;hxx;hm;inl;inc;xsd"
UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
>
<File
RelativePath=".\mkvmuxer.hpp"
>
</File>
<File
RelativePath=".\mkvmuxertypes.hpp"
>
</File>
<File
RelativePath=".\mkvmuxerutil.hpp"
>
</File>
<File
RelativePath=".\mkvparser.hpp"
>
</File>
<File
RelativePath=".\mkvreader.hpp"
>
</File>
<File
RelativePath=".\mkvwriter.hpp"
>
</File>
<File
RelativePath=".\webmids.hpp"
>
</File>
</Filter>
</Files>
<Globals>
</Globals>
</VisualStudioProject>

View File

@@ -1,38 +1,38 @@

Microsoft Visual Studio Solution File, Format Version 10.00
# Visual Studio 2008
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "sample", "sample_2008.vcproj", "{0CB5681F-6065-490C-98C8-05531732ED7E}"
ProjectSection(ProjectDependencies) = postProject
{7B1F12CA-0724-430B-B61A-1D357C912CBA} = {7B1F12CA-0724-430B-B61A-1D357C912CBA}
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libwebm", "libwebm_2008.vcproj", "{7B1F12CA-0724-430B-B61A-1D357C912CBA}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "sample_muxer", "sample_muxer\sample_muxer.vcproj", "{B407561F-1F5E-4798-B9C2-81AB09CFBC16}"
ProjectSection(ProjectDependencies) = postProject
{7B1F12CA-0724-430B-B61A-1D357C912CBA} = {7B1F12CA-0724-430B-B61A-1D357C912CBA}
EndProjectSection
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Win32 = Debug|Win32
Release|Win32 = Release|Win32
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{0CB5681F-6065-490C-98C8-05531732ED7E}.Debug|Win32.ActiveCfg = Debug|Win32
{0CB5681F-6065-490C-98C8-05531732ED7E}.Debug|Win32.Build.0 = Debug|Win32
{0CB5681F-6065-490C-98C8-05531732ED7E}.Release|Win32.ActiveCfg = Release|Win32
{0CB5681F-6065-490C-98C8-05531732ED7E}.Release|Win32.Build.0 = Release|Win32
{7B1F12CA-0724-430B-B61A-1D357C912CBA}.Debug|Win32.ActiveCfg = Debug|Win32
{7B1F12CA-0724-430B-B61A-1D357C912CBA}.Debug|Win32.Build.0 = Debug|Win32
{7B1F12CA-0724-430B-B61A-1D357C912CBA}.Release|Win32.ActiveCfg = Release|Win32
{7B1F12CA-0724-430B-B61A-1D357C912CBA}.Release|Win32.Build.0 = Release|Win32
{B407561F-1F5E-4798-B9C2-81AB09CFBC16}.Debug|Win32.ActiveCfg = Debug|Win32
{B407561F-1F5E-4798-B9C2-81AB09CFBC16}.Debug|Win32.Build.0 = Debug|Win32
{B407561F-1F5E-4798-B9C2-81AB09CFBC16}.Release|Win32.ActiveCfg = Release|Win32
{B407561F-1F5E-4798-B9C2-81AB09CFBC16}.Release|Win32.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal

Microsoft Visual Studio Solution File, Format Version 10.00
# Visual Studio 2008
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "sample", "sample_2008.vcproj", "{0CB5681F-6065-490C-98C8-05531732ED7E}"
ProjectSection(ProjectDependencies) = postProject
{7B1F12CA-0724-430B-B61A-1D357C912CBA} = {7B1F12CA-0724-430B-B61A-1D357C912CBA}
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libwebm", "libwebm_2008.vcproj", "{7B1F12CA-0724-430B-B61A-1D357C912CBA}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "sample_muxer", "sample_muxer_2008.vcproj", "{B407561F-1F5E-4798-B9C2-81AB09CFBC16}"
ProjectSection(ProjectDependencies) = postProject
{7B1F12CA-0724-430B-B61A-1D357C912CBA} = {7B1F12CA-0724-430B-B61A-1D357C912CBA}
EndProjectSection
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Win32 = Debug|Win32
Release|Win32 = Release|Win32
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{0CB5681F-6065-490C-98C8-05531732ED7E}.Debug|Win32.ActiveCfg = Debug|Win32
{0CB5681F-6065-490C-98C8-05531732ED7E}.Debug|Win32.Build.0 = Debug|Win32
{0CB5681F-6065-490C-98C8-05531732ED7E}.Release|Win32.ActiveCfg = Release|Win32
{0CB5681F-6065-490C-98C8-05531732ED7E}.Release|Win32.Build.0 = Release|Win32
{7B1F12CA-0724-430B-B61A-1D357C912CBA}.Debug|Win32.ActiveCfg = Debug|Win32
{7B1F12CA-0724-430B-B61A-1D357C912CBA}.Debug|Win32.Build.0 = Debug|Win32
{7B1F12CA-0724-430B-B61A-1D357C912CBA}.Release|Win32.ActiveCfg = Release|Win32
{7B1F12CA-0724-430B-B61A-1D357C912CBA}.Release|Win32.Build.0 = Release|Win32
{B407561F-1F5E-4798-B9C2-81AB09CFBC16}.Debug|Win32.ActiveCfg = Debug|Win32
{B407561F-1F5E-4798-B9C2-81AB09CFBC16}.Debug|Win32.Build.0 = Debug|Win32
{B407561F-1F5E-4798-B9C2-81AB09CFBC16}.Release|Win32.ActiveCfg = Release|Win32
{B407561F-1F5E-4798-B9C2-81AB09CFBC16}.Release|Win32.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal

View File

@@ -1,209 +1,210 @@
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="9.00"
Name="libwebm"
ProjectGUID="{7B1F12CA-0724-430B-B61A-1D357C912CBA}"
RootNamespace="libwebm"
Keyword="Win32Proj"
TargetFrameworkVersion="196613"
>
<Platforms>
<Platform
Name="Win32"
/>
</Platforms>
<ToolFiles>
</ToolFiles>
<Configurations>
<Configuration
Name="Debug|Win32"
OutputDirectory="$(SolutionDir)$(ConfigurationName)"
IntermediateDirectory="$(ConfigurationName)"
ConfigurationType="4"
CharacterSet="1"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
PreprocessorDefinitions="WIN32;_DEBUG;_LIB"
MinimalRebuild="false"
BasicRuntimeChecks="3"
RuntimeLibrary="1"
UsePrecompiledHeader="0"
WarningLevel="4"
DebugInformationFormat="1"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLibrarianTool"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
<Configuration
Name="Release|Win32"
OutputDirectory="$(SolutionDir)$(ConfigurationName)"
IntermediateDirectory="$(ConfigurationName)"
ConfigurationType="4"
CharacterSet="1"
WholeProgramOptimization="1"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
Optimization="2"
EnableIntrinsicFunctions="true"
PreprocessorDefinitions="WIN32;NDEBUG;_LIB"
RuntimeLibrary="0"
EnableFunctionLevelLinking="true"
UsePrecompiledHeader="0"
WarningLevel="4"
DebugInformationFormat="1"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLibrarianTool"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
</Configurations>
<References>
</References>
<Files>
<Filter
Name="Source Files"
Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
>
<File
RelativePath=".\mkvmuxer.cpp"
>
</File>
<File
RelativePath=".\mkvmuxerutil.cpp"
>
</File>
<File
RelativePath=".\mkvparser.cpp"
>
</File>
<File
RelativePath=".\mkvreader.cpp"
>
</File>
<File
RelativePath=".\mkvwriter.cpp"
>
</File>
</Filter>
<Filter
Name="Header Files"
Filter="h;hpp;hxx;hm;inl;inc;xsd"
UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
>
<File
RelativePath=".\mkvmuxer.hpp"
>
</File>
<File
RelativePath=".\mkvmuxertypes.hpp"
>
</File>
<File
RelativePath=".\mkvmuxerutil.hpp"
>
</File>
<File
RelativePath=".\mkvparser.hpp"
>
</File>
<File
RelativePath=".\mkvreader.hpp"
>
</File>
<File
RelativePath=".\mkvwriter.hpp"
>
</File>
<File
RelativePath=".\webmids.hpp"
>
</File>
</Filter>
</Files>
<Globals>
</Globals>
</VisualStudioProject>
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="9.00"
Name="libwebm"
ProjectGUID="{7B1F12CA-0724-430B-B61A-1D357C912CBA}"
RootNamespace="libwebm"
Keyword="Win32Proj"
TargetFrameworkVersion="196613"
>
<Platforms>
<Platform
Name="Win32"
/>
</Platforms>
<ToolFiles>
</ToolFiles>
<Configurations>
<Configuration
Name="Debug|Win32"
OutputDirectory="$(ProjectDir)..\lib\libwebm_2008\$(ProjectName)\$(PlatformName)\$(ConfigurationName)"
IntermediateDirectory="$(ProjectDir)..\obj\libwebm_2008\$(ProjectName)\$(PlatformName)\$(ConfigurationName)"
ConfigurationType="4"
CharacterSet="1"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
PreprocessorDefinitions="WIN32;_DEBUG;_LIB"
MinimalRebuild="false"
BasicRuntimeChecks="3"
RuntimeLibrary="1"
UsePrecompiledHeader="0"
WarningLevel="4"
DebugInformationFormat="1"
DisableSpecificWarnings="4996"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLibrarianTool"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
<Configuration
Name="Release|Win32"
OutputDirectory="$(ProjectDir)..\lib\libwebm_2008\$(ProjectName)\$(PlatformName)\$(ConfigurationName)"
IntermediateDirectory="$(ProjectDir)..\obj\libwebm_2008\$(ProjectName)\$(PlatformName)\$(ConfigurationName)"
ConfigurationType="4"
CharacterSet="1"
WholeProgramOptimization="1"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
Optimization="2"
EnableIntrinsicFunctions="true"
PreprocessorDefinitions="WIN32;NDEBUG;_LIB"
RuntimeLibrary="0"
EnableFunctionLevelLinking="true"
UsePrecompiledHeader="0"
WarningLevel="4"
DebugInformationFormat="1"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLibrarianTool"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
</Configurations>
<References>
</References>
<Files>
<Filter
Name="Source Files"
Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
>
<File
RelativePath=".\mkvmuxer.cpp"
>
</File>
<File
RelativePath=".\mkvmuxerutil.cpp"
>
</File>
<File
RelativePath=".\mkvparser.cpp"
>
</File>
<File
RelativePath=".\mkvreader.cpp"
>
</File>
<File
RelativePath=".\mkvwriter.cpp"
>
</File>
</Filter>
<Filter
Name="Header Files"
Filter="h;hpp;hxx;hm;inl;inc;xsd"
UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
>
<File
RelativePath=".\mkvmuxer.hpp"
>
</File>
<File
RelativePath=".\mkvmuxertypes.hpp"
>
</File>
<File
RelativePath=".\mkvmuxerutil.hpp"
>
</File>
<File
RelativePath=".\mkvparser.hpp"
>
</File>
<File
RelativePath=".\mkvreader.hpp"
>
</File>
<File
RelativePath=".\mkvwriter.hpp"
>
</File>
<File
RelativePath=".\webmids.hpp"
>
</File>
</Filter>
</Files>
<Globals>
</Globals>
</VisualStudioProject>

46
libwebm_2010.sln Normal file
View File

@@ -0,0 +1,46 @@

Microsoft Visual Studio Solution File, Format Version 11.00
# Visual Studio 2010
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "sample", "sample_2010.vcxproj", "{0CB5681F-6065-490C-98C8-05531732ED7E}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libwebm", "libwebm_2010.vcxproj", "{7B1F12CA-0724-430B-B61A-1D357C912CBA}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "sample_muxer", "sample_muxer_2010.vcxproj", "{B407561F-1F5E-4798-B9C2-81AB09CFBC16}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug DLL|Win32 = Debug DLL|Win32
Debug|Win32 = Debug|Win32
Release DLL|Win32 = Release DLL|Win32
Release|Win32 = Release|Win32
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{0CB5681F-6065-490C-98C8-05531732ED7E}.Debug DLL|Win32.ActiveCfg = Debug DLL|Win32
{0CB5681F-6065-490C-98C8-05531732ED7E}.Debug DLL|Win32.Build.0 = Debug DLL|Win32
{0CB5681F-6065-490C-98C8-05531732ED7E}.Debug|Win32.ActiveCfg = Debug|Win32
{0CB5681F-6065-490C-98C8-05531732ED7E}.Debug|Win32.Build.0 = Debug|Win32
{0CB5681F-6065-490C-98C8-05531732ED7E}.Release DLL|Win32.ActiveCfg = Release DLL|Win32
{0CB5681F-6065-490C-98C8-05531732ED7E}.Release DLL|Win32.Build.0 = Release DLL|Win32
{0CB5681F-6065-490C-98C8-05531732ED7E}.Release|Win32.ActiveCfg = Release|Win32
{0CB5681F-6065-490C-98C8-05531732ED7E}.Release|Win32.Build.0 = Release|Win32
{7B1F12CA-0724-430B-B61A-1D357C912CBA}.Debug DLL|Win32.ActiveCfg = Debug DLL|Win32
{7B1F12CA-0724-430B-B61A-1D357C912CBA}.Debug DLL|Win32.Build.0 = Debug DLL|Win32
{7B1F12CA-0724-430B-B61A-1D357C912CBA}.Debug|Win32.ActiveCfg = Debug|Win32
{7B1F12CA-0724-430B-B61A-1D357C912CBA}.Debug|Win32.Build.0 = Debug|Win32
{7B1F12CA-0724-430B-B61A-1D357C912CBA}.Release DLL|Win32.ActiveCfg = Release DLL|Win32
{7B1F12CA-0724-430B-B61A-1D357C912CBA}.Release DLL|Win32.Build.0 = Release DLL|Win32
{7B1F12CA-0724-430B-B61A-1D357C912CBA}.Release|Win32.ActiveCfg = Release|Win32
{7B1F12CA-0724-430B-B61A-1D357C912CBA}.Release|Win32.Build.0 = Release|Win32
{B407561F-1F5E-4798-B9C2-81AB09CFBC16}.Debug DLL|Win32.ActiveCfg = Debug DLL|Win32
{B407561F-1F5E-4798-B9C2-81AB09CFBC16}.Debug DLL|Win32.Build.0 = Debug DLL|Win32
{B407561F-1F5E-4798-B9C2-81AB09CFBC16}.Debug|Win32.ActiveCfg = Debug|Win32
{B407561F-1F5E-4798-B9C2-81AB09CFBC16}.Debug|Win32.Build.0 = Debug|Win32
{B407561F-1F5E-4798-B9C2-81AB09CFBC16}.Release DLL|Win32.ActiveCfg = Release DLL|Win32
{B407561F-1F5E-4798-B9C2-81AB09CFBC16}.Release DLL|Win32.Build.0 = Release DLL|Win32
{B407561F-1F5E-4798-B9C2-81AB09CFBC16}.Release|Win32.ActiveCfg = Release|Win32
{B407561F-1F5E-4798-B9C2-81AB09CFBC16}.Release|Win32.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal

150
libwebm_2010.vcxproj Normal file
View File

@@ -0,0 +1,150 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug DLL|Win32">
<Configuration>Debug DLL</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release DLL|Win32">
<Configuration>Release DLL</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectName>libwebm</ProjectName>
<ProjectGuid>{7B1F12CA-0724-430B-B61A-1D357C912CBA}</ProjectGuid>
<RootNamespace>libwebm</RootNamespace>
<Keyword>Win32Proj</Keyword>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<CharacterSet>Unicode</CharacterSet>
<WholeProgramOptimization>true</WholeProgramOptimization>
<PlatformToolset>Windows7.1SDK</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release DLL|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<CharacterSet>Unicode</CharacterSet>
<WholeProgramOptimization>true</WholeProgramOptimization>
<PlatformToolset>Windows7.1SDK</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<CharacterSet>Unicode</CharacterSet>
<PlatformToolset>Windows7.1SDK</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug DLL|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<CharacterSet>Unicode</CharacterSet>
<PlatformToolset>Windows7.1SDK</PlatformToolset>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release DLL|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug DLL|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup>
<_ProjectFileVersion>10.0.40219.1</_ProjectFileVersion>
<OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(ProjectDir)..\lib\libwebm_2010\$(ProjectName)\$(Platform)\$(Configuration)\</OutDir>
<OutDir Condition="'$(Configuration)|$(Platform)'=='Debug DLL|Win32'">$(ProjectDir)..\lib\libwebm_2010\$(ProjectName)\$(Platform)\$(Configuration)\</OutDir>
<IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(ProjectDir)..\obj\libwebm_2010\$(ProjectName)\$(Platform)\$(Configuration)\</IntDir>
<IntDir Condition="'$(Configuration)|$(Platform)'=='Debug DLL|Win32'">$(ProjectDir)..\obj\libwebm_2010\$(ProjectName)\$(Platform)\$(Configuration)\</IntDir>
<OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(ProjectDir)..\lib\libwebm_2010\$(ProjectName)\$(Platform)\$(Configuration)\</OutDir>
<OutDir Condition="'$(Configuration)|$(Platform)'=='Release DLL|Win32'">$(ProjectDir)..\lib\libwebm_2010\$(ProjectName)\$(Platform)\$(Configuration)\</OutDir>
<IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(ProjectDir)..\obj\libwebm_2010\$(ProjectName)\$(Platform)\$(Configuration)\</IntDir>
<IntDir Condition="'$(Configuration)|$(Platform)'=='Release DLL|Win32'">$(ProjectDir)..\obj\libwebm_2010\$(ProjectName)\$(Platform)\$(Configuration)\</IntDir>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<MinimalRebuild>false</MinimalRebuild>
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
<PrecompiledHeader>
</PrecompiledHeader>
<WarningLevel>Level4</WarningLevel>
<DebugInformationFormat>OldStyle</DebugInformationFormat>
<DisableSpecificWarnings>4996;%(DisableSpecificWarnings)</DisableSpecificWarnings>
</ClCompile>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug DLL|Win32'">
<ClCompile>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<MinimalRebuild>false</MinimalRebuild>
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
<PrecompiledHeader>
</PrecompiledHeader>
<WarningLevel>Level4</WarningLevel>
<DebugInformationFormat>OldStyle</DebugInformationFormat>
<DisableSpecificWarnings>4996;%(DisableSpecificWarnings)</DisableSpecificWarnings>
</ClCompile>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<Optimization>MaxSpeed</Optimization>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<FunctionLevelLinking>true</FunctionLevelLinking>
<PrecompiledHeader>
</PrecompiledHeader>
<WarningLevel>Level4</WarningLevel>
<DebugInformationFormat>OldStyle</DebugInformationFormat>
</ClCompile>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release DLL|Win32'">
<ClCompile>
<Optimization>MaxSpeed</Optimization>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
<FunctionLevelLinking>true</FunctionLevelLinking>
<PrecompiledHeader>
</PrecompiledHeader>
<WarningLevel>Level4</WarningLevel>
<DebugInformationFormat>OldStyle</DebugInformationFormat>
</ClCompile>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="mkvmuxer.cpp" />
<ClCompile Include="mkvmuxerutil.cpp" />
<ClCompile Include="mkvparser.cpp" />
<ClCompile Include="mkvreader.cpp" />
<ClCompile Include="mkvwriter.cpp" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="mkvmuxer.hpp" />
<ClInclude Include="mkvmuxertypes.hpp" />
<ClInclude Include="mkvmuxerutil.hpp" />
<ClInclude Include="mkvparser.hpp" />
<ClInclude Include="mkvreader.hpp" />
<ClInclude Include="mkvwriter.hpp" />
<ClInclude Include="webmids.hpp" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>

View File

@@ -0,0 +1,53 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Filter Include="Source Files">
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
<Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
</Filter>
<Filter Include="Header Files">
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
<Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions>
</Filter>
</ItemGroup>
<ItemGroup>
<ClCompile Include="mkvmuxer.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="mkvmuxerutil.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="mkvparser.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="mkvreader.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="mkvwriter.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="mkvmuxer.hpp">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="mkvmuxertypes.hpp">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="mkvmuxerutil.hpp">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="mkvparser.hpp">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="mkvreader.hpp">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="mkvwriter.hpp">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="webmids.hpp">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
</Project>

File diff suppressed because it is too large Load Diff

View File

@@ -1,4 +1,4 @@
// Copyright (c) 2011 The WebM project authors. All Rights Reserved.
// Copyright (c) 2012 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
@@ -14,9 +14,14 @@
// For a description of the WebM elements see
// http://www.webmproject.org/code/specs/container/.
namespace mkvparser {
class IMkvReader;
} // end namespace
namespace mkvmuxer {
class MkvWriter;
class Segment;
///////////////////////////////////////////////////////////////
// Interface used by the mkvmuxer to write out the Mkv data.
@@ -54,6 +59,10 @@ class IMkvWriter {
// before any other libwebm writing functions are called.
bool WriteEbmlHeader(IMkvWriter* writer);
// Copies in Chunk from source to destination between the given byte positions
bool ChunkedCopy(mkvparser::IMkvReader* source, IMkvWriter* dst,
int64 start, int64 size);
///////////////////////////////////////////////////////////////
// Class to hold data the will be written to a block.
class Frame {
@@ -151,7 +160,10 @@ class Cues {
// Returns the cue point by index. Returns NULL if there is no cue point
// match.
const CuePoint* GetCueByIndex(int32 index) const;
CuePoint* GetCueByIndex(int32 index) const;
// Returns the total size of the Cues element
uint64 Size();
// Output the Cues element to the writer. Returns true on success.
bool Write(IMkvWriter* writer) const;
@@ -179,23 +191,49 @@ class Cues {
LIBWEBM_DISALLOW_COPY_AND_ASSIGN(Cues);
};
///////////////////////////////////////////////////////////////
// ContentEncAESSettings element
class ContentEncAESSettings {
public:
enum {
kCTR = 1
};
ContentEncAESSettings();
~ContentEncAESSettings() {}
// Returns the size in bytes for the ContentEncAESSettings element.
uint64 Size() const;
// Writes out the ContentEncAESSettings element to |writer|. Returns true on
// success.
bool Write(IMkvWriter* writer) const;
uint64 cipher_mode() const { return cipher_mode_; }
private:
// Returns the size in bytes for the payload of the ContentEncAESSettings
// element.
uint64 PayloadSize() const;
// Sub elements
uint64 cipher_mode_;
LIBWEBM_DISALLOW_COPY_AND_ASSIGN(ContentEncAESSettings);
};
///////////////////////////////////////////////////////////////
// ContentEncoding element
// Elements used to describe if the track data has been encrypted or
// compressed with zlib or header stripping.
// Currently only whole frames can only be encrypted once with AES. This
// dictates that ContentEncodingOrder will be 0, ContentEncodingScope will
// be 1, ContentEncodingType will be 1, and ContentEncAlgo will be 5.
// Currently only whole frames can be encrypted with AES. This dictates that
// ContentEncodingOrder will be 0, ContentEncodingScope will be 1,
// ContentEncodingType will be 1, and ContentEncAlgo will be 5.
class ContentEncoding {
public:
ContentEncoding();
~ContentEncoding();
uint64 enc_algo() const { return enc_algo_; }
uint64 encoding_order() const { return encoding_order_; }
uint64 encoding_scope() const { return encoding_scope_; }
uint64 encoding_type() const { return encoding_type_; }
// Sets the content encryption id. Copies |length| bytes from |id| to
// |enc_key_id_|. Returns true on success.
bool SetEncryptionID(const uint8* id, uint64 length);
@@ -207,6 +245,12 @@ class ContentEncoding {
// success.
bool Write(IMkvWriter* writer) const;
uint64 enc_algo() const { return enc_algo_; }
uint64 encoding_order() const { return encoding_order_; }
uint64 encoding_scope() const { return encoding_scope_; }
uint64 encoding_type() const { return encoding_type_; }
ContentEncAESSettings* enc_aes_settings() { return &enc_aes_settings_; }
private:
// Returns the size in bytes for the encoding elements.
uint64 EncodingSize(uint64 compresion_size, uint64 encryption_size) const;
@@ -221,6 +265,9 @@ class ContentEncoding {
uint64 encoding_scope_;
uint64 encoding_type_;
// ContentEncAESSettings element.
ContentEncAESSettings enc_aes_settings_;
// Size of the ContentEncKeyID data in bytes.
uint64 enc_key_id_length_;
@@ -231,7 +278,8 @@ class ContentEncoding {
// Track element.
class Track {
public:
Track();
// The |seed| parameter is used to synthesize a UID for the track.
explicit Track(unsigned int* seed);
virtual ~Track();
// Adds a ContentEncoding element to the Track. Returns true on success.
@@ -259,12 +307,17 @@ class Track {
const uint8* codec_private() const { return codec_private_; }
void set_language(const char* language);
const char* language() const { return language_; }
void set_max_block_additional_id(uint64 max_block_additional_id) {
max_block_additional_id_ = max_block_additional_id;
}
uint64 max_block_additional_id() const { return max_block_additional_id_; }
void set_name(const char* name);
const char* name() const { return name_; }
void set_number(uint64 number) { number_ = number; }
uint64 number() const { return number_; }
void set_type(uint64 type) { type_ = type; }
uint64 type() const { return type_; }
void set_uid(uint64 uid) { uid_ = uid; }
uint64 uid() const { return uid_; }
uint64 codec_private_length() const { return codec_private_length_; }
@@ -273,17 +326,15 @@ class Track {
}
private:
// Returns a random number to be used for the Track UID.
static uint64 MakeUID();
// Track element names
char* codec_id_;
uint8* codec_private_;
char* language_;
uint64 max_block_additional_id_;
char* name_;
uint64 number_;
uint64 type_;
const uint64 uid_;
uint64 uid_;
// Size of the CodecPrivate data in bytes.
uint64 codec_private_length_;
@@ -294,9 +345,6 @@ class Track {
// Number of ContentEncoding elements added.
uint32 content_encoding_entries_size_;
// Flag telling if the rand call was seeded.
static bool is_seeded_;
LIBWEBM_DISALLOW_COPY_AND_ASSIGN(Track);
};
@@ -313,7 +361,13 @@ class VideoTrack : public Track {
kSideBySideRightIsFirst = 11
};
VideoTrack();
enum AlphaMode {
kNoAlpha = 0,
kAlpha = 1
};
// The |seed| parameter is used to synthesize a UID for the track.
explicit VideoTrack(unsigned int* seed);
virtual ~VideoTrack();
// Returns the size in bytes for the payload of the Track element plus the
@@ -326,6 +380,9 @@ class VideoTrack : public Track {
// Sets the video's stereo mode. Returns true on success.
bool SetStereoMode(uint64 stereo_mode);
// Sets the video's alpha mode. Returns true on success.
bool SetAlphaMode(uint64 alpha_mode);
void set_display_height(uint64 height) { display_height_ = height; }
uint64 display_height() const { return display_height_; }
void set_display_width(uint64 width) { display_width_ = width; }
@@ -335,6 +392,7 @@ class VideoTrack : public Track {
void set_height(uint64 height) { height_ = height; }
uint64 height() const { return height_; }
uint64 stereo_mode() { return stereo_mode_; }
uint64 alpha_mode() { return alpha_mode_; }
void set_width(uint64 width) { width_ = width; }
uint64 width() const { return width_; }
@@ -348,6 +406,7 @@ class VideoTrack : public Track {
double frame_rate_;
uint64 height_;
uint64 stereo_mode_;
uint64 alpha_mode_;
uint64 width_;
LIBWEBM_DISALLOW_COPY_AND_ASSIGN(VideoTrack);
@@ -357,7 +416,8 @@ class VideoTrack : public Track {
// Track that has audio specific elements.
class AudioTrack : public Track {
public:
AudioTrack();
// The |seed| parameter is used to synthesize a UID for the track.
explicit AudioTrack(unsigned int* seed);
virtual ~AudioTrack();
// Returns the size in bytes for the payload of the Track element plus the
@@ -433,6 +493,170 @@ class Tracks {
LIBWEBM_DISALLOW_COPY_AND_ASSIGN(Tracks);
};
///////////////////////////////////////////////////////////////
// Chapter element
//
class Chapter {
public:
// Set the identifier for this chapter. (This corresponds to the
// Cue Identifier line in WebVTT.)
// TODO(matthewjheaney): the actual serialization of this item in
// MKV is pending.
bool set_id(const char* id);
// Converts the nanosecond start and stop times of this chapter to
// their corresponding timecode values, and stores them that way.
void set_time(const Segment& segment,
uint64 start_time_ns,
uint64 end_time_ns);
// Add a title string to this chapter, per the semantics described
// here:
// http://www.matroska.org/technical/specs/index.html
//
// The title ("chapter string") is a UTF-8 string.
//
// The language has ISO 639-2 representation, described here:
// http://www.loc.gov/standards/iso639-2/englangn.html
// http://www.loc.gov/standards/iso639-2/php/English_list.php
// If you specify NULL as the language value, this implies
// English ("eng").
//
// The country value corresponds to the codes listed here:
// http://www.iana.org/domains/root/db/
//
// The function returns false if the string could not be allocated.
bool add_string(const char* title,
const char* language,
const char* country);
private:
friend class Chapters;
// For storage of chapter titles that differ by language.
class Display {
public:
// Establish representation invariant for new Display object.
void Init();
// Reclaim resources, in anticipation of destruction.
void Clear();
// Copies the title to the |title_| member. Returns false on
// error.
bool set_title(const char* title);
// Copies the language to the |language_| member. Returns false
// on error.
bool set_language(const char* language);
// Copies the country to the |country_| member. Returns false on
// error.
bool set_country(const char* country);
// If |writer| is non-NULL, serialize the Display sub-element of
// the Atom into the stream. Returns the Display element size on
// success, 0 if error.
uint64 WriteDisplay(IMkvWriter* writer) const;
private:
char* title_;
char* language_;
char* country_;
};
Chapter();
~Chapter();
// Establish the representation invariant for a newly-created
// Chapter object. The |seed| parameter is used to create the UID
// for this chapter atom.
void Init(unsigned int* seed);
// Copies this Chapter object to a different one. This is used when
// expanding a plain array of Chapter objects (see Chapters).
void ShallowCopy(Chapter* dst) const;
// Reclaim resources used by this Chapter object, pending its
// destruction.
void Clear();
// If there is no storage remaining on the |displays_| array for a
// new display object, creates a new, longer array and copies the
// existing Display objects to the new array. Returns false if the
// array cannot be expanded.
bool ExpandDisplaysArray();
// If |writer| is non-NULL, serialize the Atom sub-element into the
// stream. Returns the total size of the element on success, 0 if
// error.
uint64 WriteAtom(IMkvWriter* writer) const;
// The string identifier for this chapter (corresponds to WebVTT cue
// identifier).
char* id_;
// Start timecode of the chapter.
uint64 start_timecode_;
// Stop timecode of the chapter.
uint64 end_timecode_;
// The binary identifier for this chapter.
uint64 uid_;
// The Atom element can contain multiple Display sub-elements, as
// the same logical title can be rendered in different languages.
Display* displays_;
// The physical length (total size) of the |displays_| array.
int displays_size_;
// The logical length (number of active elements) on the |displays_|
// array.
int displays_count_;
LIBWEBM_DISALLOW_COPY_AND_ASSIGN(Chapter);
};
///////////////////////////////////////////////////////////////
// Chapters element
//
class Chapters {
public:
Chapters();
~Chapters();
Chapter* AddChapter(unsigned int* seed);
// Returns the number of chapters that have been added.
int Count() const;
// Output the Chapters element to the writer. Returns true on success.
bool Write(IMkvWriter* writer) const;
private:
// Expands the chapters_ array if there is not enough space to contain
// another chapter object. Returns true on success.
bool ExpandChaptersArray();
// If |writer| is non-NULL, serialize the Edition sub-element of the
// Chapters element into the stream. Returns the Edition element
// size on success, 0 if error.
uint64 WriteEdition(IMkvWriter* writer) const;
// Total length of the chapters_ array.
int chapters_size_;
// Number of active chapters on the chapters_ array.
int chapters_count_;
// Array for storage of chapter objects.
Chapter* chapters_;
LIBWEBM_DISALLOW_COPY_AND_ASSIGN(Chapters);
};
///////////////////////////////////////////////////////////////
// Cluster element
//
@@ -454,15 +678,58 @@ class Cluster {
// frame: Pointer to the data
// length: Length of the data
// track_number: Track to add the data to. Value returned by Add track
// functions.
// timestamp: Timecode of the frame relative to the cluster timecode.
// functions. The range of allowed values is [1, 126].
// timecode: Absolute (not relative to cluster) timestamp of the
// frame, expressed in timecode units.
// is_key: Flag telling whether or not this frame is a key frame.
bool AddFrame(const uint8* frame,
uint64 length,
uint64 track_number,
short timecode,
uint64 timecode, // timecode units (absolute)
bool is_key);
// Adds a frame to be output in the file. The frame is written out through
// |writer_| if successful. Returns true on success.
// Inputs:
// frame: Pointer to the data
// length: Length of the data
// additional: Pointer to the additional data
// additional_length: Length of the additional data
// add_id: Value of BlockAddID element
// track_number: Track to add the data to. Value returned by Add track
// functions. The range of allowed values is [1, 126].
// abs_timecode: Absolute (not relative to cluster) timestamp of the
// frame, expressed in timecode units.
// is_key: Flag telling whether or not this frame is a key frame.
bool AddFrameWithAdditional(const uint8* frame,
uint64 length,
const uint8* additional,
uint64 additional_length,
uint64 add_id,
uint64 track_number,
uint64 abs_timecode,
bool is_key);
// Writes a frame of metadata to the output medium; returns true on
// success.
// Inputs:
// frame: Pointer to the data
// length: Length of the data
// track_number: Track to add the data to. Value returned by Add track
// functions. The range of allowed values is [1, 126].
// timecode: Absolute (not relative to cluster) timestamp of the
// metadata frame, expressed in timecode units.
// duration: Duration of metadata frame, in timecode units.
//
// The metadata frame is written as a block group, with a duration
// sub-element but no reference time sub-elements (indicating that
// it is considered a keyframe, per Matroska semantics).
bool AddMetadata(const uint8* frame,
uint64 length,
uint64 track_number,
uint64 timecode, // timecode units (absolute)
uint64 duration); // timecode units
// Increments the size of the cluster's data in bytes.
void AddPayloadSize(uint64 size);
@@ -473,12 +740,53 @@ class Cluster {
// Returns the size in bytes for the entire Cluster element.
uint64 Size() const;
int64 size_position() const { return size_position_; }
int32 blocks_added() const { return blocks_added_; }
uint64 payload_size() const { return payload_size_; }
int64 position_for_cues() const { return position_for_cues_; }
uint64 timecode() const { return timecode_; }
private:
// Signature that matches either of WriteSimpleBlock or WriteMetadataBlock
// in the muxer utilities package.
typedef uint64 (*WriteBlock)(IMkvWriter* writer,
const uint8* data,
uint64 length,
uint64 track_number,
int64 timecode,
uint64 generic_arg);
// Signature that matches WriteBlockWithAdditional
// in the muxer utilities package.
typedef uint64 (*WriteBlockAdditional)(IMkvWriter* writer,
const uint8* data,
uint64 length,
const uint8* additional,
uint64 add_id,
uint64 additional_length,
uint64 track_number,
int64 timecode,
uint64 is_key);
// Used to implement AddFrame and AddMetadata.
bool DoWriteBlock(const uint8* frame,
uint64 length,
uint64 track_number,
uint64 absolute_timecode,
uint64 generic_arg,
WriteBlock write_block);
// Used to implement AddFrameWithAdditional
bool DoWriteBlockWithAdditional(const uint8* frame,
uint64 length,
const uint8* additional,
uint64 additional_length,
uint64 add_id,
uint64 track_number,
uint64 absolute_timecode,
uint64 generic_arg,
WriteBlockAdditional write_block);
// Outputs the Cluster header to |writer_|. Returns true on success.
bool WriteClusterHeader();
@@ -527,14 +835,26 @@ class SeekHead {
// Writes out SeekHead and SeekEntry elements. Returns true on success.
bool Finalize(IMkvWriter* writer) const;
// Returns the id of the Seek Entry at the given index. Returns -1 if index is
// out of range.
uint32 GetId(int index) const;
// Returns the position of the Seek Entry at the given index. Returns -1 if
// index is out of range.
uint64 GetPosition(int index) const;
// Sets the Seek Entry id and position at given index.
// Returns true on success.
bool SetSeekEntry(int index, uint32 id, uint64 position);
// Reserves space by writing out a Void element which will be updated with
// a SeekHead element later. Returns true on success.
bool Write(IMkvWriter* writer);
private:
// We are going to put a cap on the number of Seek Entries.
const static int32 kSeekEntryCount = 4;
// We are going to put a cap on the number of Seek Entries.
const static int32 kSeekEntryCount = 5;
private:
// Returns the maximum size in bytes of one seek entry.
uint64 MaxEntrySize() const;
@@ -569,6 +889,7 @@ class SegmentInfo {
void set_duration(double duration) { duration_ = duration; }
double duration() const { return duration_; }
void set_muxing_app(const char* app);
const char* muxing_app() const { return muxing_app_; }
void set_timecode_scale(uint64 scale) { timecode_scale_ = scale; }
uint64 timecode_scale() const { return timecode_scale_; }
@@ -605,6 +926,11 @@ class Segment {
kFile = 0x2
};
enum CuesPosition {
kAfterClusters = 0x0, // Position Cues after Clusters - Default
kBeforeClusters = 0x1 // Position Cues before Clusters
};
const static uint64 kDefaultMaxClusterDuration = 30000000000ULL;
Segment();
@@ -614,9 +940,12 @@ class Segment {
// |ptr_writer| is NULL.
bool Init(IMkvWriter* ptr_writer);
// Adds an audio track to the segment. Returns the number of the track on
// success, 0 on error.
uint64 AddAudioTrack(int32 sample_rate, int32 channels);
// Adds a generic track to the segment. Returns the newly-allocated
// track object (which is owned by the segment) on success, NULL on
// error. |number| is the number to use for the track. |number|
// must be >= 0. If |number| == 0 then the muxer will decide on the
// track number.
Track* AddTrack(int32 number);
// Adds an audio track to the segment. Returns the number of the track on
// success, 0 on error. |number| is the number to use for the audio track.
@@ -624,6 +953,17 @@ class Segment {
// the track number.
uint64 AddAudioTrack(int32 sample_rate, int32 channels, int32 number);
// Adds an empty chapter to the chapters of this segment. Returns
// non-NULL on success. After adding the chapter, the caller should
// populate its fields via the Chapter member functions.
Chapter* AddChapter();
// Adds a cue point to the Cues element. |timestamp| is the time in
// nanoseconds of the cue's time. |track| is the Track of the Cue. This
// function must be called after AddFrame to calculate the correct
// BlockNumber for the CuePoint. Returns true on success.
bool AddCuePoint(uint64 timestamp, uint64 track);
// Adds a frame to be output in the file. Returns true on success.
// Inputs:
// frame: Pointer to the data
@@ -635,12 +975,37 @@ class Segment {
bool AddFrame(const uint8* frame,
uint64 length,
uint64 track_number,
uint64 timestamp,
uint64 timestamp_ns,
bool is_key);
// Adds a video track to the segment. Returns the number of the track on
// success, 0 on error.
uint64 AddVideoTrack(int32 width, int32 height);
// Writes a frame of metadata to the output medium; returns true on
// success.
// Inputs:
// frame: Pointer to the data
// length: Length of the data
// track_number: Track to add the data to. Value returned by Add track
// functions.
// timecode: Absolute timestamp of the metadata frame, expressed
// in nanosecond units.
// duration: Duration of metadata frame, in nanosecond units.
//
// The metadata frame is written as a block group, with a duration
// sub-element but no reference time sub-elements (indicating that
// it is considered a keyframe, per Matroska semantics).
bool AddMetadata(const uint8* frame,
uint64 length,
uint64 track_number,
uint64 timestamp_ns,
uint64 duration_ns);
bool AddFrameWithAdditional(const uint8* frame,
uint64 length,
const uint8* additional,
uint64 additional_length,
uint64 add_id,
uint64 track_number,
uint64 timestamp,
bool is_key);
// Adds a video track to the segment. Returns the number of the track on
// success, 0 on error. |number| is the number to use for the video track.
@@ -648,11 +1013,29 @@ class Segment {
// the track number.
uint64 AddVideoTrack(int32 width, int32 height, int32 number);
// This function must be called after Finalize() if you need a copy of the
// output with Cues written before the Clusters. It will return false if the
// writer is not seekable of if chunking is set to true.
// Input parameters:
// reader - an IMkvReader object created with the same underlying file of the
// current writer object. Make sure to close the existing writer
// object before creating this so that all the data is properly
// flushed and available for reading.
// writer - an IMkvWriter object pointing to a *different* file than the one
// pointed by the current writer object. This file will contain the
// Cues element before the Clusters.
bool CopyAndMoveCuesBeforeClusters(mkvparser::IMkvReader* reader,
IMkvWriter* writer);
// Sets which track to use for the Cues element. Must have added the track
// before calling this function. Returns true on success. |track_number| is
// returned by the Add track functions.
bool CuesTrack(uint64 track_number);
// This will force the muxer to create a new Cluster when the next frame is
// added.
void ForceNewClusterOnNextFrame();
// Writes out any frames that have not been written out. Finalizes the last
// cluster. May update the size and duration of the segment. May output the
// Cues element. May finalize the SeekHead element. Returns true on success.
@@ -662,6 +1045,7 @@ class Segment {
Cues* GetCues() { return &cues_; }
// Returns the Segment Information object.
const SegmentInfo* GetSegmentInfo() const { return &segment_info_; }
SegmentInfo* GetSegmentInfo() { return &segment_info_; }
// Search the Tracks and return the track that matches |track_number|.
@@ -694,14 +1078,11 @@ class Segment {
uint64 max_cluster_size() const { return max_cluster_size_; }
void set_mode(Mode mode) { mode_ = mode; }
Mode mode() const { return mode_; }
CuesPosition cues_position() const { return cues_position_; }
bool output_cues() const { return output_cues_; }
const SegmentInfo* segment_info() const { return &segment_info_; }
private:
// Adds a cue point to the Cues element. |timestamp| is the time in
// nanoseconds of the cue's time. Returns true on success.
bool AddCuePoint(uint64 timestamp);
// Checks if header information has been output and initialized. If not it
// will output the Segment element and initialize the SeekHead elment and
// Cues elements.
@@ -720,9 +1101,9 @@ class Segment {
// Adds the frame to our frame array.
bool QueueFrame(Frame* frame);
// Output all frames that are queued. Returns true on success and if there
// are no frames queued.
bool WriteFramesAll();
// Output all frames that are queued. Returns -1 on error, otherwise
// it returns the number of frames written.
int WriteFramesAll();
// Output all frames that are queued that have an end time that is less
// then |timestamp|. Returns true on success and if there are no frames
@@ -733,11 +1114,49 @@ class Segment {
// and Tracks element to |writer_|.
bool WriteSegmentHeader();
// Given a frame with the specified timestamp (nanosecond units) and
// keyframe status, determine whether a new cluster should be
// created, before writing enqueued frames and the frame itself. The
// function returns one of the following values:
// -1 = error: an out-of-order frame was detected
// 0 = do not create a new cluster, and write frame to the existing cluster
// 1 = create a new cluster, and write frame to that new cluster
// 2 = create a new cluster, and re-run test
int TestFrame(uint64 track_num, uint64 timestamp_ns, bool key) const;
// Create a new cluster, using the earlier of the first enqueued
// frame, or the indicated time. Returns true on success.
bool MakeNewCluster(uint64 timestamp_ns);
// Checks whether a new cluster needs to be created, and if so
// creates a new cluster. Returns false if creation of a new cluster
// was necessary but creation was not successful.
bool DoNewClusterProcessing(uint64 track_num, uint64 timestamp_ns, bool key);
// Adjusts Cue Point values (to place Cues before Clusters) so that they
// reflect the correct offsets.
void MoveCuesBeforeClusters();
// This function recursively computes the correct cluster offsets (this is
// done to move the Cues before Clusters). It recursively updates the change
// in size (which indicates a change in cluster offset) until no sizes change.
// Parameters:
// diff - indicates the difference in size of the Cues element that needs to
// accounted for.
// index - index in the list of Cues which is currently being adjusted.
// cue_size - size of the Cues element.
void MoveCuesBeforeClustersHelper(uint64 diff, int index, uint64* cue_size);
// Seeds the random number generator used to make UIDs.
unsigned int seed_;
// WebM elements
Cues cues_;
SeekHead seek_head_;
SegmentInfo segment_info_;
Tracks tracks_;
Chapters chapters_;
// Number of chunks written.
int chunk_count_;
@@ -764,6 +1183,9 @@ class Segment {
// Base filename for the chunked files.
char* chunking_base_name_;
// File position offset where the Clusters end.
int64 cluster_end_offset_;
// List of clusters.
Cluster** cluster_list_;
@@ -773,9 +1195,15 @@ class Segment {
// Number of clusters in the cluster list.
int32 cluster_list_size_;
// Indicates whether Cues should be written before or after Clusters
CuesPosition cues_position_;
// Track number that is associated with the cues element for this segment.
uint64 cues_track_;
// Tells the muxer to force a new cluster on the next Block.
bool force_new_cluster_;
// List of stored audio frames. These variables are used to store frames so
// the muxer can follow the guideline "Audio blocks that contain the video
// key frame's timecode should be in the same cluster as the video key frame
@@ -811,10 +1239,6 @@ class Segment {
// seek backwards.
Mode mode_;
// Flag telling the muxer that a new cluster should be started with the next
// frame.
bool new_cluster_;
// Flag telling the muxer that a new cue point should be added.
bool new_cuepoint_;

View File

@@ -1,4 +1,4 @@
// Copyright (c) 2011 The WebM project authors. All Rights Reserved.
// Copyright (c) 2012 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
@@ -19,6 +19,7 @@
namespace mkvmuxer {
typedef unsigned char uint8;
typedef short int16;
typedef int int32;
typedef unsigned int uint32;
typedef long long int64;

View File

@@ -1,4 +1,4 @@
// Copyright (c) 2011 The WebM project authors. All Rights Reserved.
// Copyright (c) 2012 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
@@ -8,11 +8,18 @@
#include "mkvmuxerutil.hpp"
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#ifdef __ANDROID__
#include <fcntl.h>
#endif
#include <cmath>
#include <cstdio>
#ifdef _WIN32
#define _CRT_RAND_S
#endif
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <new>
@@ -22,7 +29,6 @@
namespace mkvmuxer {
int32 GetCodedUIntSize(uint64 value) {
if (value < 0x000000000000007FULL)
return 1;
else if (value < 0x0000000000003FFFULL)
@@ -41,7 +47,6 @@ int32 GetCodedUIntSize(uint64 value) {
}
int32 GetUIntSize(uint64 value) {
if (value < 0x0000000000000100ULL)
return 1;
else if (value < 0x0000000000010000ULL)
@@ -82,12 +87,12 @@ uint64 EbmlElementSize(uint64 type, uint64 value) {
return ebml_size;
}
uint64 EbmlElementSize(uint64 type, float value) {
uint64 EbmlElementSize(uint64 type, float /* value */ ) {
// Size of EBML ID
uint64 ebml_size = GetUIntSize(type);
// Datasize
ebml_size += sizeof(value);
ebml_size += sizeof(float);
// Size of Datasize
ebml_size++;
@@ -308,11 +313,28 @@ bool WriteEbmlElement(IMkvWriter* writer,
uint64 WriteSimpleBlock(IMkvWriter* writer,
const uint8* data,
uint64 length,
char track_number,
short timecode,
bool is_key) {
uint64 track_number,
int64 timecode,
uint64 is_key) {
if (!writer)
return false;
if (!writer || !data || length < 1 || track_number < 1 || timecode < 0)
if (!data || length < 1)
return false;
// Here we only permit track number values to be no greater than
// 126, which the largest value we can store having a Matroska
// integer representation of only 1 byte.
if (track_number < 1 || track_number > 126)
return false;
// Technically the timestamp for a block can be less than the
// timestamp for the cluster itself (remember that block timestamp
// is a signed, 16-bit integer). However, as a simplification we
// only permit non-negative cluster-relative timestamps for blocks.
if (timecode < 0 || timecode > kMaxBlockTimecode)
return false;
if (WriteID(writer, kMkvSimpleBlock))
@@ -325,11 +347,11 @@ uint64 WriteSimpleBlock(IMkvWriter* writer,
if (WriteUInt(writer, static_cast<uint64>(track_number)))
return 0;
if (SerializeInt(writer, static_cast<uint64>(timecode), 2))
if (SerializeInt(writer, timecode, 2))
return 0;
uint64 flags = 0;
if(is_key)
if (is_key)
flags |= 0x80;
if (SerializeInt(writer, flags, 1))
@@ -344,6 +366,193 @@ uint64 WriteSimpleBlock(IMkvWriter* writer,
return element_size;
}
// We must write the metadata (key)frame as a BlockGroup element,
// because we need to specify a duration for the frame. The
// BlockGroup element comprises the frame itself and its duration,
// and is laid out as follows:
//
// BlockGroup tag
// BlockGroup size
// Block tag
// Block size
// (the frame is the block payload)
// Duration tag
// Duration size
// (duration payload)
//
uint64 WriteMetadataBlock(IMkvWriter* writer,
const uint8* data,
uint64 length,
uint64 track_number,
int64 timecode,
uint64 duration) {
// We don't backtrack when writing to the stream, so we must
// pre-compute the BlockGroup size, by summing the sizes of each
// sub-element (the block and the duration).
// We use a single byte for the track number of the block, which
// means the block header is exactly 4 bytes.
// TODO(matthewjheaney): use EbmlMasterElementSize and WriteEbmlMasterElement
const uint64 block_payload_size = 4 + length;
const int32 block_size = GetCodedUIntSize(block_payload_size);
const uint64 block_elem_size = 1 + block_size + block_payload_size;
const int32 duration_payload_size = GetUIntSize(duration);
const int32 duration_size = GetCodedUIntSize(duration_payload_size);
const uint64 duration_elem_size = 1 + duration_size + duration_payload_size;
const uint64 blockg_payload_size = block_elem_size + duration_elem_size;
const int32 blockg_size = GetCodedUIntSize(blockg_payload_size);
const uint64 blockg_elem_size = 1 + blockg_size + blockg_payload_size;
if (WriteID(writer, kMkvBlockGroup)) // 1-byte ID size
return 0;
if (WriteUInt(writer, blockg_payload_size))
return 0;
// Write Block element
if (WriteID(writer, kMkvBlock)) // 1-byte ID size
return 0;
if (WriteUInt(writer, block_payload_size))
return 0;
// Byte 1 of 4
if (WriteUInt(writer, track_number))
return 0;
// Bytes 2 & 3 of 4
if (SerializeInt(writer, timecode, 2))
return 0;
// Byte 4 of 4
const uint64 flags = 0;
if (SerializeInt(writer, flags, 1))
return 0;
// Now write the actual frame (of metadata)
if (writer->Write(data, static_cast<uint32>(length)))
return 0;
// Write Duration element
if (WriteID(writer, kMkvBlockDuration)) // 1-byte ID size
return 0;
if (WriteUInt(writer, duration_payload_size))
return 0;
if (SerializeInt(writer, duration, duration_payload_size))
return 0;
// Note that we don't write a reference time as part of the block
// group; no reference time(s) indicates that this block is a
// keyframe. (Unlike the case for a SimpleBlock element, the header
// bits of the Block sub-element of a BlockGroup element do not
// indicate keyframe status. The keyframe status is inferred from
// the absence of reference time sub-elements.)
return blockg_elem_size;
}
// Writes a WebM Block with Additional. The structure is as follows
// Indentation shows sub-levels
// BlockGroup
// Block
// Data
// BlockAdditions
// BlockMore
// BlockAddID
// 1 (Denotes Alpha)
// BlockAdditional
// Data
uint64 WriteBlockWithAdditional(IMkvWriter* writer,
const uint8* data,
uint64 length,
const uint8* additional,
uint64 additional_length,
uint64 add_id,
uint64 track_number,
int64 timecode,
uint64 is_key) {
if (!data || !additional || length < 1 || additional_length < 1)
return 0;
const uint64 block_payload_size = 4 + length;
const uint64 block_elem_size = EbmlMasterElementSize(kMkvBlock,
block_payload_size) +
block_payload_size;
const uint64 block_additional_elem_size = EbmlElementSize(kMkvBlockAdditional,
additional,
additional_length);
const uint64 block_addid_elem_size = EbmlElementSize(kMkvBlockAddID, add_id);
const uint64 block_more_payload_size = block_addid_elem_size +
block_additional_elem_size;
const uint64 block_more_elem_size = EbmlMasterElementSize(
kMkvBlockMore,
block_more_payload_size) +
block_more_payload_size;
const uint64 block_additions_payload_size = block_more_elem_size;
const uint64 block_additions_elem_size = EbmlMasterElementSize(
kMkvBlockAdditions,
block_additions_payload_size) +
block_additions_payload_size;
const uint64 block_group_payload_size = block_elem_size +
block_additions_elem_size;
const uint64 block_group_elem_size = EbmlMasterElementSize(
kMkvBlockGroup,
block_group_payload_size) +
block_group_payload_size;
if (!WriteEbmlMasterElement(writer, kMkvBlockGroup,
block_group_payload_size))
return 0;
if (!WriteEbmlMasterElement(writer, kMkvBlock, block_payload_size))
return 0;
if (WriteUInt(writer, track_number))
return 0;
if (SerializeInt(writer, timecode, 2))
return 0;
uint64 flags = 0;
if (is_key)
flags |= 0x80;
if (SerializeInt(writer, flags, 1))
return 0;
if (writer->Write(data, static_cast<uint32>(length)))
return 0;
if (!WriteEbmlMasterElement(writer, kMkvBlockAdditions,
block_additions_payload_size))
return 0;
if (!WriteEbmlMasterElement(writer, kMkvBlockMore, block_more_payload_size))
return 0;
if (!WriteEbmlElement(writer, kMkvBlockAddID, add_id))
return 0;
if (!WriteEbmlElement(writer, kMkvBlockAdditional,
additional, additional_length))
return 0;
return block_group_elem_size;
}
uint64 WriteVoidElement(IMkvWriter* writer, uint64 size) {
if (!writer)
return false;
@@ -380,11 +589,42 @@ uint64 WriteVoidElement(IMkvWriter* writer, uint64 size) {
return void_size;
}
void GetVersion(int32& major, int32& minor, int32& build, int32& revision) {
major = 0;
minor = 0;
build = 0;
revision = 1;
void GetVersion(int32* major, int32* minor, int32* build, int32* revision) {
*major = 0;
*minor = 2;
*build = 1;
*revision = 0;
}
} // namespace mkvmuxer
mkvmuxer::uint64 mkvmuxer::MakeUID(unsigned int* seed) {
uint64 uid = 0;
for (int i = 0; i < 7; ++i) { // avoid problems with 8-byte values
uid <<= 8;
// TODO(fgalligan): Move random number generation to platform specific code.
#ifdef _WIN32
(void)seed;
unsigned int random_value;
const errno_t e = rand_s(&random_value);
(void)e;
const int32 nn = random_value;
#elif __ANDROID__
int32 temp_num = 1;
int fd = open("/dev/urandom", O_RDONLY);
if (fd != -1) {
read(fd, &temp_num, sizeof(int32));
close(fd);
}
const int32 nn = temp_num;
#else
const int32 nn = rand_r(seed);
#endif
const int32 n = 0xFF & (nn >> 4); // throw away low-order bits
uid |= n;
}
return uid;
}

View File

@@ -16,11 +16,14 @@ namespace mkvmuxer {
class IMkvWriter;
const uint64 kEbmlUnknownValue = 0x01FFFFFFFFFFFFFFULL;
const int64 kMaxBlockTimecode = 0x07FFFLL;
// Writes out |value| in Big Endian order. Returns 0 on success.
int32 SerializeInt(IMkvWriter* writer, int64 value, int32 size);
// Returns the size in bytes of the element.
int32 GetUIntSize(uint64 value);
int32 GetCodedUIntSize(uint64 value);
uint64 EbmlMasterElementSize(uint64 type, uint64 value);
uint64 EbmlElementSize(uint64 type, uint64 value);
uint64 EbmlElementSize(uint64 type, float value);
@@ -58,15 +61,57 @@ bool WriteEbmlElement(IMkvWriter* writer,
// data: Pointer to the data.
// length: Length of the data.
// track_number: Track to add the data to. Value returned by Add track
// functions.
// timecode: Relative timecode of the Block.
// is_key: Flag telling whether or not this frame is a key frame.
// functions. Only values in the range [1, 126] are
// permitted.
// timecode: Relative timecode of the Block. Only values in the
// range [0, 2^15) are permitted.
// is_key: Non-zero value specifies that frame is a key frame.
uint64 WriteSimpleBlock(IMkvWriter* writer,
const uint8* data,
uint64 length,
char track_number,
short timecode,
bool is_key);
uint64 track_number,
int64 timecode,
uint64 is_key);
// Output a metadata keyframe, using a Block Group element.
// Inputs:
// data: Pointer to the (meta)data.
// length: Length of the (meta)data.
// track_number: Track to add the data to. Value returned by Add track
// functions. Only values in the range [1, 126] are
// permitted.
// timecode Timecode of frame, relative to cluster timecode. Only
// values in the range [0, 2^15) are permitted.
// duration_timecode Duration of frame, using timecode units.
uint64 WriteMetadataBlock(IMkvWriter* writer,
const uint8* data,
uint64 length,
uint64 track_number,
int64 timecode,
uint64 duration_timecode);
// Output an Mkv Block with BlockAdditional data.
// Inputs:
// data: Pointer to the data.
// length: Length of the data.
// additional: Pointer to the additional data
// additional_length: Length of the additional data.
// add_id: Value of BlockAddID element.
// track_number: Track to add the data to. Value returned by Add track
// functions. Only values in the range [1, 126] are
// permitted.
// timecode: Relative timecode of the Block. Only values in the
// range [0, 2^15) are permitted.
// is_key: Non-zero value specifies that frame is a key frame.
uint64 WriteBlockWithAdditional(IMkvWriter* writer,
const uint8* data,
uint64 length,
const uint8* additional,
uint64 additional_length,
uint64 add_id,
uint64 track_number,
int64 timecode,
uint64 is_key);
// Output a void element. |size| must be the entire size in bytes that will be
// void. The function will calculate the size of the void header and subtract
@@ -75,7 +120,11 @@ uint64 WriteVoidElement(IMkvWriter* writer, uint64 size);
// Returns the version number of the muxer in |major|, |minor|, |build|,
// and |revision|.
void GetVersion(int32& major, int32& minor, int32& build, int32& revision);
void GetVersion(int32* major, int32* minor, int32* build, int32* revision);
// Returns a random number to be used for UID, using |seed| to seed
// the random-number generator (see POSIX rand_r() for semantics).
uint64 MakeUID(unsigned int* seed);
} //end namespace mkvmuxer

File diff suppressed because it is too large Load Diff

View File

@@ -1,4 +1,4 @@
// Copyright (c) 2010 The WebM project authors. All Rights Reserved.
// Copyright (c) 2012 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
@@ -30,23 +30,26 @@ protected:
long long GetUIntLength(IMkvReader*, long long, long&);
long long ReadUInt(IMkvReader*, long long, long&);
long long SyncReadUInt(IMkvReader*, long long pos, long long stop, long&);
long long UnserializeUInt(IMkvReader*, long long pos, long long size);
float Unserialize4Float(IMkvReader*, long long);
double Unserialize8Double(IMkvReader*, long long);
#if 0
short Unserialize2SInt(IMkvReader*, long long);
signed char Unserialize1SInt(IMkvReader*, long long);
#else
long UnserializeFloat(IMkvReader*, long long pos, long long size, double&);
long UnserializeInt(IMkvReader*, long long pos, long len, long long& result);
#endif
long UnserializeString(
IMkvReader*,
long long pos,
long long size,
char*& str);
long ParseElementHeader(
IMkvReader* pReader,
long long& pos, //consume id and size fields
long long stop, //if you know size of element's parent
long long& id,
long long& size);
bool Match(IMkvReader*, long long&, unsigned long, long long&);
bool Match(IMkvReader*, long long&, unsigned long, char*&);
bool Match(IMkvReader*, long long&, unsigned long, unsigned char*&, size_t&);
bool Match(IMkvReader*, long long&, unsigned long, double&);
bool Match(IMkvReader*, long long&, unsigned long, short&);
void GetVersion(int& major, int& minor, int& build, int& revision);
@@ -80,9 +83,11 @@ public:
const long long m_start;
const long long m_size;
Block(long long start, long long size, IMkvReader*);
Block(long long start, long long size);
~Block();
long Parse(const Cluster*);
long long GetTrackNumber() const;
long long GetTimeCode(const Cluster*) const; //absolute, but not scaled
long long GetTime(const Cluster*) const; //absolute, and scaled (ns)
@@ -126,6 +131,7 @@ protected:
public:
virtual ~BlockEntry();
bool EOS() const;
const Cluster* GetCluster() const;
long GetIndex() const;
@@ -148,6 +154,7 @@ class SimpleBlock : public BlockEntry
public:
SimpleBlock(Cluster*, long index, long long start, long long size);
long Parse();
Kind GetKind() const;
const Block* GetBlock() const;
@@ -173,12 +180,14 @@ public:
long long next,
long long duration);
long Parse();
Kind GetKind() const;
const Block* GetBlock() const;
long long GetPrevTimeCode() const; //relative to block's time
long long GetNextTimeCode() const; //as above
long long GetDuration() const;
long long GetDurationTimeCode() const;
private:
Block m_block;
@@ -194,6 +203,10 @@ private:
// compressed with zlib or header stripping.
class ContentEncoding {
public:
enum {
kCTR = 1
};
ContentEncoding();
~ContentEncoding();
@@ -204,6 +217,15 @@ public:
unsigned long long algo;
unsigned char* settings;
long long settings_len;
};
// ContentEncAESSettings element names
struct ContentEncAESSettings {
ContentEncAESSettings() : cipher_mode(kCTR) {}
~ContentEncAESSettings() {}
unsigned long long cipher_mode;
};
// ContentEncryption element names
@@ -220,6 +242,8 @@ public:
long long sig_key_id_len;
unsigned long long sig_algo;
unsigned long long sig_hash_algo;
ContentEncAESSettings aes_settings;
};
// Returns ContentCompression represented by |idx|. Returns NULL if |idx|
@@ -230,6 +254,15 @@ public:
// element.
unsigned long GetCompressionCount() const;
// Parses the ContentCompression element from |pReader|. |start| is the
// starting offset of the ContentCompression payload. |size| is the size in
// bytes of the ContentCompression payload. |compression| is where the parsed
// values will be stored.
long ParseCompressionEntry(long long start,
long long size,
IMkvReader* pReader,
ContentCompression* compression);
// Returns ContentEncryption represented by |idx|. Returns NULL if |idx|
// is out of bounds.
const ContentEncryption* GetEncryptionByIndex(unsigned long idx) const;
@@ -238,21 +271,30 @@ public:
// element.
unsigned long GetEncryptionCount() const;
// Parses the ContentEncAESSettings element from |pReader|. |start| is the
// starting offset of the ContentEncAESSettings payload. |size| is the
// size in bytes of the ContentEncAESSettings payload. |encryption| is
// where the parsed values will be stored.
long ParseContentEncAESSettingsEntry(long long start,
long long size,
IMkvReader* pReader,
ContentEncAESSettings* aes);
// Parses the ContentEncoding element from |pReader|. |start| is the
// starting offset of the ContentEncoding payload. |size| is the size in
// bytes of the ContentEncoding payload. Returns true on success.
bool ParseContentEncodingEntry(long long start,
long ParseContentEncodingEntry(long long start,
long long size,
IMkvReader* const pReader);
IMkvReader* pReader);
// Parses the ContentEncryption element from |pReader|. |start| is the
// starting offset of the ContentEncryption payload. |size| is the size in
// bytes of the ContentEncryption payload. |encryption| is where the parsed
// values will be stored.
void ParseEncryptionEntry(long long start,
long ParseEncryptionEntry(long long start,
long long size,
IMkvReader* const pReader,
ContentEncryption* const encryption);
IMkvReader* pReader,
ContentEncryption* encryption);
unsigned long long encoding_order() const { return encoding_order_; }
unsigned long long encoding_scope() const { return encoding_scope_; }
@@ -283,19 +325,36 @@ class Track
Track& operator=(const Track&);
public:
class Info;
static long Create(
Segment*,
const Info&,
long long element_start,
long long element_size,
Track*&);
enum Type {
kVideo = 1,
kAudio = 2,
kSubtitle = 0x11,
kMetadata = 0x21
};
Segment* const m_pSegment;
const long long m_element_start;
const long long m_element_size;
virtual ~Track();
long long GetType() const;
long long GetNumber() const;
long GetType() const;
long GetNumber() const;
unsigned long long GetUid() const;
const char* GetNameAsUTF8() const;
const char* GetLanguage() const;
const char* GetCodecNameAsUTF8() const;
const char* GetCodecId() const;
const unsigned char* GetCodecPrivate(size_t&) const;
bool GetLacing() const;
unsigned long long GetDefaultDuration() const;
const BlockEntry* GetEOS() const;
@@ -305,49 +364,56 @@ public:
long long size;
};
struct Info
class Info
{
long long type;
long long number;
public:
Info();
~Info();
int Copy(Info&) const;
void Clear();
private:
Info(const Info&);
Info& operator=(const Info&);
public:
long type;
long number;
unsigned long long uid;
unsigned long long defaultDuration;
char* nameAsUTF8;
char* language;
char* codecId;
char* codecNameAsUTF8;
unsigned char* codecPrivate;
size_t codecPrivateSize;
char* codecNameAsUTF8;
bool lacing;
Settings settings;
Info();
void Clear();
private:
int CopyStr(char* Info::*str, Info&) const;
};
long GetFirst(const BlockEntry*&) const;
long GetNext(const BlockEntry* pCurr, const BlockEntry*& pNext) const;
virtual bool VetEntry(const BlockEntry*) const = 0;
virtual long Seek(long long time_ns, const BlockEntry*&) const = 0;
virtual bool VetEntry(const BlockEntry*) const;
virtual long Seek(long long time_ns, const BlockEntry*&) const;
const ContentEncoding* GetContentEncodingByIndex(unsigned long idx) const;
unsigned long GetContentEncodingCount() const;
void ParseContentEncodingsEntry(long long start, long long size);
long ParseContentEncodingsEntry(long long start, long long size);
protected:
Track(
Segment*,
const Info&,
long long element_start,
long long element_size);
const Info m_info;
Info m_info;
class EOSBlock : public BlockEntry
{
public:
EOSBlock();
//bool EOS() const;
//const Cluster* GetCluster() const;
//long GetIndex() const;
Kind GetKind() const;
const Block* GetBlock() const;
};
@@ -365,12 +431,19 @@ class VideoTrack : public Track
VideoTrack(const VideoTrack&);
VideoTrack& operator=(const VideoTrack&);
public:
VideoTrack(
Segment*,
long long element_start,
long long element_size);
public:
static long Parse(
Segment*,
const Info&,
long long element_start,
long long element_size);
long long element_size,
VideoTrack*&);
long long GetWidth() const;
long long GetHeight() const;
double GetFrameRate() const;
@@ -391,17 +464,21 @@ class AudioTrack : public Track
AudioTrack(const AudioTrack&);
AudioTrack& operator=(const AudioTrack&);
public:
AudioTrack(
Segment*,
long long element_start,
long long element_size);
public:
static long Parse(
Segment*,
const Info&,
long long element_start,
long long element_size);
long long element_size,
AudioTrack*&);
double GetSamplingRate() const;
long long GetChannels() const;
long long GetBitDepth() const;
bool VetEntry(const BlockEntry*) const;
long Seek(long long time_ns, const BlockEntry*&) const;
private:
double m_rate;
@@ -428,24 +505,152 @@ public:
long long size,
long long element_start,
long long element_size);
virtual ~Tracks();
const Track* GetTrackByNumber(unsigned long tn) const;
~Tracks();
long Parse();
unsigned long GetTracksCount() const;
const Track* GetTrackByNumber(long tn) const;
const Track* GetTrackByIndex(unsigned long idx) const;
private:
Track** m_trackEntries;
Track** m_trackEntriesEnd;
void ParseTrackEntry(
long long,
long long,
Track*&,
long ParseTrackEntry(
long long payload_start,
long long payload_size,
long long element_start,
long long element_size,
Track*&) const;
};
class Chapters
{
Chapters(const Chapters&);
Chapters& operator=(const Chapters&);
public:
Segment* const m_pSegment;
const long long m_start;
const long long m_size;
const long long m_element_start;
const long long m_element_size;
Chapters(
Segment*,
long long payload_start,
long long payload_size,
long long element_start,
long long element_size);
public:
unsigned long GetTracksCount() const;
~Chapters();
long Parse();
class Atom;
class Edition;
class Display
{
friend class Atom;
Display();
Display(const Display&);
~Display();
Display& operator=(const Display&);
public:
const char* GetString() const;
const char* GetLanguage() const;
const char* GetCountry() const;
private:
void Init();
void ShallowCopy(Display&) const;
void Clear();
long Parse(IMkvReader*, long long pos, long long size);
char* m_string;
char* m_language;
char* m_country;
};
class Atom
{
friend class Edition;
Atom();
Atom(const Atom&);
~Atom();
Atom& operator=(const Atom&);
public:
unsigned long long GetUID() const;
const char* GetStringUID() const;
long long GetStartTimecode() const;
long long GetStopTimecode() const;
long long GetStartTime(const Chapters*) const;
long long GetStopTime(const Chapters*) const;
int GetDisplayCount() const;
const Display* GetDisplay(int index) const;
private:
void Init();
void ShallowCopy(Atom&) const;
void Clear();
long Parse(IMkvReader*, long long pos, long long size);
static long long GetTime(const Chapters*, long long timecode);
long ParseDisplay(IMkvReader*, long long pos, long long size);
bool ExpandDisplaysArray();
char* m_string_uid;
unsigned long long m_uid;
long long m_start_timecode;
long long m_stop_timecode;
Display* m_displays;
int m_displays_size;
int m_displays_count;
};
class Edition
{
friend class Chapters;
Edition();
Edition(const Edition&);
~Edition();
Edition& operator=(const Edition&);
public:
int GetAtomCount() const;
const Atom* GetAtom(int index) const;
private:
void Init();
void ShallowCopy(Edition&) const;
void Clear();
long Parse(IMkvReader*, long long pos, long long size);
long ParseAtom(IMkvReader*, long long pos, long long size);
bool ExpandAtomsArray();
Atom* m_atoms;
int m_atoms_size;
int m_atoms_count;
};
int GetEditionCount() const;
const Edition* GetEdition(int index) const;
private:
long ParseEdition(long long pos, long long size);
bool ExpandEditionsArray();
Edition* m_editions;
int m_editions_size;
int m_editions_count;
};
@@ -470,6 +675,8 @@ public:
~SegmentInfo();
long Parse();
long long GetTimeCodeScale() const;
long long GetDuration() const; //scaled
const char* GetMuxingAppAsUTF8() const;
@@ -506,6 +713,8 @@ public:
~SeekHead();
long Parse();
struct Entry
{
//the SeekHead entry payload
@@ -680,9 +889,10 @@ public:
long long GetFirstTime() const; //time (ns) of first (earliest) block
long long GetLastTime() const; //time (ns) of last (latest) block
const BlockEntry* GetFirst() const;
const BlockEntry* GetLast() const;
const BlockEntry* GetNext(const BlockEntry*) const;
long GetFirst(const BlockEntry*&) const;
long GetLast(const BlockEntry*&) const;
long GetNext(const BlockEntry* curr, const BlockEntry*& next) const;
const BlockEntry* GetEntry(const Track*, long long ns = -1) const;
const BlockEntry* GetEntry(
const CuePoint&,
@@ -731,12 +941,12 @@ private:
mutable long m_entries_size;
mutable long m_entries_count;
long ParseSimpleBlock(long long, long long&, long&) const;
long ParseBlockGroup(long long, long long&, long&) const;
long ParseSimpleBlock(long long, long long&, long&);
long ParseBlockGroup(long long, long long&, long&);
void CreateBlock(long long id, long long pos, long long size) const;
void CreateBlockGroup(long long, long long, BlockEntry**&) const;
void CreateSimpleBlock(long long, long long, BlockEntry**&) const;
long CreateBlock(long long id, long long pos, long long size);
long CreateBlockGroup(long long, long long);
long CreateSimpleBlock(long long, long long);
};
@@ -744,8 +954,8 @@ private:
class Segment
{
friend class Cues;
friend class Track;
friend class VideoTrack;
friend class AudioTrack;
Segment(const Segment&);
Segment& operator=(const Segment&);
@@ -796,6 +1006,7 @@ public:
const Tracks* GetTracks() const;
const SegmentInfo* GetInfo() const;
const Cues* GetCues() const;
const Chapters* GetChapters() const;
long long GetDuration() const;
@@ -823,6 +1034,7 @@ private:
SegmentInfo* m_pInfo;
Tracks* m_pTracks;
Cues* m_pCues;
Chapters* m_pChapters;
Cluster** m_clusters;
long m_clusterCount; //number of entries for which m_index >= 0
long m_clusterPreloadCount; //number of entries for which m_index < 0

View File

@@ -25,7 +25,6 @@ public:
int Open(const char*);
void Close();
bool IsOpen() const;
virtual int Read(long long position, long length, unsigned char* buffer);
virtual int Length(long long* total, long long* available);

View File

@@ -1,94 +1,94 @@
// Copyright (c) 2011 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 "mkvwriter.hpp"
#ifdef _MSC_VER
#include <share.h> // for _SH_DENYWR
#endif
#include <new>
namespace mkvmuxer {
MkvWriter::MkvWriter() : file_(NULL) {
}
MkvWriter::~MkvWriter() {
Close();
}
int32 MkvWriter::Write(const void* buffer, uint32 length) {
if (!file_)
return -1;
if (length == 0)
return 0;
if (buffer == NULL)
return -1;
const size_t bytes_written = fwrite(buffer, 1, length, file_);
return (bytes_written == length) ? 0 : -1;
}
bool MkvWriter::Open(const char* filename) {
if (filename == NULL)
return false;
if (file_)
return false;
#ifdef _MSC_VER
file_ = _fsopen(filename, "wb", _SH_DENYWR);
#else
file_ = fopen(filename, "wb");
#endif
if (file_ == NULL)
return false;
return true;
}
void MkvWriter::Close() {
if (file_) {
fclose(file_);
file_ = NULL;
}
}
int64 MkvWriter::Position() const {
if (!file_)
return 0;
#ifdef _MSC_VER
return _ftelli64(file_);
#else
return ftell(file_);
#endif
}
int32 MkvWriter::Position(int64 position) {
if (!file_)
return -1;
#ifdef _MSC_VER
return _fseeki64(file_, position, SEEK_SET);
#else
return fseek(file_, position, SEEK_SET);
#endif
}
bool MkvWriter::Seekable() const {
return true;
}
void MkvWriter::ElementStartNotify(uint64, int64) {
}
} // namespace mkvmuxer
// Copyright (c) 2012 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 "mkvwriter.hpp"
#ifdef _MSC_VER
#include <share.h> // for _SH_DENYWR
#endif
#include <new>
namespace mkvmuxer {
MkvWriter::MkvWriter() : file_(NULL) {
}
MkvWriter::~MkvWriter() {
Close();
}
int32 MkvWriter::Write(const void* buffer, uint32 length) {
if (!file_)
return -1;
if (length == 0)
return 0;
if (buffer == NULL)
return -1;
const size_t bytes_written = fwrite(buffer, 1, length, file_);
return (bytes_written == length) ? 0 : -1;
}
bool MkvWriter::Open(const char* filename) {
if (filename == NULL)
return false;
if (file_)
return false;
#ifdef _MSC_VER
file_ = _fsopen(filename, "wb", _SH_DENYWR);
#else
file_ = fopen(filename, "wb");
#endif
if (file_ == NULL)
return false;
return true;
}
void MkvWriter::Close() {
if (file_) {
fclose(file_);
file_ = NULL;
}
}
int64 MkvWriter::Position() const {
if (!file_)
return 0;
#ifdef _MSC_VER
return _ftelli64(file_);
#else
return ftell(file_);
#endif
}
int32 MkvWriter::Position(int64 position) {
if (!file_)
return -1;
#ifdef _MSC_VER
return _fseeki64(file_, position, SEEK_SET);
#else
return fseek(file_, position, SEEK_SET);
#endif
}
bool MkvWriter::Seekable() const {
return true;
}
void MkvWriter::ElementStartNotify(uint64, int64) {
}
} // namespace mkvmuxer

View File

@@ -1,49 +1,49 @@
// Copyright (c) 2012 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.
#ifndef MKVWRITER_HPP
#define MKVWRITER_HPP
#include <stdio.h>
#include "mkvmuxer.hpp"
#include "mkvmuxertypes.hpp"
namespace mkvmuxer {
// Default implementation of the IMkvWriter interface on Windows.
class MkvWriter : public IMkvWriter {
public:
MkvWriter();
virtual ~MkvWriter();
// IMkvWriter interface
virtual int64 Position() const;
virtual int32 Position(int64 position);
virtual bool Seekable() const;
virtual int32 Write(const void* buffer, uint32 length);
virtual void ElementStartNotify(uint64 element_id, int64 position);
// Creates and opens a file for writing. |filename| is the name of the file
// to open. This function will overwrite the contents of |filename|. Returns
// true on success.
bool Open(const char* filename);
// Closes an opened file.
void Close();
private:
// File handle to output file.
FILE* file_;
LIBWEBM_DISALLOW_COPY_AND_ASSIGN(MkvWriter);
};
} //end namespace mkvmuxer
#endif // MKVWRITER_HPP
// Copyright (c) 2012 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.
#ifndef MKVWRITER_HPP
#define MKVWRITER_HPP
#include <stdio.h>
#include "mkvmuxer.hpp"
#include "mkvmuxertypes.hpp"
namespace mkvmuxer {
// Default implementation of the IMkvWriter interface on Windows.
class MkvWriter : public IMkvWriter {
public:
MkvWriter();
virtual ~MkvWriter();
// IMkvWriter interface
virtual int64 Position() const;
virtual int32 Position(int64 position);
virtual bool Seekable() const;
virtual int32 Write(const void* buffer, uint32 length);
virtual void ElementStartNotify(uint64 element_id, int64 position);
// Creates and opens a file for writing. |filename| is the name of the file
// to open. This function will overwrite the contents of |filename|. Returns
// true on success.
bool Open(const char* filename);
// Closes an opened file.
void Close();
private:
// File handle to output file.
FILE* file_;
LIBWEBM_DISALLOW_COPY_AND_ASSIGN(MkvWriter);
};
} //end namespace mkvmuxer
#endif // MKVWRITER_HPP

View File

@@ -11,6 +11,7 @@
#include "mkvreader.hpp"
#include "mkvparser.hpp"
#include <memory>
#ifdef _MSC_VER
// Silences these warnings:
@@ -83,15 +84,18 @@ int main(int argc, char* argv[])
printf("\t\tDoc Type\t\t: %s\n", ebmlHeader.m_docType);
printf("\t\tPos\t\t\t: %lld\n", pos);
mkvparser::Segment* pSegment;
typedef mkvparser::Segment seg_t;
seg_t* pSegment_;
long long ret = mkvparser::Segment::CreateInstance(&reader, pos, pSegment);
long long ret = seg_t::CreateInstance(&reader, pos, pSegment_);
if (ret)
{
printf("\n Segment::CreateInstance() failed.");
return -1;
}
const std::auto_ptr<seg_t> pSegment(pSegment_);
ret = pSegment->Load();
if (ret < 0)
{
@@ -157,8 +161,6 @@ int main(int argc, char* argv[])
unsigned long i = 0;
const unsigned long j = pTracks->GetTracksCount();
enum { VIDEO_TRACK = 1, AUDIO_TRACK = 2 };
printf("\n\t\t\t Track Info\n");
while (i != j)
@@ -168,13 +170,13 @@ int main(int argc, char* argv[])
if (pTrack == NULL)
continue;
const long long trackType = pTrack->GetType();
const long long trackNumber = pTrack->GetNumber();
const long trackType = pTrack->GetType();
const long trackNumber = pTrack->GetNumber();
const unsigned long long trackUid = pTrack->GetUid();
const wchar_t* const pTrackName = utf8towcs(pTrack->GetNameAsUTF8());
printf("\t\tTrack Type\t\t: %lld\n", trackType);
printf("\t\tTrack Number\t\t: %lld\n", trackNumber);
printf("\t\tTrack Type\t\t: %ld\n", trackType);
printf("\t\tTrack Number\t\t: %ld\n", trackNumber);
printf("\t\tTrack Uid\t\t: %lld\n", trackUid);
if (pTrackName == NULL)
@@ -203,7 +205,7 @@ int main(int argc, char* argv[])
delete [] pCodecName;
}
if (trackType == VIDEO_TRACK)
if (trackType == mkvparser::Track::kVideo)
{
const VideoTrack* const pVideoTrack =
static_cast<const VideoTrack*>(pTrack);
@@ -218,7 +220,7 @@ int main(int argc, char* argv[])
printf("\t\tVideo Rate\t\t: %f\n",rate);
}
if (trackType == AUDIO_TRACK)
if (trackType == mkvparser::Track::kAudio)
{
const AudioTrack* const pAudioTrack =
static_cast<const AudioTrack*>(pTrack);
@@ -242,7 +244,6 @@ int main(int argc, char* argv[])
if (clusterCount == 0)
{
printf("\t\tSegment has no clusters.\n");
delete pSegment;
return -1;
}
@@ -256,7 +257,16 @@ int main(int argc, char* argv[])
const long long time_ns = pCluster->GetTime();
printf("\t\tCluster Time (ns)\t: %lld\n", time_ns);
const BlockEntry* pBlockEntry = pCluster->GetFirst();
const BlockEntry* pBlockEntry;
long status = pCluster->GetFirst(pBlockEntry);
if (status < 0) //error
{
printf("\t\tError parsing first block of cluster\n");
fflush(stdout);
return -1;
}
while ((pBlockEntry != NULL) && !pBlockEntry->EOS())
{
@@ -264,30 +274,42 @@ int main(int argc, char* argv[])
const long long trackNum = pBlock->GetTrackNumber();
const unsigned long tn = static_cast<unsigned long>(trackNum);
const Track* const pTrack = pTracks->GetTrackByNumber(tn);
const long long trackType = pTrack->GetType();
const int frameCount = pBlock->GetFrameCount();
const long long time_ns = pBlock->GetTime(pCluster);
printf("\t\t\tBlock\t\t:%s,%s,%15lld\n",
(trackType == VIDEO_TRACK) ? "V" : "A",
pBlock->IsKey() ? "I" : "P",
time_ns);
for (int i = 0; i < frameCount; ++i)
if (pTrack == NULL)
printf("\t\t\tBlock\t\t:UNKNOWN TRACK TYPE\n");
else
{
const Block::Frame& theFrame = pBlock->GetFrame(i);
const long size = theFrame.len;
const long long offset = theFrame.pos;
printf("\t\t\t %15ld,%15llx\n", size, offset);
const long long trackType = pTrack->GetType();
const int frameCount = pBlock->GetFrameCount();
const long long time_ns = pBlock->GetTime(pCluster);
printf("\t\t\tBlock\t\t:%s,%s,%15lld\n",
(trackType == mkvparser::Track::kVideo) ? "V" : "A",
pBlock->IsKey() ? "I" : "P",
time_ns);
for (int i = 0; i < frameCount; ++i)
{
const Block::Frame& theFrame = pBlock->GetFrame(i);
const long size = theFrame.len;
const long long offset = theFrame.pos;
printf("\t\t\t %15ld,%15llx\n", size, offset);
}
}
pBlockEntry = pCluster->GetNext(pBlockEntry);
status = pCluster->GetNext(pBlockEntry, pBlockEntry);
if (status < 0)
{
printf("\t\t\tError parsing next block of cluster\n");
fflush(stdout);
return -1;
}
}
pCluster = pSegment->GetNext(pCluster);
}
delete pSegment;
fflush(stdout);
return 0;
}

View File

@@ -1,194 +0,0 @@
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="8.00"
Name="sample"
ProjectGUID="{0CB5681F-6065-490C-98C8-05531732ED7E}"
RootNamespace="sample"
Keyword="Win32Proj"
>
<Platforms>
<Platform
Name="Win32"
/>
</Platforms>
<ToolFiles>
</ToolFiles>
<Configurations>
<Configuration
Name="Debug|Win32"
OutputDirectory="$(SolutionDir)$(ConfigurationName)"
IntermediateDirectory="$(ConfigurationName)"
ConfigurationType="1"
CharacterSet="1"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories="..\"
PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE"
MinimalRebuild="false"
BasicRuntimeChecks="3"
RuntimeLibrary="1"
UsePrecompiledHeader="0"
WarningLevel="3"
Detect64BitPortabilityProblems="true"
DebugInformationFormat="1"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies=".\Debug\libwebm.lib"
LinkIncremental="2"
GenerateDebugInformation="true"
SubSystem="1"
TargetMachine="1"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCWebDeploymentTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
<Configuration
Name="Release|Win32"
OutputDirectory="$(SolutionDir)$(ConfigurationName)"
IntermediateDirectory="$(ConfigurationName)"
ConfigurationType="1"
CharacterSet="1"
WholeProgramOptimization="1"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"
RuntimeLibrary="0"
UsePrecompiledHeader="0"
WarningLevel="3"
Detect64BitPortabilityProblems="true"
DebugInformationFormat="3"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies=".\Release\libwebm.lib"
LinkIncremental="1"
GenerateDebugInformation="true"
SubSystem="1"
OptimizeReferences="2"
EnableCOMDATFolding="2"
TargetMachine="1"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCWebDeploymentTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
</Configurations>
<References>
</References>
<Files>
<Filter
Name="Source Files"
Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
>
<File
RelativePath=".\sample.cpp"
>
</File>
</Filter>
<Filter
Name="Header Files"
Filter="h;hpp;hxx;hm;inl;inc;xsd"
UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
>
</Filter>
</Files>
<Globals>
</Globals>
</VisualStudioProject>

View File

@@ -1,193 +1,181 @@
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="9.00"
Name="sample"
ProjectGUID="{0CB5681F-6065-490C-98C8-05531732ED7E}"
RootNamespace="sample"
Keyword="Win32Proj"
TargetFrameworkVersion="131072"
>
<Platforms>
<Platform
Name="Win32"
/>
</Platforms>
<ToolFiles>
</ToolFiles>
<Configurations>
<Configuration
Name="Debug|Win32"
OutputDirectory="$(SolutionDir)$(ConfigurationName)"
IntermediateDirectory="$(ConfigurationName)"
ConfigurationType="1"
CharacterSet="1"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories="..\"
PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE"
MinimalRebuild="false"
BasicRuntimeChecks="3"
RuntimeLibrary="1"
UsePrecompiledHeader="0"
WarningLevel="4"
Detect64BitPortabilityProblems="false"
DebugInformationFormat="1"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies=".\Debug\libwebm.lib"
LinkIncremental="2"
GenerateDebugInformation="true"
SubSystem="1"
RandomizedBaseAddress="1"
DataExecutionPrevention="0"
TargetMachine="1"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
<Configuration
Name="Release|Win32"
OutputDirectory="$(SolutionDir)$(ConfigurationName)"
IntermediateDirectory="$(ConfigurationName)"
ConfigurationType="1"
CharacterSet="1"
WholeProgramOptimization="1"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"
RuntimeLibrary="0"
UsePrecompiledHeader="0"
WarningLevel="3"
Detect64BitPortabilityProblems="false"
DebugInformationFormat="3"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies=".\Release\libwebm.lib"
LinkIncremental="1"
GenerateDebugInformation="true"
SubSystem="1"
OptimizeReferences="2"
EnableCOMDATFolding="2"
RandomizedBaseAddress="1"
DataExecutionPrevention="0"
TargetMachine="1"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
</Configurations>
<References>
</References>
<Files>
<Filter
Name="Source Files"
Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
>
<File
RelativePath=".\sample.cpp"
>
</File>
</Filter>
<Filter
Name="Header Files"
Filter="h;hpp;hxx;hm;inl;inc;xsd"
UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
>
</Filter>
</Files>
<Globals>
</Globals>
</VisualStudioProject>
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="9.00"
Name="sample"
ProjectGUID="{0CB5681F-6065-490C-98C8-05531732ED7E}"
RootNamespace="sample"
Keyword="Win32Proj"
TargetFrameworkVersion="131072"
>
<Platforms>
<Platform
Name="Win32"
/>
</Platforms>
<ToolFiles>
</ToolFiles>
<Configurations>
<Configuration
Name="Debug|Win32"
OutputDirectory="$(ProjectDir)..\exe\libwebm_2008\$(ProjectName)\$(PlatformName)\$(ConfigurationName)"
IntermediateDirectory="$(ProjectDir)..\obj\libwebm_2008\$(ProjectName)\$(PlatformName)\$(ConfigurationName)"
ConfigurationType="1"
CharacterSet="1"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories="..\"
PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE"
MinimalRebuild="false"
BasicRuntimeChecks="3"
RuntimeLibrary="1"
UsePrecompiledHeader="0"
WarningLevel="4"
Detect64BitPortabilityProblems="false"
DebugInformationFormat="1"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="$(ProjectDir)..\lib\libwebm_2008\libwebm\$(PlatformName)\$(ConfigurationName)\libwebm.lib"
LinkIncremental="2"
GenerateDebugInformation="true"
SubSystem="1"
RandomizedBaseAddress="1"
DataExecutionPrevention="0"
TargetMachine="1"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
<Configuration
Name="Release|Win32"
OutputDirectory="$(ProjectDir)..\exe\libwebm_2008\$(ProjectName)\$(PlatformName)\$(ConfigurationName)"
IntermediateDirectory="$(ProjectDir)..\obj\libwebm_2008\$(ProjectName)\$(PlatformName)\$(ConfigurationName)"
ConfigurationType="1"
CharacterSet="1"
WholeProgramOptimization="1"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"
RuntimeLibrary="0"
UsePrecompiledHeader="0"
WarningLevel="3"
Detect64BitPortabilityProblems="false"
DebugInformationFormat="3"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="$(ProjectDir)..\lib\libwebm_2008\libwebm\$(PlatformName)\$(ConfigurationName)\libwebm.lib"
LinkIncremental="1"
GenerateDebugInformation="true"
SubSystem="1"
OptimizeReferences="2"
EnableCOMDATFolding="2"
RandomizedBaseAddress="1"
DataExecutionPrevention="0"
TargetMachine="1"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
</Configurations>
<References>
</References>
<Files>
<File
RelativePath=".\sample.cpp"
>
</File>
</Files>
<Globals>
</Globals>
</VisualStudioProject>

181
sample_2010.vcxproj Normal file
View File

@@ -0,0 +1,181 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug DLL|Win32">
<Configuration>Debug DLL</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release DLL|Win32">
<Configuration>Release DLL</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectName>sample</ProjectName>
<ProjectGuid>{0CB5681F-6065-490C-98C8-05531732ED7E}</ProjectGuid>
<RootNamespace>sample</RootNamespace>
<Keyword>Win32Proj</Keyword>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<CharacterSet>Unicode</CharacterSet>
<WholeProgramOptimization>true</WholeProgramOptimization>
<PlatformToolset>Windows7.1SDK</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release DLL|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<CharacterSet>Unicode</CharacterSet>
<WholeProgramOptimization>true</WholeProgramOptimization>
<PlatformToolset>Windows7.1SDK</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<CharacterSet>Unicode</CharacterSet>
<PlatformToolset>Windows7.1SDK</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug DLL|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<CharacterSet>Unicode</CharacterSet>
<PlatformToolset>Windows7.1SDK</PlatformToolset>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release DLL|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug DLL|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup>
<_ProjectFileVersion>10.0.40219.1</_ProjectFileVersion>
<OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(ProjectDir)..\exe\libwebm_2010\$(ProjectName)\$(Platform)\$(Configuration)\</OutDir>
<OutDir Condition="'$(Configuration)|$(Platform)'=='Debug DLL|Win32'">$(ProjectDir)..\exe\libwebm_2010\$(ProjectName)\$(Platform)\$(Configuration)\</OutDir>
<IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(ProjectDir)..\obj\libwebm_2010\$(ProjectName)\$(Platform)\$(Configuration)\</IntDir>
<IntDir Condition="'$(Configuration)|$(Platform)'=='Debug DLL|Win32'">$(ProjectDir)..\obj\libwebm_2010\$(ProjectName)\$(Platform)\$(Configuration)\</IntDir>
<LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</LinkIncremental>
<LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug DLL|Win32'">true</LinkIncremental>
<OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(ProjectDir)..\exe\libwebm_2010\$(ProjectName)\$(Platform)\$(Configuration)\</OutDir>
<OutDir Condition="'$(Configuration)|$(Platform)'=='Release DLL|Win32'">$(ProjectDir)..\exe\libwebm_2010\$(ProjectName)\$(Platform)\$(Configuration)\</OutDir>
<IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(ProjectDir)..\obj\libwebm_2010\$(ProjectName)\$(Platform)\$(Configuration)\</IntDir>
<IntDir Condition="'$(Configuration)|$(Platform)'=='Release DLL|Win32'">$(ProjectDir)..\obj\libwebm_2010\$(ProjectName)\$(Platform)\$(Configuration)\</IntDir>
<LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</LinkIncremental>
<LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release DLL|Win32'">false</LinkIncremental>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<Optimization>Disabled</Optimization>
<AdditionalIncludeDirectories>..\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<MinimalRebuild>false</MinimalRebuild>
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
<PrecompiledHeader>
</PrecompiledHeader>
<WarningLevel>Level4</WarningLevel>
<DebugInformationFormat>OldStyle</DebugInformationFormat>
</ClCompile>
<Link>
<AdditionalDependencies>$(ProjectDir)..\lib\libwebm_2010\libwebm\$(Platform)\$(Configuration)\libwebm.lib;%(AdditionalDependencies)</AdditionalDependencies>
<GenerateDebugInformation>true</GenerateDebugInformation>
<SubSystem>Console</SubSystem>
<RandomizedBaseAddress>false</RandomizedBaseAddress>
<DataExecutionPrevention>
</DataExecutionPrevention>
<TargetMachine>MachineX86</TargetMachine>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug DLL|Win32'">
<ClCompile>
<Optimization>Disabled</Optimization>
<AdditionalIncludeDirectories>..\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<MinimalRebuild>false</MinimalRebuild>
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
<PrecompiledHeader>
</PrecompiledHeader>
<WarningLevel>Level4</WarningLevel>
<DebugInformationFormat>OldStyle</DebugInformationFormat>
</ClCompile>
<Link>
<AdditionalDependencies>$(ProjectDir)..\lib\libwebm_2010\libwebm\$(Platform)\$(Configuration)\libwebm.lib;%(AdditionalDependencies)</AdditionalDependencies>
<GenerateDebugInformation>true</GenerateDebugInformation>
<SubSystem>Console</SubSystem>
<RandomizedBaseAddress>false</RandomizedBaseAddress>
<DataExecutionPrevention>
</DataExecutionPrevention>
<TargetMachine>MachineX86</TargetMachine>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<PrecompiledHeader>
</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
</ClCompile>
<Link>
<AdditionalDependencies>$(ProjectDir)..\lib\libwebm_2010\libwebm\$(Platform)\$(Configuration)\libwebm.lib;%(AdditionalDependencies)</AdditionalDependencies>
<GenerateDebugInformation>true</GenerateDebugInformation>
<SubSystem>Console</SubSystem>
<OptimizeReferences>true</OptimizeReferences>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<RandomizedBaseAddress>false</RandomizedBaseAddress>
<DataExecutionPrevention>
</DataExecutionPrevention>
<TargetMachine>MachineX86</TargetMachine>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release DLL|Win32'">
<ClCompile>
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
<PrecompiledHeader>
</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
</ClCompile>
<Link>
<AdditionalDependencies>$(ProjectDir)..\lib\libwebm_2010\libwebm\$(Platform)\$(Configuration)\libwebm.lib;%(AdditionalDependencies)</AdditionalDependencies>
<GenerateDebugInformation>true</GenerateDebugInformation>
<SubSystem>Console</SubSystem>
<OptimizeReferences>true</OptimizeReferences>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<RandomizedBaseAddress>false</RandomizedBaseAddress>
<DataExecutionPrevention>
</DataExecutionPrevention>
<TargetMachine>MachineX86</TargetMachine>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="sample.cpp" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="libwebm_2010.vcxproj">
<Project>{7b1f12ca-0724-430b-b61a-1d357c912cba}</Project>
<ReferenceOutputAssembly>false</ReferenceOutputAssembly>
</ProjectReference>
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>

View File

@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<ClCompile Include="sample.cpp" />
</ItemGroup>
</Project>

View File

@@ -9,6 +9,8 @@
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <list>
#include <string>
// libwebm parser includes
#include "mkvreader.hpp"
@@ -19,6 +21,10 @@
#include "mkvwriter.hpp"
#include "mkvmuxerutil.hpp"
#include "sample_muxer_metadata.h"
using mkvmuxer::uint64;
namespace {
void Usage() {
@@ -33,7 +39,6 @@ void Usage() {
printf(" -output_cues <int> >0 outputs cues element\n");
printf(" -cues_on_video_track <int> >0 outputs cues on video track\n");
printf(" -cues_on_audio_track <int> >0 outputs cues on audio track\n");
printf(" 0 outputs cues on audio track\n");
printf(" -max_cluster_duration <double> in seconds\n");
printf(" -max_cluster_size <int> in bytes\n");
printf(" -switch_tracks <int> >0 switches tracks in output\n");
@@ -48,13 +53,91 @@ void Usage() {
printf("\n");
printf("Cues options:\n");
printf(" -output_cues_block_number <int> >0 outputs cue block number\n");
printf(" -cues_before_clusters <int> >0 puts Cues before Clusters\n");
printf("\n");
printf("Metadata options:\n");
printf(" -webvtt-subtitles <vttfile> "
"add WebVTT subtitles as metadata track\n");
printf(" -webvtt-captions <vttfile> "
"add WebVTT captions as metadata track\n");
printf(" -webvtt-descriptions <vttfile> "
"add WebVTT descriptions as metadata track\n");
printf(" -webvtt-metadata <vttfile> "
"add WebVTT subtitles as metadata track\n");
printf(" -webvtt-chapters <vttfile> "
"add WebVTT chapters as MKV chapters element\n");
}
} //end namespace
struct MetadataFile {
const char* name;
SampleMuxerMetadata::Kind kind;
};
typedef std::list<MetadataFile> metadata_files_t;
// Cache the WebVTT filenames specified as command-line args.
bool LoadMetadataFiles(
const metadata_files_t& files,
SampleMuxerMetadata* metadata) {
typedef metadata_files_t::const_iterator iter_t;
iter_t i = files.begin();
const iter_t j = files.end();
while (i != j) {
const metadata_files_t::value_type& v = *i++;
if (!metadata->Load(v.name, v.kind))
return false;
}
return true;
}
int ParseArgWebVTT(
char* argv[],
int* argv_index,
int argc_check,
metadata_files_t* metadata_files) {
int& i = *argv_index;
enum { kCount = 5 };
struct Arg { const char* name; SampleMuxerMetadata::Kind kind; };
const Arg args[kCount] = {
{ "-webvtt-subtitles", SampleMuxerMetadata::kSubtitles },
{ "-webvtt-captions", SampleMuxerMetadata::kCaptions },
{ "-webvtt-descriptions", SampleMuxerMetadata::kDescriptions },
{ "-webvtt-metadata", SampleMuxerMetadata::kMetadata },
{ "-webvtt-chapters", SampleMuxerMetadata::kChapters }
};
for (int idx = 0; idx < kCount; ++idx) {
const Arg& arg = args[idx];
if (strcmp(arg.name, argv[i]) != 0) // no match
continue;
++i; // consume arg name here
if (i > argc_check) {
printf("missing value for %s\n", arg.name);
return -1; // error
}
MetadataFile f;
f.name = argv[i]; // arg value is consumed via caller's loop idx
f.kind = arg.kind;
metadata_files->push_back(f);
return 1; // successfully parsed WebVTT arg
}
return 0; // not a WebVTT arg
}
} // end namespace
int main(int argc, char* argv[]) {
using mkvmuxer::uint64;
char* input = NULL;
char* output = NULL;
@@ -63,13 +146,14 @@ int main(int argc, char* argv[]) {
bool output_audio = true;
bool live_mode = false;
bool output_cues = true;
bool cues_before_clusters = false;
bool cues_on_video_track = true;
bool cues_on_audio_track = true;
bool cues_on_audio_track = false;
uint64 max_cluster_duration = 0;
uint64 max_cluster_size = 0;
bool switch_tracks = false;
int audio_track_number = 0; // 0 tells muxer to decide.
int video_track_number = 0; // 0 tells muxer to decide.
int audio_track_number = 0; // 0 tells muxer to decide.
int video_track_number = 0; // 0 tells muxer to decide.
bool chunking = false;
const char* chunk_name = NULL;
@@ -79,52 +163,65 @@ int main(int argc, char* argv[]) {
uint64 display_height = 0;
uint64 stereo_mode = 0;
metadata_files_t metadata_files;
const int argc_check = argc - 1;
for (int i = 1; i < argc; ++i) {
char* end;
if (!strcmp("-h", argv[i]) || !strcmp("-?", argv[i])) {
Usage();
return EXIT_SUCCESS;
} else if (!strcmp("-i", argv[i])) {
} else if (!strcmp("-i", argv[i]) && i < argc_check) {
input = argv[++i];
} else if (!strcmp("-o", argv[i])) {
} else if (!strcmp("-o", argv[i]) && i < argc_check) {
output = argv[++i];
} else if (!strcmp("-video", argv[i])) {
} else if (!strcmp("-video", argv[i]) && i < argc_check) {
output_video = strtol(argv[++i], &end, 10) == 0 ? false : true;
} else if (!strcmp("-audio", argv[i])) {
} else if (!strcmp("-audio", argv[i]) && i < argc_check) {
output_audio = strtol(argv[++i], &end, 10) == 0 ? false : true;
} else if (!strcmp("-live", argv[i])) {
} else if (!strcmp("-live", argv[i]) && i < argc_check) {
live_mode = strtol(argv[++i], &end, 10) == 0 ? false : true;
} else if (!strcmp("-output_cues", argv[i])) {
} else if (!strcmp("-output_cues", argv[i]) && i < argc_check) {
output_cues = strtol(argv[++i], &end, 10) == 0 ? false : true;
} else if (!strcmp("-cues_on_video_track", argv[i])) {
} else if (!strcmp("-cues_before_clusters", argv[i]) && i < argc_check) {
cues_before_clusters = strtol(argv[++i], &end, 10) == 0 ? false : true;
} else if (!strcmp("-cues_on_video_track", argv[i]) && i < argc_check) {
cues_on_video_track = strtol(argv[++i], &end, 10) == 0 ? false : true;
} else if (!strcmp("-cues_on_audio_track", argv[i])) {
if (cues_on_video_track)
cues_on_audio_track = false;
} else if (!strcmp("-cues_on_audio_track", argv[i]) && i < argc_check) {
cues_on_audio_track = strtol(argv[++i], &end, 10) == 0 ? false : true;
} else if (!strcmp("-max_cluster_duration", argv[i])) {
if (cues_on_audio_track)
cues_on_video_track = false;
} else if (!strcmp("-max_cluster_duration", argv[i]) && i < argc_check) {
const double seconds = strtod(argv[++i], &end);
max_cluster_duration =
static_cast<uint64>(seconds * 1000000000.0);
} else if (!strcmp("-max_cluster_size", argv[i])) {
} else if (!strcmp("-max_cluster_size", argv[i]) && i < argc_check) {
max_cluster_size = strtol(argv[++i], &end, 10);
} else if (!strcmp("-switch_tracks", argv[i])) {
} else if (!strcmp("-switch_tracks", argv[i]) && i < argc_check) {
switch_tracks = strtol(argv[++i], &end, 10) == 0 ? false : true;
} else if (!strcmp("-audio_track_number", argv[i])) {
} else if (!strcmp("-audio_track_number", argv[i]) && i < argc_check) {
audio_track_number = strtol(argv[++i], &end, 10);
} else if (!strcmp("-video_track_number", argv[i])) {
} else if (!strcmp("-video_track_number", argv[i]) && i < argc_check) {
video_track_number = strtol(argv[++i], &end, 10);
} else if (!strcmp("-chunking", argv[i])) {
} else if (!strcmp("-chunking", argv[i]) && i < argc_check) {
chunking = true;
chunk_name = argv[++i];
} else if (!strcmp("-display_width", argv[i])) {
} else if (!strcmp("-display_width", argv[i]) && i < argc_check) {
display_width = strtol(argv[++i], &end, 10);
} else if (!strcmp("-display_height", argv[i])) {
} else if (!strcmp("-display_height", argv[i]) && i < argc_check) {
display_height = strtol(argv[++i], &end, 10);
} else if (!strcmp("-stereo_mode", argv[i])) {
} else if (!strcmp("-stereo_mode", argv[i]) && i < argc_check) {
stereo_mode = strtol(argv[++i], &end, 10);
} else if (!strcmp("-output_cues_block_number", argv[i])) {
} else if (!strcmp("-output_cues_block_number", argv[i]) &&
i < argc_check) {
output_cues_block_number =
strtol(argv[++i], &end, 10) == 0 ? false : true;
} else if (int e = ParseArgWebVTT(argv, &i, argc_check, &metadata_files)) {
if (e < 0)
return EXIT_FAILURE;
}
}
@@ -166,7 +263,8 @@ int main(int argc, char* argv[]) {
// Set muxer header info
mkvmuxer::MkvWriter writer;
if (!writer.Open(output)) {
char* temp_file = tmpnam(NULL);
if (!writer.Open(cues_before_clusters ? temp_file : output)) {
printf("\n Filename is invalid or error while opening.\n");
return EXIT_FAILURE;
}
@@ -199,11 +297,12 @@ int main(int argc, char* argv[]) {
info->set_writing_app("sample_muxer");
// Set Tracks element attributes
enum { kVideoTrack = 1, kAudioTrack = 2 };
const mkvparser::Tracks* const parser_tracks = parser_segment->GetTracks();
unsigned long i = 0;
uint64 vid_track = 0; // no track added
uint64 aud_track = 0; // no track added
uint64 vid_track = 0; // no track added
uint64 aud_track = 0; // no track added
using mkvparser::Track;
while (i != parser_tracks->GetTracksCount()) {
int track_num = i++;
@@ -221,7 +320,7 @@ int main(int argc, char* argv[]) {
const long long track_type = parser_track->GetType();
if (track_type == kVideoTrack && output_video) {
if (track_type == Track::kVideo && output_video) {
// Get the video track from the parser
const mkvparser::VideoTrack* const pVideoTrack =
static_cast<const mkvparser::VideoTrack*>(parser_track);
@@ -259,7 +358,7 @@ int main(int argc, char* argv[]) {
if (rate > 0.0) {
video->set_frame_rate(rate);
}
} else if (track_type == kAudioTrack && output_audio) {
} else if (track_type == Track::kAudio && output_audio) {
// Get the audio track from the parser
const mkvparser::AudioTrack* const pAudioTrack =
static_cast<const mkvparser::AudioTrack*>(parser_track);
@@ -302,6 +401,24 @@ int main(int argc, char* argv[]) {
}
}
// We have created all the video and audio tracks. If any WebVTT
// files were specified as command-line args, then parse them and
// add a track to the output file corresponding to each metadata
// input file.
SampleMuxerMetadata metadata;
if (!metadata.Init(&muxer_segment)) {
printf("\n Could not initialize metadata cache.\n");
return EXIT_FAILURE;
}
if (!LoadMetadataFiles(metadata_files, &metadata))
return EXIT_FAILURE;
if (!metadata.AddChapters())
return EXIT_FAILURE;
// Set Cues element attributes
mkvmuxer::Cues* const cues = muxer_segment.GetCues();
cues->set_output_block_number(output_cues_block_number);
@@ -317,7 +434,14 @@ int main(int argc, char* argv[]) {
const mkvparser::Cluster* cluster = parser_segment->GetFirst();
while ((cluster != NULL) && !cluster->EOS()) {
const mkvparser::BlockEntry* block_entry = cluster->GetFirst();
const mkvparser::BlockEntry* block_entry;
long status = cluster->GetFirst(block_entry);
if (status) {
printf("\n Could not get first block of cluster.\n");
return EXIT_FAILURE;
}
while ((block_entry != NULL) && !block_entry->EOS()) {
const mkvparser::Block* const block = block_entry->GetBlock();
@@ -326,11 +450,16 @@ int main(int argc, char* argv[]) {
parser_tracks->GetTrackByNumber(
static_cast<unsigned long>(trackNum));
const long long track_type = parser_track->GetType();
const long long time_ns = block->GetTime(cluster);
if ((track_type == kAudioTrack && output_audio) ||
(track_type == kVideoTrack && output_video)) {
// Flush any metadata frames to the output file, before we write
// the current block.
if (!metadata.Write(time_ns))
return EXIT_FAILURE;
if ((track_type == Track::kAudio && output_audio) ||
(track_type == Track::kVideo && output_video)) {
const int frame_count = block->GetFrameCount();
const long long time_ns = block->GetTime(cluster);
const bool is_key = block->IsKey();
for (int i = 0; i < frame_count; ++i) {
@@ -348,7 +477,7 @@ int main(int argc, char* argv[]) {
return EXIT_FAILURE;
uint64 track_num = vid_track;
if (track_type == kAudioTrack)
if (track_type == Track::kAudio)
track_num = aud_track;
if (!muxer_segment.AddFrame(data,
@@ -362,22 +491,50 @@ int main(int argc, char* argv[]) {
}
}
block_entry = cluster->GetNext(block_entry);
status = cluster->GetNext(block_entry, block_entry);
if (status) {
printf("\n Could not get next block of cluster.\n");
return EXIT_FAILURE;
}
}
cluster = parser_segment->GetNext(cluster);
}
muxer_segment.Finalize();
// We have exhausted all video and audio frames in the input file.
// Flush any remaining metadata frames to the output file.
if (!metadata.Write(-1))
return EXIT_FAILURE;
if (!muxer_segment.Finalize()) {
printf("Finalization of segment failed.\n");
return EXIT_FAILURE;
}
reader.Close();
writer.Close();
if (cues_before_clusters) {
if (reader.Open(temp_file)) {
printf("\n Filename is invalid or error while opening.\n");
return EXIT_FAILURE;
}
if (!writer.Open(output)) {
printf("\n Filename is invalid or error while opening.\n");
return EXIT_FAILURE;
}
if (!muxer_segment.CopyAndMoveCuesBeforeClusters(&reader, &writer)) {
printf("\n Unable to copy and move cues before clusters.\n");
return EXIT_FAILURE;
}
reader.Close();
writer.Close();
remove(temp_file);
}
delete [] data;
delete parser_segment;
writer.Close();
reader.Close();
return EXIT_SUCCESS;
}

View File

@@ -1,197 +1,179 @@
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="9.00"
Name="sample_muxer"
ProjectGUID="{B407561F-1F5E-4798-B9C2-81AB09CFBC16}"
RootNamespace="sample_muxer"
Keyword="Win32Proj"
TargetFrameworkVersion="196613"
>
<Platforms>
<Platform
Name="Win32"
/>
</Platforms>
<ToolFiles>
</ToolFiles>
<Configurations>
<Configuration
Name="Debug|Win32"
OutputDirectory="$(SolutionDir)$(ConfigurationName)"
IntermediateDirectory="$(ConfigurationName)"
ConfigurationType="1"
CharacterSet="1"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories="../"
PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE"
MinimalRebuild="true"
BasicRuntimeChecks="3"
RuntimeLibrary="1"
UsePrecompiledHeader="0"
WarningLevel="4"
DebugInformationFormat="4"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="..\Debug\libwebm.lib"
LinkIncremental="2"
GenerateDebugInformation="true"
SubSystem="1"
TargetMachine="1"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
<Configuration
Name="Release|Win32"
OutputDirectory="$(SolutionDir)$(ConfigurationName)"
IntermediateDirectory="$(ConfigurationName)"
ConfigurationType="1"
CharacterSet="1"
WholeProgramOptimization="1"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
Optimization="2"
EnableIntrinsicFunctions="true"
AdditionalIncludeDirectories="../"
PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"
RuntimeLibrary="0"
EnableFunctionLevelLinking="true"
UsePrecompiledHeader="0"
WarningLevel="4"
DebugInformationFormat="3"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="..\Release\libwebm.lib"
LinkIncremental="1"
GenerateDebugInformation="true"
SubSystem="1"
OptimizeReferences="2"
EnableCOMDATFolding="2"
TargetMachine="1"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
</Configurations>
<References>
</References>
<Files>
<Filter
Name="Source Files"
Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
>
<File
RelativePath=".\sample_muxer.cpp"
>
</File>
</Filter>
<Filter
Name="Header Files"
Filter="h;hpp;hxx;hm;inl;inc;xsd"
UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
>
</Filter>
<Filter
Name="Resource Files"
Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav"
UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
>
</Filter>
</Files>
<Globals>
</Globals>
</VisualStudioProject>
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="9.00"
Name="sample_muxer"
ProjectGUID="{B407561F-1F5E-4798-B9C2-81AB09CFBC16}"
RootNamespace="sample_muxer"
Keyword="Win32Proj"
TargetFrameworkVersion="196613"
>
<Platforms>
<Platform
Name="Win32"
/>
</Platforms>
<ToolFiles>
</ToolFiles>
<Configurations>
<Configuration
Name="Debug|Win32"
OutputDirectory="$(ProjectDir)..\exe\libwebm_2008\$(ProjectName)\$(PlatformName)\$(ConfigurationName)"
IntermediateDirectory="$(ProjectDir)..\obj\libwebm_2008\$(ProjectName)\$(PlatformName)\$(ConfigurationName)"
ConfigurationType="1"
CharacterSet="1"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories="../"
PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE"
MinimalRebuild="true"
BasicRuntimeChecks="3"
RuntimeLibrary="1"
UsePrecompiledHeader="0"
WarningLevel="4"
DebugInformationFormat="4"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="$(ProjectDir)..\lib\libwebm_2008\libwebm\$(PlatformName)\$(ConfigurationName)\libwebm.lib"
LinkIncremental="2"
GenerateDebugInformation="true"
SubSystem="1"
TargetMachine="1"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
<Configuration
Name="Release|Win32"
OutputDirectory="$(ProjectDir)..\exe\libwebm_2008\$(ProjectName)\$(PlatformName)\$(ConfigurationName)"
IntermediateDirectory="$(ProjectDir)..\obj\libwebm_2008\$(ProjectName)\$(PlatformName)\$(ConfigurationName)"
ConfigurationType="1"
CharacterSet="1"
WholeProgramOptimization="1"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
Optimization="2"
EnableIntrinsicFunctions="true"
AdditionalIncludeDirectories="../"
PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"
RuntimeLibrary="0"
EnableFunctionLevelLinking="true"
UsePrecompiledHeader="0"
WarningLevel="4"
DebugInformationFormat="3"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="$(ProjectDir)..\lib\libwebm_2008\libwebm\$(PlatformName)\$(ConfigurationName)\libwebm.lib"
LinkIncremental="1"
GenerateDebugInformation="true"
SubSystem="1"
OptimizeReferences="2"
EnableCOMDATFolding="2"
TargetMachine="1"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
</Configurations>
<References>
</References>
<Files>
<File
RelativePath=".\sample_muxer.cpp"
>
</File>
</Files>
<Globals>
</Globals>
</VisualStudioProject>

185
sample_muxer_2010.vcxproj Normal file
View File

@@ -0,0 +1,185 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug DLL|Win32">
<Configuration>Debug DLL</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release DLL|Win32">
<Configuration>Release DLL</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectName>sample_muxer</ProjectName>
<ProjectGuid>{B407561F-1F5E-4798-B9C2-81AB09CFBC16}</ProjectGuid>
<RootNamespace>sample_muxer</RootNamespace>
<Keyword>Win32Proj</Keyword>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<CharacterSet>Unicode</CharacterSet>
<WholeProgramOptimization>true</WholeProgramOptimization>
<PlatformToolset>Windows7.1SDK</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release DLL|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<CharacterSet>Unicode</CharacterSet>
<WholeProgramOptimization>true</WholeProgramOptimization>
<PlatformToolset>Windows7.1SDK</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<CharacterSet>Unicode</CharacterSet>
<PlatformToolset>Windows7.1SDK</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug DLL|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<CharacterSet>Unicode</CharacterSet>
<PlatformToolset>Windows7.1SDK</PlatformToolset>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release DLL|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug DLL|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup>
<_ProjectFileVersion>10.0.40219.1</_ProjectFileVersion>
<OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(ProjectDir)..\exe\libwebm_2010\$(ProjectName)\$(Platform)\$(Configuration)\</OutDir>
<OutDir Condition="'$(Configuration)|$(Platform)'=='Debug DLL|Win32'">$(ProjectDir)..\exe\libwebm_2010\$(ProjectName)\$(Platform)\$(Configuration)\</OutDir>
<IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(ProjectDir)..\obj\libwebm_2010\$(ProjectName)\$(Platform)\$(Configuration)\</IntDir>
<IntDir Condition="'$(Configuration)|$(Platform)'=='Debug DLL|Win32'">$(ProjectDir)..\obj\libwebm_2010\$(ProjectName)\$(Platform)\$(Configuration)\</IntDir>
<LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</LinkIncremental>
<LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug DLL|Win32'">true</LinkIncremental>
<OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(ProjectDir)..\exe\libwebm_2010\$(ProjectName)\$(Platform)\$(Configuration)\</OutDir>
<OutDir Condition="'$(Configuration)|$(Platform)'=='Release DLL|Win32'">$(ProjectDir)..\exe\libwebm_2010\$(ProjectName)\$(Platform)\$(Configuration)\</OutDir>
<IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(ProjectDir)..\obj\libwebm_2010\$(ProjectName)\$(Platform)\$(Configuration)\</IntDir>
<IntDir Condition="'$(Configuration)|$(Platform)'=='Release DLL|Win32'">$(ProjectDir)..\obj\libwebm_2010\$(ProjectName)\$(Platform)\$(Configuration)\</IntDir>
<LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</LinkIncremental>
<LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release DLL|Win32'">false</LinkIncremental>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<Optimization>Disabled</Optimization>
<AdditionalIncludeDirectories>../;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<MinimalRebuild>true</MinimalRebuild>
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
<PrecompiledHeader>
</PrecompiledHeader>
<WarningLevel>Level4</WarningLevel>
<DebugInformationFormat>EditAndContinue</DebugInformationFormat>
</ClCompile>
<Link>
<AdditionalDependencies>$(ProjectDir)..\lib\libwebm_2010\libwebm\$(Platform)\$(Configuration)\libwebm.lib;%(AdditionalDependencies)</AdditionalDependencies>
<GenerateDebugInformation>true</GenerateDebugInformation>
<SubSystem>Console</SubSystem>
<TargetMachine>MachineX86</TargetMachine>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug DLL|Win32'">
<ClCompile>
<Optimization>Disabled</Optimization>
<AdditionalIncludeDirectories>../;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<MinimalRebuild>true</MinimalRebuild>
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
<PrecompiledHeader>
</PrecompiledHeader>
<WarningLevel>Level4</WarningLevel>
<DebugInformationFormat>EditAndContinue</DebugInformationFormat>
</ClCompile>
<Link>
<AdditionalDependencies>$(ProjectDir)..\lib\libwebm_2010\libwebm\$(Platform)\$(Configuration)\libwebm.lib;%(AdditionalDependencies)</AdditionalDependencies>
<GenerateDebugInformation>true</GenerateDebugInformation>
<SubSystem>Console</SubSystem>
<TargetMachine>MachineX86</TargetMachine>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<Optimization>MaxSpeed</Optimization>
<IntrinsicFunctions>true</IntrinsicFunctions>
<AdditionalIncludeDirectories>../;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<FunctionLevelLinking>true</FunctionLevelLinking>
<PrecompiledHeader>
</PrecompiledHeader>
<WarningLevel>Level4</WarningLevel>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
</ClCompile>
<Link>
<AdditionalDependencies>$(ProjectDir)..\lib\libwebm_2010\libwebm\$(Platform)\$(Configuration)\libwebm.lib;%(AdditionalDependencies)</AdditionalDependencies>
<GenerateDebugInformation>true</GenerateDebugInformation>
<SubSystem>Console</SubSystem>
<OptimizeReferences>true</OptimizeReferences>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<TargetMachine>MachineX86</TargetMachine>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release DLL|Win32'">
<ClCompile>
<Optimization>MaxSpeed</Optimization>
<IntrinsicFunctions>true</IntrinsicFunctions>
<AdditionalIncludeDirectories>../;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
<FunctionLevelLinking>true</FunctionLevelLinking>
<PrecompiledHeader>
</PrecompiledHeader>
<WarningLevel>Level4</WarningLevel>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
</ClCompile>
<Link>
<AdditionalDependencies>$(ProjectDir)..\lib\libwebm_2010\libwebm\$(Platform)\$(Configuration)\libwebm.lib;%(AdditionalDependencies)</AdditionalDependencies>
<GenerateDebugInformation>true</GenerateDebugInformation>
<SubSystem>Console</SubSystem>
<OptimizeReferences>true</OptimizeReferences>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<TargetMachine>MachineX86</TargetMachine>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="sample_muxer.cpp" />
<ClCompile Include="sample_muxer_metadata.cc" />
<ClCompile Include="vttreader.cc" />
<ClCompile Include="webvttparser.cc" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="libwebm_2010.vcxproj">
<Project>{7b1f12ca-0724-430b-b61a-1d357c912cba}</Project>
<ReferenceOutputAssembly>false</ReferenceOutputAssembly>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<ClInclude Include="sample_muxer_metadata.h" />
<ClInclude Include="vttreader.h" />
<ClInclude Include="webvttparser.h" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>

View File

@@ -0,0 +1,14 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<ClCompile Include="sample_muxer.cpp" />
<ClCompile Include="sample_muxer_metadata.cc" />
<ClCompile Include="vttreader.cc" />
<ClCompile Include="webvttparser.cc" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="sample_muxer_metadata.h" />
<ClInclude Include="vttreader.h" />
<ClInclude Include="webvttparser.h" />
</ItemGroup>
</Project>

379
sample_muxer_metadata.cc Normal file
View File

@@ -0,0 +1,379 @@
#include "sample_muxer_metadata.h"
#include <string>
#include "vttreader.h"
SampleMuxerMetadata::SampleMuxerMetadata() : segment_(NULL) {
}
bool SampleMuxerMetadata::Init(mkvmuxer::Segment* segment) {
if (segment == NULL || segment_ != NULL)
return false;
segment_ = segment;
return true;
}
bool SampleMuxerMetadata::Load(const char* file, Kind kind) {
if (kind == kChapters)
return LoadChapters(file);
mkvmuxer::uint64 track_num;
if (!AddTrack(kind, &track_num)) {
printf("Unable to add track for WebVTT file \"%s\"\n", file);
return false;
}
return Parse(file, kind, track_num);
}
bool SampleMuxerMetadata::AddChapters() {
typedef cue_list_t::const_iterator iter_t;
iter_t i = chapter_cues_.begin();
const iter_t j = chapter_cues_.end();
while (i != j) {
const cue_t& chapter = *i++;
if (!AddChapter(chapter))
return false;
}
return true;
}
bool SampleMuxerMetadata::Write(mkvmuxer::int64 time_ns) {
typedef cues_set_t::iterator iter_t;
iter_t i = cues_set_.begin();
const iter_t j = cues_set_.end();
while (i != j) {
const cues_set_t::value_type& v = *i;
if (time_ns >= 0 && v > time_ns)
return true; // nothing else to do just yet
if (!v.Write(segment_)) {
printf("\nCould not add metadata.\n");
return false; // error
}
cues_set_.erase(i++);
}
return true;
}
bool SampleMuxerMetadata::LoadChapters(const char* file) {
if (!chapter_cues_.empty()) {
printf("Support for more than one chapters file is not yet implemented\n");
return false;
}
cue_list_t cues;
if (!ParseChapters(file, &cues))
return false;
// TODO(matthewjheaney): support more than one chapters file
chapter_cues_.swap(cues);
return true;
}
bool SampleMuxerMetadata::ParseChapters(
const char* file,
cue_list_t* cues_ptr) {
cue_list_t& cues = *cues_ptr;
cues.clear();
libwebvtt::VttReader r;
int e = r.Open(file);
if (e) {
printf("Unable to open WebVTT file: \"%s\"\n", file);
return false;
}
libwebvtt::Parser p(&r);
e = p.Init();
if (e < 0) { // error
printf("Error parsing WebVTT file: \"%s\"\n", file);
return false;
}
libwebvtt::Time t;
t.hours = -1;
for (;;) {
cue_t c;
e = p.Parse(&c);
if (e < 0) { // error
printf("Error parsing WebVTT file: \"%s\"\n", file);
return false;
}
if (e > 0) // EOF
return true;
if (c.start_time < t) {
printf("bad WebVTT cue timestamp (out-of-order)\n");
return false;
}
if (c.stop_time < c.start_time) {
printf("bad WebVTT cue timestamp (stop < start)\n");
return false;
}
t = c.start_time;
cues.push_back(c);
}
}
bool SampleMuxerMetadata::AddChapter(const cue_t& cue) {
// TODO(matthewjheaney): support language and country
mkvmuxer::Chapter* const chapter = segment_->AddChapter();
if (chapter == NULL) {
printf("Unable to add chapter\n");
return false;
}
if (cue.identifier.empty()) {
chapter->set_id(NULL);
} else {
const char* const id = cue.identifier.c_str();
if (!chapter->set_id(id)) {
printf("Unable to set chapter id\n");
return false;
}
}
typedef libwebvtt::presentation_t time_ms_t;
const time_ms_t start_time_ms = cue.start_time.presentation();
const time_ms_t stop_time_ms = cue.stop_time.presentation();
enum { kNsPerMs = 1000000 };
const mkvmuxer::uint64 start_time_ns = start_time_ms * kNsPerMs;
const mkvmuxer::uint64 stop_time_ns = stop_time_ms * kNsPerMs;
chapter->set_time(*segment_, start_time_ns, stop_time_ns);
typedef libwebvtt::Cue::payload_t::const_iterator iter_t;
iter_t i = cue.payload.begin();
const iter_t j = cue.payload.end();
std::string title;
for (;;) {
title += *i++;
if (i == j)
break;
enum { kLF = '\x0A' };
title += kLF;
}
if (!chapter->add_string(title.c_str(), NULL, NULL)) {
printf("Unable to set chapter title\n");
return false;
}
return true;
}
bool SampleMuxerMetadata::AddTrack(
Kind kind,
mkvmuxer::uint64* track_num) {
*track_num = 0;
// Track number value 0 means "let muxer choose track number"
mkvmuxer::Track* const track = segment_->AddTrack(0);
if (track == NULL) // error
return false;
// Return the track number value chosen by the muxer
*track_num = track->number();
int type;
const char* codec_id;
switch (kind) {
case kSubtitles:
type = 0x11;
codec_id = "D_WEBVTT/SUBTITLES";
break;
case kCaptions:
type = 0x11;
codec_id = "D_WEBVTT/CAPTIONS";
break;
case kDescriptions:
type = 0x21;
codec_id = "D_WEBVTT/DESCRIPTIONS";
break;
case kMetadata:
type = 0x21;
codec_id = "D_WEBVTT/METADATA";
break;
default:
return false;
}
track->set_type(type);
track->set_codec_id(codec_id);
// TODO(matthewjheaney): set name and language
return true;
}
bool SampleMuxerMetadata::Parse(
const char* file,
Kind /* kind */,
mkvmuxer::uint64 track_num) {
libwebvtt::VttReader r;
int e = r.Open(file);
if (e) {
printf("Unable to open WebVTT file: \"%s\"\n", file);
return false;
}
libwebvtt::Parser p(&r);
e = p.Init();
if (e < 0) { // error
printf("Error parsing WebVTT file: \"%s\"\n", file);
return false;
}
SortableCue cue;
cue.track_num = track_num;
libwebvtt::Time t;
t.hours = -1;
for (;;) {
cue_t& c = cue.cue;
e = p.Parse(&c);
if (e < 0) { // error
printf("Error parsing WebVTT file: \"%s\"\n", file);
return false;
}
if (e > 0) // EOF
return true;
if (c.start_time >= t) {
t = c.start_time;
} else {
printf("bad WebVTT cue timestamp (out-of-order)\n");
return false;
}
if (c.stop_time < c.start_time) {
printf("bad WebVTT cue timestamp (stop < start)\n");
return false;
}
cues_set_.insert(cue);
}
}
void SampleMuxerMetadata::MakeFrame(const cue_t& c, std::string* pf) {
pf->clear();
WriteCueIdentifier(c.identifier, pf);
WriteCueSettings(c.settings, pf);
WriteCuePayload(c.payload, pf);
}
void SampleMuxerMetadata::WriteCueIdentifier(
const std::string& identifier,
std::string* pf) {
pf->append(identifier);
pf->push_back('\x0A'); // LF
}
void SampleMuxerMetadata::WriteCueSettings(
const cue_t::settings_t& settings,
std::string* pf) {
if (settings.empty()) {
pf->push_back('\x0A'); // LF
return;
}
typedef cue_t::settings_t::const_iterator iter_t;
iter_t i = settings.begin();
const iter_t j = settings.end();
for (;;) {
const libwebvtt::Setting& setting = *i++;
pf->append(setting.name);
pf->push_back(':');
pf->append(setting.value);
if (i == j)
break;
pf->push_back(' '); // separate settings with whitespace
}
pf->push_back('\x0A'); // LF
}
void SampleMuxerMetadata::WriteCuePayload(
const cue_t::payload_t& payload,
std::string* pf) {
typedef cue_t::payload_t::const_iterator iter_t;
iter_t i = payload.begin();
const iter_t j = payload.end();
while (i != j) {
const std::string& line = *i++;
pf->append(line);
pf->push_back('\x0A'); // LF
}
}
bool SampleMuxerMetadata::SortableCue::Write(
mkvmuxer::Segment* segment) const {
// Cue start time expressed in milliseconds
const mkvmuxer::int64 start_ms = cue.start_time.presentation();
// Cue start time expressed in nanoseconds (MKV time)
const mkvmuxer::int64 start_ns = start_ms * 1000000;
// Cue stop time expressed in milliseconds
const mkvmuxer::int64 stop_ms = cue.stop_time.presentation();
// Cue stop time expressed in nanonseconds
const mkvmuxer::int64 stop_ns = stop_ms * 1000000;
// Metadata blocks always specify the block duration.
const mkvmuxer::int64 duration_ns = stop_ns - start_ns;
std::string frame;
MakeFrame(cue, &frame);
typedef const mkvmuxer::uint8* data_t;
const data_t buf = reinterpret_cast<data_t>(frame.data());
const mkvmuxer::uint64 len = frame.length();
return segment->AddMetadata(buf, len, track_num, start_ns, duration_ns);
}

135
sample_muxer_metadata.h Normal file
View File

@@ -0,0 +1,135 @@
// Copyright (c) 2012 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.
#ifndef SAMPLE_MUXER_METADATA_H_ // NOLINT
#define SAMPLE_MUXER_METADATA_H_
#include <list>
#include <set>
#include "mkvmuxer.hpp"
#include "webvttparser.h"
class SampleMuxerMetadata {
public:
enum Kind {
kSubtitles,
kCaptions,
kDescriptions,
kMetadata,
kChapters
};
SampleMuxerMetadata();
// Bind this metadata object to the muxer instance. Returns false
// if segment equals NULL, or Init has already been called.
bool Init(mkvmuxer::Segment* segment);
// Parse the WebVTT file |filename| having the indicated |kind|, and
// create a corresponding track (or chapters element) in the
// segment. Returns false on error.
bool Load(const char* filename, Kind kind);
bool AddChapters();
// Write any WebVTT cues whose time is less or equal to |time_ns| as
// a metadata block in its corresponding track. If |time_ns| is
// negative, write all remaining cues. Returns false on error.
bool Write(mkvmuxer::int64 time_ns);
private:
typedef libwebvtt::Cue cue_t;
// Used to sort cues as they are loaded.
struct SortableCue {
bool operator>(mkvmuxer::int64 time_ns) const {
// Cue start time expressed in milliseconds
const mkvmuxer::int64 start_ms = cue.start_time.presentation();
// Cue start time expressed in nanoseconds (MKV time)
const mkvmuxer::int64 start_ns = start_ms * 1000000;
return (start_ns > time_ns);
}
bool operator<(const SortableCue& rhs) const {
if (cue.start_time < rhs.cue.start_time)
return true;
if (cue.start_time > rhs.cue.start_time)
return false;
return (track_num < rhs.track_num);
}
// Write this cue as a metablock to |segment|. Returns false on
// error.
bool Write(mkvmuxer::Segment* segment) const;
mkvmuxer::uint64 track_num;
cue_t cue;
};
typedef std::multiset<SortableCue> cues_set_t;
typedef std::list<cue_t> cue_list_t;
// Parse the WebVTT cues in the named |file|, returning false on
// error. We handle chapters as a special case, because they are
// stored in their own, dedicated level-1 element.
bool LoadChapters(const char* file);
// Parse the WebVTT chapters in |file| to populate |cues|. Returns
// false on error.
static bool ParseChapters(const char* file,
cue_list_t* cues);
// Adds WebVTT cue |chapter| to the chapters element of the output
// file's segment element. Returns false on error.
bool AddChapter(const cue_t& chapter);
// Add a metadata track to the segment having the indicated |kind|,
// returning the |track_num| that has been chosen for this track.
// Returns false on error.
bool AddTrack(Kind kind, mkvmuxer::uint64* track_num);
// Parse the WebVTT |file| having the indicated |kind| and
// |track_num|, adding each parsed cue to cues set. Returns false
// on error.
bool Parse(const char* file, Kind kind, mkvmuxer::uint64 track_num);
// Converts a WebVTT cue to a Matroska metadata block.
static void MakeFrame(const cue_t& cue, std::string* frame);
// Populate the cue identifier part of the metadata block.
static void WriteCueIdentifier(const std::string& identifier,
std::string* frame);
// Populate the cue settings part of the metadata block.
static void WriteCueSettings(const cue_t::settings_t& settings,
std::string* frame);
// Populate the payload part of the metadata block.
static void WriteCuePayload(const cue_t::payload_t& payload,
std::string* frame);
mkvmuxer::Segment* segment_;
// Set of cues ordered by time and then by track number.
cues_set_t cues_set_;
// The cues that will be used to populate the Chapters level-1
// element of the output file.
cue_list_t chapter_cues_;
// Disable copy ctor and copy assign.
SampleMuxerMetadata(const SampleMuxerMetadata&);
SampleMuxerMetadata& operator=(const SampleMuxerMetadata&);
};
#endif // SAMPLE_MUXER_METADATA_H_ // NOLINT

1037
vttdemux.cc Normal file

File diff suppressed because it is too large Load Diff

57
vttreader.cc Normal file
View File

@@ -0,0 +1,57 @@
// Copyright (c) 2012 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 "./vttreader.h" // NOLINT
namespace libwebvtt {
VttReader::VttReader() : file_(NULL) {
}
VttReader::~VttReader() {
Close();
}
int VttReader::Open(const char* filename) {
if (filename == NULL || file_ != NULL)
return -1;
file_ = fopen(filename, "rb");
if (file_ == NULL)
return -1;
return 0; // success
}
void VttReader::Close() {
if (file_) {
fclose(file_);
file_ = NULL;
}
}
int VttReader::GetChar(char* c) {
if (c == NULL || file_ == NULL)
return -1;
const int result = fgetc(file_);
if (result != EOF) {
*c = static_cast<char>(result);
return 0; // success
}
if (ferror(file_))
return -1; // error
if (feof(file_))
return 1; // EOF
return -1; // weird
}
} // namespace libwebvtt

44
vttreader.h Normal file
View File

@@ -0,0 +1,44 @@
// Copyright (c) 2012 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.
#ifndef VTTREADER_H_ // NOLINT
#define VTTREADER_H_
#include <cstdio>
#include "./webvttparser.h"
namespace libwebvtt {
class VttReader : public libwebvtt::Reader {
public:
VttReader();
virtual ~VttReader();
// Open the file identified by |filename| in read-only mode, as a
// binary stream of bytes. Returns 0 on success, negative if error.
int Open(const char* filename);
// Closes the file stream. Note that the stream is automatically
// closed when the VttReader object is destroyed.
void Close();
// Reads the next character in the file stream, as per the semantics
// of Reader::GetChar. Returns negative if error, 0 on success, and
// positive if end-of-stream has been reached.
virtual int GetChar(char* c);
private:
FILE* file_;
VttReader(const VttReader&);
VttReader& operator=(const VttReader&);
};
} // namespace libwebvtt
#endif // VTTREADER_H_ // NOLINT

View File

@@ -1,4 +1,4 @@
// Copyright (c) 2011 The WebM project authors. All Rights Reserved.
// Copyright (c) 2012 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
@@ -53,6 +53,10 @@ enum MkvId {
kMkvReferenceBlock = 0xFB,
kMkvLaceNumber = 0xCC,
kMkvSimpleBlock = 0xA3,
kMkvBlockAdditions = 0x75A1,
kMkvBlockMore = 0xA6,
kMkvBlockAddID = 0xEE,
kMkvBlockAdditional = 0xA5,
//Track
kMkvTracks = 0x1654AE6B,
kMkvTrackEntry = 0xAE,
@@ -69,10 +73,12 @@ enum MkvId {
kMkvCodecID = 0x86,
kMkvCodecPrivate = 0x63A2,
kMkvCodecName = 0x258688,
kMkvMaxBlockAdditionID = 0x55EE,
//video
kMkvVideo = 0xE0,
kMkvFlagInterlaced = 0x9A,
kMkvStereoMode = 0x53B8,
kMkvAlphaMode = 0x53C0,
kMkvPixelWidth = 0xB0,
kMkvPixelHeight = 0xBA,
kMkvPixelCropBottom = 0x54AA,
@@ -101,6 +107,9 @@ enum MkvId {
kMkvContentEncryption = 0x5035,
kMkvContentEncAlgo = 0x47E1,
kMkvContentEncKeyID = 0x47E2,
kMkvContentEncAESSettings = 0x47E7,
kMkvAESSettingsCipherMode = 0x47E8,
kMkvAESSettingsCipherInitData = 0x47E9,
//end ContentEncodings
//Cueing Data
kMkvCues = 0x1C53BB6B,
@@ -110,8 +119,20 @@ enum MkvId {
kMkvCueTrack = 0xF7,
kMkvCueClusterPosition = 0xF1,
kMkvCueBlockNumber = 0x5378,
//Chapters
kMkvChapters = 0x1043A770,
kMkvEditionEntry = 0x45B9,
kMkvChapterAtom = 0xB6,
kMkvChapterUID = 0x73C4,
kMkvChapterStringUID = 0x5654,
kMkvChapterTimeStart = 0x91,
kMkvChapterTimeEnd = 0x92,
kMkvChapterDisplay = 0x80,
kMkvChapString = 0x85,
kMkvChapLanguage = 0x437C,
kMkvChapCountry = 0x437E
};
} // end namespace mkvmuxer
#endif // WEBMIDS_HPP
#endif // WEBMIDS_HPP

725
webvttparser.cc Normal file
View File

@@ -0,0 +1,725 @@
// Copyright (c) 2012 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 "./webvttparser.h" // NOLINT
#include <climits>
namespace libwebvtt {
enum {
kNUL = '\x00',
kSPACE = ' ',
kTAB = '\x09',
kLF = '\x0A',
kCR = '\x0D'
};
Reader::~Reader() {
}
LineReader::~LineReader() {
}
int LineReader::GetLine(std::string* line_ptr) {
if (line_ptr == NULL)
return -1;
std::string& ln = *line_ptr;
ln.clear();
// Consume characters from the stream, until we
// reach end-of-line (or end-of-stream).
// The WebVTT spec states that lines may be
// terminated in any of these three ways:
// LF
// CR
// CR LF
// We interrogate each character as we read it from the stream.
// If we detect an end-of-line character, we consume the full
// end-of-line indication, and we're done; otherwise, accumulate
// the character and repeat.
for (;;) {
char c;
const int e = GetChar(&c);
if (e < 0) // error
return e;
if (e > 0) // EOF
return (ln.empty()) ? 1 : 0;
// We have a character, so we must first determine
// whether we have reached end-of-line.
if (c == kLF)
return 0; // handle the easy end-of-line case immediately
if (c == kCR)
break; // handle the hard end-of-line case outside of loop
if (c == '\xFE' || c == '\xFF') // not UTF-8
return -1;
// To defend against pathological or malicious streams, we
// cap the line length at some arbitrarily-large value:
enum { kMaxLineLength = 10000 }; // arbitrary
if (ln.length() >= kMaxLineLength)
return -1;
// We don't have an end-of-line character, so accumulate
// the character in our line buffer.
ln.push_back(c);
}
// We detected a CR. We must interrogate the next character
// in the stream, to determine whether we have a LF (which
// would make it part of this same line).
char c;
const int e = GetChar(&c);
if (e < 0) // error
return e;
if (e > 0) // EOF
return 0;
// If next character in the stream is not a LF, return it
// to the stream (because it's part of the next line).
if (c != kLF)
UngetChar(c);
return 0;
}
Parser::Parser(Reader* r) : reader_(r), unget_(-1) {
}
Parser::~Parser() {
}
int Parser::Init() {
int e = ParseBOM();
if (e < 0) // error
return e;
if (e > 0) // EOF
return -1;
// Parse "WEBVTT". We read from the stream one character at-a-time, in
// order to defend against non-WebVTT streams (e.g. binary files) that don't
// happen to comprise lines of text demarcated with line terminators.
const char kId[] = "WEBVTT";
for (const char* p = kId; *p; ++p) {
char c;
e = GetChar(&c);
if (e < 0) // error
return e;
if (e > 0) // EOF
return -1;
if (c != *p)
return -1;
}
std::string line;
e = GetLine(&line);
if (e < 0) // error
return e;
if (e > 0) // EOF
return 0; // weird but valid
if (!line.empty()) {
// Parse optional characters that follow "WEBVTT"
const char c = line[0];
if (c != kSPACE && c != kTAB)
return -1;
}
// The WebVTT spec requires that the "WEBVTT" line
// be followed by an empty line (to separate it from
// first cue).
e = GetLine(&line);
if (e < 0) // error
return e;
if (e > 0) // EOF
return 0; // weird but we allow it
if (!line.empty())
return -1;
return 0; // success
}
int Parser::Parse(Cue* cue) {
if (cue == NULL)
return -1;
// Parse first non-blank line
std::string line;
int e;
for (;;) {
e = GetLine(&line);
if (e) // EOF is OK here
return e;
if (!line.empty())
break;
}
// A WebVTT cue comprises an optional cue identifier line followed
// by a (non-optional) timings line. You determine whether you have
// a timings line by scanning for the arrow token, the lexeme of which
// may not appear in the cue identifier line.
const char kArrow[] = "-->";
std::string::size_type arrow_pos = line.find(kArrow);
if (arrow_pos != std::string::npos) {
// We found a timings line, which implies that we don't have a cue
// identifier.
cue->identifier.clear();
} else {
// We did not find a timings line, so we assume that we have a cue
// identifier line, and then try again to find the cue timings on
// the next line.
cue->identifier.swap(line);
e = GetLine(&line);
if (e < 0) // error
return e;
if (e > 0) // EOF
return -1;
arrow_pos = line.find(kArrow);
if (arrow_pos == std::string::npos) // not a timings line
return -1;
}
e = ParseTimingsLine(&line,
arrow_pos,
&cue->start_time,
&cue->stop_time,
&cue->settings);
if (e) // error
return e;
// The cue payload comprises all the non-empty
// lines that follow the timings line.
Cue::payload_t& p = cue->payload;
p.clear();
for (;;) {
e = GetLine(&line);
if (e < 0) // error
return e;
if (line.empty())
break;
p.push_back(line);
}
if (p.empty())
return -1;
return 0; // success
}
int Parser::GetChar(char* c) {
if (unget_ >= 0) {
*c = static_cast<char>(unget_);
unget_ = -1;
return 0;
}
return reader_->GetChar(c);
}
void Parser::UngetChar(char c) {
unget_ = static_cast<unsigned char>(c);
}
int Parser::ParseBOM() {
// Explanation of UTF-8 BOM:
// http://en.wikipedia.org/wiki/Byte_order_mark
static const char BOM[] = "\xEF\xBB\xBF"; // UTF-8 BOM
for (int i = 0; i < 3; ++i) {
char c;
int e = GetChar(&c);
if (e < 0) // error
return e;
if (e > 0) // EOF
return 1;
if (c != BOM[i]) {
if (i == 0) { // we don't have a BOM
UngetChar(c);
return 0; // success
}
// We started a BOM, so we must finish the BOM.
return -1; // error
}
}
return 0; // success
}
int Parser::ParseTimingsLine(
std::string* line_ptr,
std::string::size_type arrow_pos,
Time* start_time,
Time* stop_time,
Cue::settings_t* settings) {
if (line_ptr == NULL)
return -1;
std::string& line = *line_ptr;
if (arrow_pos == std::string::npos || arrow_pos >= line.length())
return -1;
// Place a NUL character at the start of the arrow token, in
// order to demarcate the start time from remainder of line.
line[arrow_pos] = kNUL;
std::string::size_type idx = 0;
int e = ParseTime(line, &idx, start_time);
if (e) // error
return e;
// Detect any junk that follows the start time,
// but precedes the arrow symbol.
while (char c = line[idx]) {
if (c != kSPACE && c != kTAB)
return -1;
++idx;
}
// Place a NUL character at the end of the line,
// so the scanner has a place to stop, and begin
// the scan just beyond the arrow token.
line.push_back(kNUL);
idx = arrow_pos + 3;
e = ParseTime(line, &idx, stop_time);
if (e) // error
return e;
e = ParseSettings(line, idx, settings);
if (e) // error
return e;
return 0; // success
}
int Parser::ParseTime(
const std::string& line,
std::string::size_type* idx_ptr,
Time* time) {
if (idx_ptr == NULL)
return -1;
std::string::size_type& idx = *idx_ptr;
if (idx == std::string::npos || idx >= line.length())
return -1;
if (time == NULL)
return -1;
// Consume any whitespace that precedes the timestamp.
while (char c = line[idx]) {
if (c != kSPACE && c != kTAB)
break;
++idx;
}
// WebVTT timestamp syntax comes in three flavors:
// SS[.sss]
// MM:SS[.sss]
// HH:MM:SS[.sss]
// Parse a generic number value. We don't know which component
// of the time we have yet, until we do more parsing.
int val = ParseNumber(line, &idx);
if (val < 0) // error
return val;
Time& t = *time;
// The presence of a colon character indicates that we have
// an [HH:]MM:SS style syntax.
if (line[idx] == ':') {
// We have either HH:MM:SS or MM:SS
// The value we just parsed is either the hours or minutes.
// It must be followed by another number value (that is
// either minutes or seconds).
const int first_val = val;
++idx; // consume colon
// Parse second value
val = ParseNumber(line, &idx);
if (val < 0)
return val;
if (val >= 60) // either MM or SS
return -1;
if (line[idx] == ':') {
// We have HH:MM:SS
t.hours = first_val;
t.minutes = val; // vetted above
++idx; // consume MM:SS colon
// We have parsed the hours and minutes.
// We must now parse the seconds.
val = ParseNumber(line, &idx);
if (val < 0)
return val;
if (val >= 60) // SS part of HH:MM:SS
return -1;
t.seconds = val;
} else {
// We have MM:SS
// The implication here is that the hour value was omitted
// from the timestamp (because it was 0).
if (first_val >= 60) // minutes
return -1;
t.hours = 0;
t.minutes = first_val;
t.seconds = val; // vetted above
}
} else {
// We have SS (only)
// The time is expressed as total number of seconds,
// so the seconds value has no upper bound.
t.seconds = val;
// Convert SS to HH:MM:SS
t.minutes = t.seconds / 60;
t.seconds -= t.minutes * 60;
t.hours = t.minutes / 60;
t.minutes -= t.hours * 60;
}
// We have parsed the hours, minutes, and seconds.
// We must now parse the milliseconds.
char c = line[idx];
// TODO(matthewjheaney): one option here is to slightly relax the
// syntax rules for WebVTT timestamps, to permit the comma character
// to also be used as the seconds/milliseconds separator. This
// would handle streams that use localization conventions for
// countries in Western Europe. For now we obey the rules specified
// in the WebVTT spec (allow "full stop" only).
const bool have_milliseconds = (c == '.');
if (!have_milliseconds) {
t.milliseconds = 0;
} else {
++idx; // consume FULL STOP
val = ParseNumber(line, &idx);
if (val < 0)
return val;
if (val >= 1000)
return -1;
if (val < 10)
t.milliseconds = val * 100;
else if (val < 100)
t.milliseconds = val * 10;
else
t.milliseconds = val;
}
// We have parsed the time proper. We must check for any
// junk that immediately follows the time specifier.
c = line[idx];
if (c != kNUL && c != kSPACE && c != kTAB)
return -1;
return 0; // success
}
int Parser::ParseSettings(
const std::string& line,
std::string::size_type idx,
Cue::settings_t* settings) {
settings->clear();
if (idx == std::string::npos || idx >= line.length())
return -1;
for (;;) {
// We must parse a line comprising a sequence of 0 or more
// NAME:VALUE pairs, separated by whitespace. The line iself is
// terminated with a NUL char (indicating end-of-line).
for (;;) {
const char c = line[idx];
if (c == kNUL) // end-of-line
return 0; // success
if (c != kSPACE && c != kTAB)
break;
++idx; // consume whitespace
}
// We have consumed the whitespace, and have not yet reached
// end-of-line, so there is something on the line for us to parse.
settings->push_back(Setting());
Setting& s = settings->back();
// Parse the NAME part of the settings pair.
for (;;) {
const char c = line[idx];
if (c == ':') // we have reached end of NAME part
break;
if (c == kNUL || c == kSPACE || c == kTAB)
return -1;
s.name.push_back(c);
++idx;
}
if (s.name.empty())
return -1;
++idx; // consume colon
// Parse the VALUE part of the settings pair.
for (;;) {
const char c = line[idx];
if (c == kNUL || c == kSPACE || c == kTAB)
break;
if (c == ':') // suspicious when part of VALUE
return -1; // TODO(matthewjheaney): verify this behavior
s.value.push_back(c);
++idx;
}
if (s.value.empty())
return -1;
}
}
int Parser::ParseNumber(
const std::string& line,
std::string::size_type* idx_ptr) {
if (idx_ptr == NULL)
return -1;
std::string::size_type& idx = *idx_ptr;
if (idx == std::string::npos || idx >= line.length())
return -1;
if (!isdigit(line[idx]))
return -1;
int result = 0;
while (isdigit(line[idx])) {
const char c = line[idx];
const int i = c - '0';
if (result > INT_MAX / 10)
return -1;
result *= 10;
if (result > INT_MAX - i)
return -1;
result += i;
++idx;
}
return result;
}
bool Time::operator==(const Time& rhs) const {
if (hours != rhs.hours)
return false;
if (minutes != rhs.minutes)
return false;
if (seconds != rhs.seconds)
return false;
return (milliseconds == rhs.milliseconds);
}
bool Time::operator<(const Time& rhs) const {
if (hours < rhs.hours)
return true;
if (hours > rhs.hours)
return false;
if (minutes < rhs.minutes)
return true;
if (minutes > rhs.minutes)
return false;
if (seconds < rhs.seconds)
return true;
if (seconds > rhs.seconds)
return false;
return (milliseconds < rhs.milliseconds);
}
bool Time::operator>(const Time& rhs) const {
return rhs.operator<(*this);
}
bool Time::operator<=(const Time& rhs) const {
return !this->operator>(rhs);
}
bool Time::operator>=(const Time& rhs) const {
return !this->operator<(rhs);
}
presentation_t Time::presentation() const {
const presentation_t h = 1000LL * 3600LL * presentation_t(hours);
const presentation_t m = 1000LL * 60LL * presentation_t(minutes);
const presentation_t s = 1000LL * presentation_t(seconds);
const presentation_t result = h + m + s + milliseconds;
return result;
}
Time& Time::presentation(presentation_t d) {
if (d < 0) { // error
hours = 0;
minutes = 0;
seconds = 0;
milliseconds = 0;
return *this;
}
seconds = d / 1000;
milliseconds = d - 1000 * seconds;
minutes = seconds / 60;
seconds -= 60 * minutes;
hours = minutes / 60;
minutes -= 60 * hours;
return *this;
}
Time& Time::operator+=(presentation_t rhs) {
const presentation_t d = this->presentation();
const presentation_t dd = d + rhs;
this->presentation(dd);
return *this;
}
Time Time::operator+(presentation_t d) const {
Time t(*this);
t += d;
return t;
}
Time& Time::operator-=(presentation_t d) {
return this->operator+=(-d);
}
presentation_t Time::operator-(const Time& t) const {
const presentation_t rhs = t.presentation();
const presentation_t lhs = this->presentation();
const presentation_t result = lhs - rhs;
return result;
}
} // namespace libwebvtt

162
webvttparser.h Normal file
View File

@@ -0,0 +1,162 @@
// Copyright (c) 2012 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.
#ifndef WEBVTTPARSER_H_ // NOLINT
#define WEBVTTPARSER_H_
#include <list>
#include <string>
namespace libwebvtt {
class Reader {
public:
// Fetch a character from the stream. Return
// negative if error, positive if end-of-stream,
// and 0 if a character is available.
virtual int GetChar(char* c) = 0;
protected:
virtual ~Reader();
};
class LineReader : protected Reader {
public:
// Consume a line of text from the stream, stripping off
// the line terminator characters. Returns negative if error,
// 0 on success, and positive at end-of-stream.
int GetLine(std::string* line);
protected:
virtual ~LineReader();
// Puts a character back into the stream.
virtual void UngetChar(char c) = 0;
};
// As measured in thousandths of a second,
// e.g. a duration of 1 equals 0.001 seconds,
// and a duration of 1000 equals 1 second.
typedef long long presentation_t; // NOLINT
struct Time {
int hours;
int minutes;
int seconds;
int milliseconds;
bool operator==(const Time& rhs) const;
bool operator<(const Time& rhs) const;
bool operator>(const Time& rhs) const;
bool operator<=(const Time& rhs) const;
bool operator>=(const Time& rhs) const;
presentation_t presentation() const;
Time& presentation(presentation_t);
Time& operator+=(presentation_t);
Time operator+(presentation_t) const;
Time& operator-=(presentation_t);
presentation_t operator-(const Time&) const;
};
struct Setting {
std::string name;
std::string value;
};
struct Cue {
std::string identifier;
Time start_time;
Time stop_time;
typedef std::list<Setting> settings_t;
settings_t settings;
typedef std::list<std::string> payload_t;
payload_t payload;
};
class Parser : private LineReader {
public:
explicit Parser(Reader* r);
virtual ~Parser();
// Pre-parse enough of the stream to determine whether
// this is really a WEBVTT file. Returns 0 on success,
// negative if error.
int Init();
// Parse the next WebVTT cue from the stream. Returns 0 if
// an entire cue was parsed, negative if error, and positive
// at end-of-stream.
int Parse(Cue* cue);
private:
// Returns the next character in the stream, using the look-back character
// if present (as per Reader::GetChar).
virtual int GetChar(char* c);
// Puts a character back into the stream (as per LineReader::UngetChar).
virtual void UngetChar(char c);
// Check for presence of a UTF-8 BOM in the stream. Returns
// negative if error, 0 on success, and positive at end-of-stream.
int ParseBOM();
// Parse the distinguished "cue timings" line, which includes the start
// and stop times and settings. Argument |line| contains the complete
// line of text (as returned by ParseLine()), which the function is free
// to modify as it sees fit, to facilitate scanning. Argument |arrow_pos|
// is the offset of the arrow token ("-->"), which indicates that this is
// the timings line. Returns negative if error, 0 on success.
//
static int ParseTimingsLine(std::string* line,
std::string::size_type arrow_pos,
Time* start_time,
Time* stop_time,
Cue::settings_t* settings);
// Parse a single time specifier (from the timings line), starting
// at the given offset; lexical scanning stops when a NUL character
// is detected. The function modifies offset |off| by the number of
// characters consumed. Returns negative if error, 0 on success.
//
static int ParseTime(const std::string& line,
std::string::size_type* off,
Time* time);
// Parse the cue settings from the timings line, starting at the
// given offset. Returns negative if error, 0 on success.
//
static int ParseSettings(const std::string& line,
std::string::size_type off,
Cue::settings_t* settings);
// Parse a non-negative integer from the characters in |line| beginning
// at offset |off|. The function increments |off| by the number
// of characters consumed. Returns the value, or negative if error.
//
static int ParseNumber(const std::string& line,
std::string::size_type* off);
Reader* const reader_;
// Provides one character's worth of look-back, to facilitate scanning.
int unget_;
// Disable copy ctor and copy assign for Parser.
Parser(const Parser&);
Parser& operator=(const Parser&);
};
} // namespace libwebvtt
#endif // WEBVTTPARSER_H_ // NOLINT