/* look for further theora headers */
while (theora_p != 0 && (theora_p < 3) && ((ret = OGG.ogg_stream_packetout(to, op))) != 0)
{
if (ret < 0)
{
throw new ResourceUnavailableException("Error parsing Theora stream headers; corrupt stream?");
}
if (THEORA.theora_decode_header(ti, tc, op) != 0)
{
throw new ResourceUnavailableException("Error parsing Theora stream headers; corrupt stream?");
}
theora_p++;
if (theora_p == 3)
break;
}
/* look for more vorbis header packets */
while (vorbis_p != 0 && (vorbis_p < 3) && ((ret = OGG.ogg_stream_packetout(vo, op))) != 0)
{
if (ret < 0)
{
throw new ResourceUnavailableException("Error parsing Vorbis stream headers; corrupt stream?");
}
if (VORBIS.vorbis_synthesis_headerin(vi, vc, op) != 0)
{
throw new ResourceUnavailableException("Error parsing Vorbis stream headers; corrupt stream?");
}
vorbis_p++;
if (vorbis_p == 3)
break;
}
/*
* The header pages/packets will arrive before anything else
* we care about, or the stream is not obeying spec
*/
if (OGG.ogg_sync_pageout(oy, og) > 0)
{
queue_page(og); /* demux into the appropriate stream */
} else
{
final int ret2 = buffer_data(oy); /* someone needs more data */
if (ret2 <= 0)
{
throw new ResourceUnavailableException("End of file while searching for codec headers.");
}
}
}
/* and now we have it all. initialize decoders */
if (theora_p != 0)
{
THEORA.theora_decode_init(td, ti);
final double fps = (double) ti.fps_numerator / (double) ti.fps_denominator;
logger.info("Ogg logical stream " + Integer.toHexString( to.serialno.intValue()) + " is Theora " + ti.width + "x" + ti.height + " " + fps + " fps");
switch (ti.pixelformat)
{
case TheoraLibrary.OC_PF_420:
logger.info(" 4:2:0 video");
break;
case TheoraLibrary.OC_PF_422:
logger.info(" 4:2:2 video");
break;
case TheoraLibrary.OC_PF_444:
logger.info(" 4:4:4 video");
break;
case TheoraLibrary.OC_PF_RSVD:
default:
logger.info(" video\n (UNKNOWN Chroma sampling!)");
break;
}
if (ti.width != ti.frame_width || ti.height != ti.frame_height)
{ logger.warning(" Frame content is " + ti.frame_width + "x" + ti.frame_height + " with offset (" + ti.offset_x + "," + ti.offset_y + ").");
// TODO: we need to handle cropping properly.
}
report_colorspace(ti);
dump_comments(tc);
} else
{
/* tear down the partial theora setup */
THEORA.theora_info_clear(ti);
THEORA.theora_comment_clear(tc);
}
if (vorbis_p != 0)
{
VORBIS.vorbis_synthesis_init(vd, vi);
VORBIS.vorbis_block_init(vd, vb);
logger.info("Ogg logical stream " + Integer.toHexString(vo.serialno.intValue()) + " is Vorbis " + vi.channels + " channel " + vi.rate.intValue() + " Hz audio.");
} else
{
/* tear down the partial vorbis setup */
VORBIS.vorbis_info_clear(vi);
VORBIS.vorbis_comment_clear(vc);
}
stateflag = 0; /* playback has not begun */
VideoTrack videoTrack = null;
AudioTrack audioTrack = null;
if (theora_p != 0)
{
videoTrack = new VideoTrack();
}
if (vorbis_p != 0)
{
audioTrack = new AudioTrack();
}
if (audioTrack == null && videoTrack == null)
throw new ResourceUnavailableException("No audio or video track found");
else if (audioTrack != null && videoTrack != null)
tracks = new PullSourceStreamTrack[] { videoTrack, audioTrack };
else if (audioTrack != null)
tracks = new PullSourceStreamTrack[] { audioTrack };
else
tracks = new PullSourceStreamTrack[] { videoTrack };
} catch (IOException e)
{
logger.log(Level.WARNING, "" + e, e);
throw new ResourceUnavailableException("" + e);
}
}
super.open();