I’m using this api and have come across some a code example that is confusing me. I know that I can assign an object to an interface using “new”, since an interface is a datatype. What I don’t understand from the code below is why the variables: “cc” and “audioDecoder” are assigned the values that they have been assigned. As far as I know, those variables should be assigned to new objects. Could someone explain what is going on here?
try {
// open media file
DefaultMediaPlayer player = new DefaultMediaPlayer("/home/me/walking.wav");
// get some properties of the first audio stream
IDecoder audioDecoder = player.getAudioStreamDecoder(0);
ICodecContextWrapper cc = audioDecoder.getCodecContext();
int sampleFormat = cc.getSampleFormat();
int sampleRate = cc.getSampleRate();
int bytesPerSample = AVSampleFormat.getBytesPerSample(sampleFormat);
long channelLayout = cc.getChannelLayout();
int channelCount = AVChannelLayout.getChannelCount(channelLayout);
AudioFormat.Encoding encoding;
if (AVSampleFormat.isPlanar(sampleFormat) || AVSampleFormat.isReal(sampleFormat))
throw new LibavException("unsupported output sample format");
else if (AVSampleFormat.isSigned(sampleFormat))
encoding = AudioFormat.Encoding.PCM_SIGNED;
else
encoding = AudioFormat.Encoding.PCM_UNSIGNED;
// create Java InputStream for audio stream raw data
SampleInputStream sis = new SampleInputStream(sampleRate * bytesPerSample * channelCount, true);
// create AudioInputStream from the SampleInputStream
AudioInputStream audioStream = new AudioInputStream(sis, new AudioFormat(encoding, sampleRate,
bytesPerSample * 8, channelCount, bytesPerSample * channelCount, sampleRate,
ByteOrder.BIG_ENDIAN.equals(ByteOrder.nativeOrder())), -1);
// create adapter between Libav audio frames and the SampleInputStream
Frame2AudioFrameAdapter resampler = new Frame2AudioFrameAdapter(channelLayout, channelLayout, sampleRate,
sampleRate, sampleFormat, sampleFormat);
// get audio mixer for the audio stream format
PlaybackMixer audioMixer = PlaybackMixer.getMixer(audioStream.getFormat());
// connect all streams
audioDecoder.addFrameConsumer(resampler);
resampler.addAudioFrameConsumer(sis);
audioMixer.addInputStream(audioStream);
// enable audio stream decoding
player.setAudioStreamDecodingEnabled(0, true);
// start playback
audioMixer.play();
player.play();
// wait until the playback stops
player.join();
// release system resources
player.close();
resampler.dispose();
PlaybackMixer.closeAllMixers();
} catch (Exception ex) {
Logger.getLogger(PlaybackSample.class.getName()).log(Level.WARNING, "unable to play audio", ex);
}
If you have gone through the API document. The method DefaultMediaPlayer.getAudioStreamDecoder
is returning the instance of type IDecoder. Thats why in the src they are assigning the return type to audioDecoder variable of type IDecoder.
There is no rule saying that you can assign objects to Interface type only using
new. You can assign object instances from method return types.Likewise the method
IDecoder.getCodecContext()returns the object of instanceICodecContextWrapperwhich is being assigned to variablecc.