* And keep some convenience pointers for the specific stream we're working
* on for a packet.
*/
IStreamCoder ic = null;
IStreamCoder oc = null;
IAudioResampler as = null;
IVideoResampler vs = null;
IVideoPicture inFrame = null;
IVideoPicture reFrame = null;
/**
* Now, we've already opened the files in #setupStreams(CommandLine). We
* just keep reading packets from it until the IContainer returns <0
*/
while (mIContainer.readNextPacket(iPacket) == 0)
{
/**
* Find out which stream this packet belongs to.
*/
int i = iPacket.getStreamIndex();
int offset = 0;
/**
* Find out if this stream has a starting timestamp
*/
IStream stream = mIContainer.getStream(i);
long tsOffset = 0;
if (stream.getStartTime() != Global.NO_PTS && stream.getStartTime() > 0
&& stream.getTimeBase() != null)
{
IRational defTimeBase = IRational.make(1,
(int) Global.DEFAULT_PTS_PER_SECOND);
tsOffset = defTimeBase.rescale(stream.getStartTime(), stream
.getTimeBase());
}
/**
* And look up the appropriate objects that are working on that stream.
*/
ic = mICoders[i];
oc = mOCoders[i];
as = mASamplers[i];
vs = mVSamplers[i];
inFrame = mIVideoPictures[i];
reFrame = mOVideoPictures[i];
inSamples = mISamples[i];
reSamples = mOSamples[i];
if (oc == null)
// we didn't set up this coder; ignore the packet
continue;
/**
* Find out if the stream is audio or video.
*/
ICodec.Type cType = ic.getCodecType();
if (cType == ICodec.Type.CODEC_TYPE_AUDIO && mHasAudio)
{
/**
* Decoding audio works by taking the data in the packet, and eating
* chunks from it to create decoded raw data.
*
* However, there may be more data in a packet than is needed to get one
* set of samples (or less), so you need to iterate through the byts to
* get that data.
*
* The following loop is the standard way of doing that.
*/
while (offset < iPacket.getSize())
{
retval = ic.decodeAudio(inSamples, iPacket, offset);
if (retval <= 0)
throw new RuntimeException("could not decode audio. stream: " + i);
if (inSamples.getTimeStamp() != Global.NO_PTS)
inSamples.setTimeStamp(inSamples.getTimeStamp() - tsOffset);
log.trace("packet:{}; samples:{}; offset:{}", new Object[]
{
iPacket, inSamples, tsOffset
});
/**
* If not an error, the decodeAudio returns the number of bytes it
* consumed. We use that so the next time around the loop we get new
* data.
*/
offset += retval;
int numSamplesConsumed = 0;
/**
* If as is not null then we know a resample was needed, so we do that
* resample now.
*/
if (as != null && inSamples.getNumSamples() > 0)
{
retval = as.resample(reSamples, inSamples, inSamples
.getNumSamples());
outSamples = reSamples;
}
else