Xuggler 3.1: "Chloe"
Announcing Xuggler 3.1: Get It Here.
Table of Contents
Summary
Introducing Xuggler 3.1. Here's the new features (and see below for defects fixed):
- Installers for Linux & Mac users -- no more long builds.
- Support for encoding Speex and Vorbis audio and Theora video.
- Support for getting and setting MetaData on files like MP3.
- Support for generating SDP descriptors for RTSP streams.
- Support for creating
IVideoPictureandIAudioSamplesdirectly from memory-mapped files.
As usual, read on for the details.
Release Notes
xuggle-ffmpeg
We made a major change to our build-system for FFmpeg in this
release: It is now published as a completely separate xuggle-ffmpeg
project. For AGPL users the change is 100% transparent -- Xuggler just
links the project into the captive directory in our source
as before, but it means if you want to use our build system for FFmpeg
without using Xuggler you're welcome to. And the build system itself is
licensed under the MIT license, so there are no restrictions beyond
those of the incorporated libraries.
But xuggle-ffmpeg has a major new feature: it can now apply patches at build time to the latest FFmpeg source tree. This is important because it lets us add features to FFmpeg without having to wait for FFmpeg to decide to incorporate them. What do you get for that... see next.
Speex Encoding
You can use Xuggler (with our xuggle-ffmpeg version of FFmpeg) to encode Speex audio into FLV or Ogg containers. Just use the "libspeex" encoder.
If you are using your own version of FFmpeg (not the one we build), you won't have this feature. We've submitted our patches to mainline FFmpeg and will try to shepherd them in there too.
The current speex encoder has one limitation: it always encodes 2 speex frames per packet (the Adobe default). In future versions we hope to make that configurable.
Theora and Vorbis Encoding
Xuggler now supports encoding Theora video and Vorbis audio for even more open-source brownie points. Use the "libtheora" encoder or the "libvorbis" encoder.
Get and Set Media MetaData
Xuggler can now get and set MetaData on codecs that support it. Using the MetaData API you can set things like MP3 ID3 meta-data. Here's some sample code:
IContainer container = IContainer.make();
container.open("fixtures/testfile.mp3", IContainer.Type.READ, null);
IMetaData meta = container.getMetaData();
Collection<String> keys = meta.getKeys();
for(String key : keys)
{
System.out.println(key + " = " + meta.getValue(key));
}
And the output for our testfile is:
author = Stan Kenton album = Kenton/Wagner track = 1 title = Ride of the Valkyries genre = Space Lounge
The MetaData API can only get and set strings (a limitation of the FFmpeg underlying API), but formats that support MetaData will convert to the correct on-disk format. For example, here's some code setting MetaData on an MP3 file:
IContainer container = IContainer.make();
container.open(filename, IContainer.Type.WRITE, null);
IStream stream = container.addNewStream(0);
IStreamCoder coder = stream.getStreamCoder();
coder.setCodec(ICodec.ID.CODEC_ID_MP3);
coder.setSampleRate(22050);
coder.setChannels(1);
coder.open();
IMetaData meta = container.getMetaData();
String author = "Your Mom";
String genre = "6";
String title = "Ode to Mothers";
meta.setValue("title", title);
meta.setValue("author", author);
meta.setValue("genre", genre);
meta.setValue("year", "2009");
meta.setValue("album", "So large the sun rotates around her");
meta.setValue("comment", "I wonder why genre is blues?");
container.writeHeader();
Note we set the "genre" tag to "6". In ID3 this is a 1-byte flag representing the genre, and will get written as such by Xuggler. When reading the data, Xuggler will convert it to a string representation.
Lastly, we modified FFmpeg to add support for reading (but not writing) MetaData from FLV containers. This was accepted into the latest FFmpeg (as well as being in xuggle-ffmpeg)
SDP Data Creation
Another oft-requested feature, Xuggler can now generate SDP data that you can write to a file for use with RTSP clients. Here's how:
IContainer container = IContainer.make();
... set up container ...
String sdp = container.createSDPData();
... write string to file ...
For our international brothers (and sisters) who can't guarantee a Java String written to a file will be UTF-8 encoded, you can use the byte-level API for SDP data:
IContainer container = IContainer.make();
... set up container ...
IBuffer buffer = IBuffer.make(null, 4192);
int len = container.createSDPData(buffer);
byte[] sdp = new byte[len-1];
buffer.get(0, sdp, 0, sdp);
... write bytes to a file ---
Create IVideoPictures from Existing Memory Without Copying
You can now create IVideoPicture and IAudioSamples objects from direct ByteBuffers. This means that if you happen to have your decoded data already available, say in a Java memory-mapped file, you can have Xuggler access that memory directly without copying data into its buffers.
Here's how:
ByteBuffer memoryMappedImageData = ...
IBuffer buffer = IBuffer.make(null,
memoryMappedImageData, 0, memoryMappedImageData.capacity());
IVideoPicture picture = IVideoPicture.make(buffer,
format, width, height);
// make sure you call picture.setComplete(...) with the right parameters
// before using
A similar make(...) method was added for com.xuggle.xuggler.IAudioSamples
Linux and Windows Binaries
We have modified our build server to automatically create Windows and Linux binaries (along with Windows installers). This was part of a large build-system re-architecture that ensures that all stable builds are tested on all OS combinations under all test conditions before promotion to stable.
We automatically create binaries for the following operating systems and versions
| OS | Java Versions | Installer | Description |
|---|---|---|---|
| Windows XP & Later 32-Bit | 1.5 & 1.6 | xuggle-xuggler.revision-win32-setup.exe |
Xuggler AGPL Build with xuggle-ffmpeg included. |
xuggle-xuggler-core.revision-win32-setup.exe |
Xuggler AGPL Build without xuggle-ffmpeg included. | ||
xuggle-ffmpeg.revision-win32-setup.exe |
xuggle-ffmpeg only binary distribution. | ||
| Mac OS X 10.5+ 64 Bit | 1.6 | xuggle-xuggler.revision-i386-apple-darwin9.7.0.sh |
Xuggler AGPL Build with xuggle-ffmpeg included. |
xuggle-xuggler-core.revision-i386-apple-darwin9.7.0.sh |
Xuggler AGPL Build without xuggle-ffmpeg included. | ||
xuggle-ffmpeg.revision-i386-apple-darwin9.7.0.sh |
xuggle-ffmpeg only binary distribution. | ||
| Linux 32 Bit | 1.5 & 1.6 | xuggle-xuggler.revision-i686-machinetype-linux-gnu.sh |
Xuggler AGPL Build with xuggle-ffmpeg included. |
xuggle-xuggler-core.revision-i686-machinetype-linux-gnu.sh |
Xuggler AGPL Build without xuggle-ffmpeg included. | ||
xuggle-ffmpeg.revision-i686-machinetype-linux-gnu.sh |
xuggle-ffmpeg only binary distribution. | ||
| Linux 64 Bit | 1.5 & 1.6 | xuggle-xuggler.revision-x86_64-machinetype-linux-gnu.sh |
Xuggler AGPL Build with xuggle-ffmpeg included. |
xuggle-xuggler-core.revision-x86_64-machinetype-linux-gnu.sh |
Xuggler AGPL Build without xuggle-ffmpeg included. | ||
xuggle-ffmpeg.revision-x86_64-machinetype-linux-gnu.sh |
xuggle-ffmpeg only binary distribution. |
To use a binary distribution, download it and run. For example (replace the filename with the one you downloaded) on Linux:
./xuggle-xuggler.3.1.806-i686-pc-linux-gnu.sh
Then, set the environment variables it tells you to set and you should be setup to go.
And for Xuggler 3.1, you no longer need to reboot after an install, even on Windows (although you should restart processes that are using Xuggler to have them pick up the new version).
On Mac OS X we can only build a 64-bit binary with our automated system which in turn only works on Intel Mac's running Java 1.6 and above. If you need Java 1.5, or want to build on a 32-bit only machine, we still support Mac OS X -- you just need to build from source yourself. It's on our wish list to make this automatable, and to make universal binaries, but it turns out to be harder than we'd like and so won't happen soon.
We also create tar files for the source tree used to generate these installers, and a tar file containing the ivy-compliant repository for Jar files created.
| Key | File | Description |
|---|---|---|
| Source | xuggle-xuggler.revision-src.tar.gz |
Source code used to create these installers |
| Repository | xuggle-xuggler.revision-repo.tar.gz |
Ivy compliant repository with Java 1.5/1.6 Jar files for this release (included in installers). |
Enjoy!
RefCounted#copyReference() is Over 50% Faster
The com.xuggle.ferry.RefCounted.copyReference()
method has been re-implemented to avoid having to transition to native
code and back to java to copy the reference, and one lock has been
replaced with atomic long updates. This makes copyReference() much
faster than before. For most users this won't make a difference, but for
multi-threaded users who are passing objects between threads and are
heavy users of copyReference(), you may see anywhere from a 0% to 5%
speed up as a result of this (well, we did in our internal projects).
Specify Type of Video Encoded Packet To Create
With Xuggler 3.1, you can ask a IStreamCoder to create a specific type of packet when encoding an IVideoPicture by calling IVideoPicture#setPictureType(...):
IVideoPicture picture = ...;
// Ask Xuggler to encode this picture as a key-frame (I-Frame)
// even if the encoder wouldn't normally do that.
picture.setPictureType(IVideoPicture.PictType.I_TYPE);
Not all codecs will honor this setting, but try it for fun.
Duration of Audio Packets Now Set
We now set the estimated duration of Audio packets on IPacket
object. The units of duration are in IPacket.getTimeBase()
units, and round-down to the nearest integer.
Easier Property Querying
com.xuggle.xuggler.IConfigurable has a new method to
return a collection of all settable property names as keys. See
IConfigurable#getPropertyNames()
Experimental non-FAAC AAC Encoder
FFmpeg just added an experimental AAC encoder (use the codec "aac"). It (in theory) doesn't have the same licensing restrictions that FAAC has, but it's definitely at the early stages.
Warnings
You must uninstall prior versions of Xuggler before installing this version.
This release of Xuggler is backwards compatible with the last release with the following exceptions:
-
com.xuggle.xuggler.IStreamCoderwill now detect rounding-errors when converting time stamps from stream-time to coder-time, and if the resulting time stamp would result in a duplicate time stamp being passed to an encoder, Xuggler will silently drop the frame. Prior versions of Xuggler would attempt to encode anyway and either get an error (in the case of MPEG2) or silently succeed for other formats.We mention this here because Xuggler 3.1 may, for some files that silently worked before, now result in an occasional video-frame being dropped. The impact should not be visible, but it can happen.
To detect if this has happened, you can use the new
IStreamCoder.getNumFramesDroppedmethod that will tell you the number, if any, of frames dropped by this encoder sinceIStreamCoder.openwas called.And to avoid dropping, try to set the time base on your
IStreamCoderto the same time base that theIStreamyou're inserting into (or reading from) will use. Be warned though, not all codecs support higher-resolution time bases.See Issue #180 for background.
Known Issues
Critical
There are no known critical issues in this release.
Major
Users of this version of Xuggler should be aware of the following limitations (which will be addressed in a future Xuggler release):
- MediaWriter does not resample audio. To work around ensure the audio sample rate and channels you ask MediaWriter to encode is the same as what you set up your audio streams with. Tracking issue.
- MediaViewer is experimental and not very robust. It's included only to get feedback, but you should not use it in production environments. Tracking issue.
Minor
There are two bugs in the current version of FFmpeg that may impact you. Both have simple workarounds:
- Issue #92: Doing resize and changing color space from YUV to either BGR24 or ARGB AT THE SAME TIME produces erroneous black pixels. Workaround: do resize operations separately from colorspace conversions.
- Issue #93: YUV to ARGB Converter causes every 2nd line of pixels to be offset by one. Work around: use BGR24 converter.
Issues Fixed
- Defect #180: Error encoding flash videos - ERROR org.ffmpeg - [flv @ 0x70790100] Error, Invalid timestamp=280, last=280
- Defect #63: detect correct swig version
- Defect #178: IContainer.setProperty does not work until after IContainer.open is called
- Defect #158: Documentation links to source code are broken
- Defect #176: java based ref-counting approach doesn't appear to fully work
- Defect #172: For some reason in some systems we appear to not be using optimized video resamplers
- Defect #160: Need to add libvorbis to captive build
- Defect #167: Xuggler fails t play VLC UDP streams
- Defect #163: JNIMemoryAllocator attempts to unlock without aquiring a lock. Causing excesive IllegalMonitorException to be generated.
- Defect #135: Xuggler build fails on Ubuntu 8 against IcedTea
Enhancements Added
- Enhancement #22: Clean up Hudson builds
- Enhancement #179: Need a way to encode speex audio
- Enhancement #142: Add way for build system to tell tests if they're running with a "head"
- Enhancement #164: Allow setting IBuffer for IVideoPicture and IAudioSample
- Enhancement #129: Allow IStreamCoder to encode IVideoPictures with different IPixelTypes if they are laid out the same in memory
- Enhancement #177: Add easy way to get all property names settable on an object.
- Enhancement #157: IPacket duration is not always set. Can it be always computed for audio format ?
- Enhancement #159: Please expose the avf_sdp_create() function
- Enhancement #137: Wrap new ffmpeg meta-data features
- Enhancement #175: Use new FFmpeg options code to set defaults on stream coders when encoding
- Enhancement #170: Expose pict_type from AVFrame structure
- Enhancement #168: copyReference() should avoid making JNI calls
- Enhancement #165: Youtube downloaded videos do not decode correctly
- Enhancement #127: Add IAudioSamples.make() which takes data
What's Next?
We're going to add small features and fix bugs while we work on something using Xuggler internally, so don't expect a major release soon. We'll keep current with FFmpeg of course.
But who knows? It'll depend on what the community reaction to Xuggler 3.1 is, but if we were guessing, here's top of our list (things we wanted to get in Xuggler 3.1 but didn't make the deadline, again):
- MediaWriter should resample audio for users behind the scenes if needed, and should take javax.sound format specifiers.
- The video conversion API should be simpler to use without sacrificing performance for those who need it.
- MediaViewer should be more stable -- FYI we're not planning on building a video player (we're leaving that for the community right now), but having a MediaViewer helps with debugging other things.
- Other ideas? Send them our way (file enhancement requests).
Warning: At some point the FFmpeg is going to move to GIT for source control. If you're in the habit of building Xuggler from our tip of tree, you'll want to install GIT. We'll likely be forced to require GIT and SVN to build Xuggler once FFmpeg makes the move. No ETA on this yet, but there is a lot of chatter on the FFmpeg lists about it. By the way, the advantage of this is we should also then be able to auto-integrate the latest libx264 as well.
Warning: We will likely have to move our SVN repository from Googlecode to some other site (still TBD). We'll try to keep disruption to a minimum if we need to do that.
Build Information
Tests
- Java Tests: 597 (+27)
Fine Print
By reading these release notes, you authorize us to go through your pockets and look for spare change. Unless, of course, you're only mostly-dead.
Source Control Versions
Xuggler 3.1.818.FINALHudson Good Build http://build.xuggle.com/job/xuggler_jdk5_stable/47/
Dynamic Revisions
* http://xuggle-ffmpeg.googlecode.com/svn/trunk/: 807
* svn://svn.mplayerhq.hu/ffmpeg/trunk : 19400
* svn://svn.ffmpeg.org/mplayer/trunk/libswscale : 29415
* http://theyard.googlecode.com/svn/theyard/code/trunk/share/gnu/
cxxtest/cxxtest-3.10.1 : 170
* http://xuggle.googlecode.com/svn/trunk/build/java : 816
* http://xuggle.googlecode.com/svn/trunk/java/xuggle-xuggler : 818
- Static Dependencies
* http://xuggle-ffmpeg.googlecode.com/svn/trunk/
* libx264: ftp://ftp.videolan.org/pub/videolan/x264/snapshots/
x264-snapshot-20090125-2245.tar.bz2
* libmp3lame: http://downloads.sourceforge.net/lame/lame-398.tar.gz: 3.98
* libspeex: http://downloads.xiph.org/releases/speex/speex-1.2rc1.tar.gz: 1.2 RC1
* libfaac: http://downloads.sourceforge.net/faac/faac-1.28.zip: 1.28
* libogg: http://downloads.xiph.org/releases/ogg/libogg-1.1.3.tar.gz
* libvorbis: http://downloads.xiph.org/releases/vorbis/libvorbis-1.2.0.tar.gz
* libtheora: http://downloads.xiph.org/releases/theora/libtheora-1.0.tar.bz2
On Windows, here's what we built our installer with:
* Mingw gcc/g++ 4.2.4: http://www.tdragon.net/recentgcc/
* Msys 1.0.11
* mingw-runtime 3.15.1
* w32api 3.13
* gmake 3.81
* binutils 2.91
* yasm 0.7.2.2153
* Msys Perl 5.6
* Ant 1.7
* Java JDK 1.5
* MSFT C++ Visual Studio 2005
* NullSoft NSIS Installer 2.42
* Subversion 1.5
Integration
