for (int i = 0; i < numStreams; i++)
{
/**
* Get the IStream for this input stream.
*/
IStream is = mIContainer.getStream(i);
/**
* And get the input stream coder. Xuggler will set up all sorts of
* defaults on this StreamCoder for you (such as the audio sample rate)
* when you open it.
*
* You can create IStreamCoders yourself using
* IStreamCoder#make(IStreamCoder.Direction), but then you have to set all
* parameters yourself.
*/
IStreamCoder ic = is.getStreamCoder();
/**
* Find out what Codec Xuggler guessed the input stream was encoded with.
*/
ICodec.Type cType = ic.getCodecType();
mIStreams[i] = is;
mICoders[i] = ic;
mOStreams[i] = null;
mOCoders[i] = null;
mASamplers[i] = null;
mVSamplers[i] = null;
mIVideoPictures[i] = null;
mOVideoPictures[i] = null;
mISamples[i] = null;
mOSamples[i] = null;
if (cType == ICodec.Type.CODEC_TYPE_AUDIO && mHasAudio
&& (astream == -1 || astream == i))
{
/**
* First, did the user specify an audio codec?
*/
ICodec codec = null;
if (acodec != null)
{
/**
* Looks like they did specify one; let's look it up by name.
*/
codec = ICodec.findEncodingCodecByName(acodec);
if (codec == null || codec.getType() != cType)
throw new RuntimeException("could not find encoder: " + acodec);
}
else
{
/**
* Looks like the user didn't specify an output coder for audio.
*
* So we ask Xuggler to guess an appropriate output coded based on the
* URL, container format, and that it's audio.
*/
codec = ICodec.guessEncodingCodec(oFmt, null, outputURL, null,
cType);
if (codec == null)
throw new RuntimeException("could not guess " + cType
+ " encoder for: " + outputURL);
}
/**
* So it looks like this stream as an audio stream. Now we add an audio
* stream to the output container that we will use to encode our
* resampled audio.
*/
IStream os = mOContainer.addNewStream(codec);
/**
* And we ask the IStream for an appropriately configured IStreamCoder
* for output.
*
* Unfortunately you still need to specify a lot of things for
* outputting (because we can't really guess what you want to encode
* as).
*/
IStreamCoder oc = os.getStreamCoder();
mOStreams[i] = os;
mOCoders[i] = oc;
/**
* Now let's see if the codec can support the input sample format; if not
* we pick the last sample format the codec supports.
*/
Format preferredFormat = ic.getSampleFormat();
List<Format> formats = codec.getSupportedAudioSampleFormats();
for(Format format : formats) {
oc.setSampleFormat(format);
if (format == preferredFormat)
break;
}
final String apreset = cmdLine.getOptionValue("apreset");
if (apreset != null)
Configuration.configure(apreset, oc);
/**
* In general a IStreamCoder encoding audio needs to know: 1) A ICodec
* to use. 2) The sample rate and number of channels of the audio. Most
* everything else can be defaulted.
*/
/**
* If the user didn't specify a sample rate to encode as, then just use
* the same sample rate as the input.
*/
if (sampleRate == 0)
sampleRate = ic.getSampleRate();
oc.setSampleRate(sampleRate);
/**
* If the user didn't specify a bit rate to encode as, then just use the
* same bit as the input.
*/
if (abitrate == 0)
abitrate = ic.getBitRate();
if (abitrate == 0)
// some containers don't give a bit-rate
abitrate = 64000;
oc.setBitRate(abitrate);
/**
* If the user didn't specify the number of channels to encode audio as,
* just assume we're keeping the same number of channels.
*/
if (channels == 0)
channels = ic.getChannels();
oc.setChannels(channels);
/**
* And set the quality (which defaults to 0, or highest, if the user
* doesn't tell us one).
*/
oc.setGlobalQuality(aquality);
/**
* Now check if our output channels or sample rate differ from our input
* channels or sample rate.
*
* If they do, we're going to need to resample the input audio to be in
* the right format to output.
*/
if (oc.getChannels() != ic.getChannels()
|| oc.getSampleRate() != ic.getSampleRate()
|| oc.getSampleFormat() != ic.getSampleFormat())
{
/**
* Create an audio resampler to do that job.
*/
mASamplers[i] = IAudioResampler.make(oc.getChannels(), ic
.getChannels(), oc.getSampleRate(), ic.getSampleRate(),
oc.getSampleFormat(), ic.getSampleFormat());
if (mASamplers[i] == null)
{
throw new RuntimeException(
"could not open audio resampler for stream: " + i);
}
}
else
{
mASamplers[i] = null;
}
/**
* Finally, create some buffers for the input and output audio
* themselves.
*
* We'll use these repeated during the #run(CommandLine) method.
*/
mISamples[i] = IAudioSamples.make(1024, ic.getChannels(), ic.getSampleFormat());
mOSamples[i] = IAudioSamples.make(1024, oc.getChannels(), oc.getSampleFormat());
}
else if (cType == ICodec.Type.CODEC_TYPE_VIDEO && mHasVideo
&& (vstream == -1 || vstream == i))
{
/**
* If you're reading these commends, this does the same thing as the
* above branch, only for video. I'm going to assume you read those
* comments and will only document something substantially different
* here.
*/
ICodec codec = null;
if (vcodec != null)
{
codec = ICodec.findEncodingCodecByName(vcodec);
if (codec == null || codec.getType() != cType)
throw new RuntimeException("could not find encoder: " + vcodec);
}
else
{
codec = ICodec.guessEncodingCodec(oFmt, null, outputURL, null,
cType);
if (codec == null)
throw new RuntimeException("could not guess " + cType
+ " encoder for: " + outputURL);
}
final IStream os = mOContainer.addNewStream(codec);
final IStreamCoder oc = os.getStreamCoder();
mOStreams[i] = os;
mOCoders[i] = oc;