throw new IllegalArgumentException(
"invalid video frame size [" + width + " x " + height + "]");
// add the new stream at the correct index
IStream stream = establishStream(inputIndex, streamId, codec);
// configre the stream coder
IStreamCoder coder = stream.getStreamCoder();
try
{
List<IRational> supportedFrameRates = codec.getSupportedVideoFrameRates();
IRational timeBase = null;
if (supportedFrameRates != null && supportedFrameRates.size() > 0)
{
IRational highestResolution = null;
// If we have a list of supported frame rates, then
// we must pick at least one of them. and if the
// user passed in a frameRate, it must match
// this list.
for(IRational supportedRate: supportedFrameRates)
{
if (!IRational.positive(supportedRate))
continue;
if (highestResolution == null)
highestResolution = supportedRate.copyReference();
if (IRational.positive(frameRate))
{
if (supportedRate.compareTo(frameRate) == 0)
// use this
highestResolution = frameRate.copyReference();
}
else if (highestResolution.getDouble() < supportedRate.getDouble())
{
highestResolution.delete();
highestResolution = supportedRate.copyReference();
}
supportedRate.delete();
}
// if we had a frame rate suggested, but we
// didn't find a match among the supported elements,
// throw an error.
if (IRational.positive(frameRate) &&
(highestResolution == null ||
highestResolution.compareTo(frameRate) != 0))
throw new UnsupportedOperationException("container does not"+
" support encoding at given frame rate: " + frameRate);
// if we got through the supported list and found NO valid
// resolution, fail.
if (highestResolution == null)
throw new UnsupportedOperationException(
"could not find supported frame rate for container: " +
getUrl());
if (timeBase == null)
timeBase = IRational.make(highestResolution.getDenominator(),
highestResolution.getNumerator());
highestResolution.delete();
highestResolution = null;
}
// if a positive frame rate was passed in, we
// should either use the inverse of it, or if
// there is a supported frame rate, but not
// this, then throw an error.
if (IRational.positive(frameRate) && timeBase == null)
{
timeBase = IRational.make(
frameRate.getDenominator(),
frameRate.getNumerator());
}
if (timeBase == null)
{
timeBase = getDefaultTimebase();
// Finally MPEG4 has some code failing if the time base
// is too aggressive...
if (codec.getID() == ICodec.ID.CODEC_ID_MPEG4 &&
timeBase.getDenominator() > ((1<<16)-1))
{
// this codec can't support that high of a frame rate
timeBase.delete();
timeBase = IRational.make(1,(1<<16)-1);
}
}
coder.setTimeBase(timeBase);
timeBase.delete();
timeBase= null;
coder.setWidth(width);
coder.setHeight(height);
coder.setPixelType(DEFAULT_PIXEL_TYPE);
// add the stream to the media writer
addStream(stream, inputIndex, stream.getIndex());
}
finally
{
coder.delete();
}
// return the new video stream
return stream.getIndex();
}