/* * myLib - https://github.com/taktod/myLib * Copyright (c) 2014 ttProject. All rights reserved. * * Licensed under The MIT license. */ package com.ttProject.container.riff.type; import java.nio.ByteBuffer; import com.ttProject.container.riff.RiffFormatUnit; import com.ttProject.container.riff.StrhRiffCodecType; import com.ttProject.container.riff.Type; import com.ttProject.frame.CodecType; import com.ttProject.frame.IAnalyzer; import com.ttProject.frame.VideoAnalyzer; import com.ttProject.frame.VideoSelector; import com.ttProject.frame.flv1.Flv1FrameAnalyzer; import com.ttProject.frame.h264.DataNalAnalyzer; import com.ttProject.frame.h264.NalAnalyzer; import com.ttProject.frame.h264.exception.ConfigDataException; import com.ttProject.frame.mjpeg.MjpegFrameAnalyzer; import com.ttProject.frame.vp8.Vp8FrameAnalyzer; import com.ttProject.nio.channels.ByteReadChannel; import com.ttProject.nio.channels.IReadChannel; import com.ttProject.unit.extra.BitLoader; import com.ttProject.unit.extra.bit.Bit16; import com.ttProject.unit.extra.bit.Bit32; import com.ttProject.util.BufferUtil; /** * strf * @author taktod */ public class Strf extends RiffFormatUnit { // need to inplements bmpInfo? private Bit32 biSize = new Bit32(); private Bit32 biWidth = new Bit32(); private Bit32 biHeight = new Bit32(); private Bit16 biPlanes = new Bit16(); private Bit16 biBitCount = new Bit16(); private Bit32 biCompression = new Bit32(); // is this fourCC? private Bit32 biSizeImage = new Bit32(); private Bit32 biXPelsPerMeter = new Bit32(); private Bit32 biYPelsPerMeter = new Bit32(); private Bit32 biClrUsed = new Bit32(); private Bit32 biClrImportant = new Bit32(); private StrhRiffCodecType riffCodecType = null; private IAnalyzer frameAnalyzer = null; private ByteBuffer extraInfo = null; // for h264 after this, here is the codecPrivate(configData.) // for theora, something wierd here... /* * note:these size information in big endian. * 00 2A size * 80 74 .... theora header frame. * 00 3A size * 81 74 .... theora comment frame. * 0C 84 size * 82 74 .... theora setup frame. */ /** * constructor */ public Strf(StrhRiffCodecType codecType) { super(Type.strf); this.riffCodecType = codecType; } /** * {@inheritDoc} */ @Override public void minimumLoad(IReadChannel channel) throws Exception { super.minimumLoad(channel); BitLoader loader = new BitLoader(channel); loader.setLittleEndianFlg(true); loader.load(biSize, biWidth, biHeight, biPlanes, biBitCount, biCompression, biSizeImage, biXPelsPerMeter, biYPelsPerMeter, biClrUsed, biClrImportant); } /** * {@inheritDoc} */ @Override public void load(IReadChannel channel) throws Exception { if(getSize() - 48 > 0) { // TODO here try to read all of the file. extraInfo = BufferUtil.safeRead(channel, getSize() - 48); } } /** * {@inheritDoc} */ @Override protected void requestUpdate() throws Exception { } /** * {@inheritDoc} */ @Override public CodecType getCodecType() { return riffCodecType.getCodecType(); } /** * {@inheritDoc} */ @Override public IAnalyzer getFrameAnalyzer() throws Exception { if(frameAnalyzer != null) { return frameAnalyzer; } switch(riffCodecType) { case MJPG: frameAnalyzer = new MjpegFrameAnalyzer(); break; case H264: if(extraInfo == null) { frameAnalyzer = new NalAnalyzer(); } else { try { frameAnalyzer = new DataNalAnalyzer(); // if here throw the exception, need to use frameAnalyzer.setPrivateData(new ByteReadChannel(extraInfo)); } catch(ConfigDataException cde) { frameAnalyzer = new NalAnalyzer(); } } break; case FLV1: frameAnalyzer = new Flv1FrameAnalyzer(); break; case VP80: frameAnalyzer = new Vp8FrameAnalyzer(); break; default: throw new RuntimeException("analyzer is unknown"); } if(frameAnalyzer instanceof VideoAnalyzer) { VideoSelector selector = ((VideoAnalyzer) frameAnalyzer).getSelector(); selector.setWidth(biWidth.get()); selector.setHeight(biHeight.get()); } return frameAnalyzer; } /** * {@inheritDoc} */ @Override public int getBlockSize() { return 0; } /** * ref the extra Info(codecPrivate for theora, ) * @return */ @Override public ByteBuffer getExtraInfo() { return extraInfo; } }