/* * myLib - https://github.com/taktod/myLib * Copyright (c) 2014 ttProject. All rights reserved. * * Licensed under The MIT license. */ package com.ttProject.frame.flv1; import java.nio.ByteBuffer; import com.ttProject.frame.CodecType; import com.ttProject.frame.VideoFrame; import com.ttProject.nio.channels.IReadChannel; import com.ttProject.unit.extra.Bit; import com.ttProject.unit.extra.BitConnector; import com.ttProject.unit.extra.bit.Bit17; import com.ttProject.unit.extra.bit.Bit1; import com.ttProject.unit.extra.bit.Bit2; import com.ttProject.unit.extra.bit.Bit3; import com.ttProject.unit.extra.bit.Bit5; import com.ttProject.unit.extra.bit.Bit8; import com.ttProject.util.BufferUtil; /** * base for flv1 frame * @see http://hkpr.info/flash/swf/index.php?%E3%83%93%E3%83%87%E3%82%AA%2FSorenson%20H.263%20%E3%83%93%E3%83%83%E3%83%88%E3%82%B9%E3%83%88%E3%83%AA%E3%83%BC%E3%83%A0%E3%83%95%E3%82%A9%E3%83%BC%E3%83%9E%E3%83%83%E3%83%88 * TODO temporalReference counter need to start from 0.(maybe suppress the warning on ffmpeg) * @author taktod */ public abstract class Flv1Frame extends VideoFrame { private final Bit17 pictureStartCode; private final Bit5 version; private final Bit8 temporalReference; private final Bit3 pictureSize; private final Bit customWidth; private final Bit customHeight; private final Bit2 pictureType; private final Bit1 deblockingFlag; private final Bit5 quantizer; private final Bit1 extraInformationFlag; private final Bit8 extraInformation; private final Bit extra; private ByteBuffer buffer = null; // buffer to read layer. private int width, height; /** * constructor * @param pictureStartCode * @param version * @param temporalReference * @param pictureSize * @param customWidth * @param customHeight * @param width * @param height * @param pictureType * @param deblockingFlag * @param quantizer * @param extraInformationFlag * @param extraInformation * @param extra */ public Flv1Frame(Bit17 pictureStartCode, Bit5 version, Bit8 temporalReference, Bit3 pictureSize, Bit customWidth, Bit customHeight, int width, int height, Bit2 pictureType, Bit1 deblockingFlag, Bit5 quantizer, Bit1 extraInformationFlag, Bit8 extraInformation, Bit extra) { this.pictureStartCode = pictureStartCode; this.version = version; this.temporalReference = temporalReference; this.pictureSize = pictureSize; this.customWidth = customWidth; this.customHeight = customHeight; this.pictureType = pictureType; this.deblockingFlag = deblockingFlag; this.quantizer = quantizer; this.extraInformationFlag = extraInformationFlag; this.extraInformation = extraInformation; this.extra = extra; this.width = width; this.height = height; } /** * {@inheritDoc} */ @Override public ByteBuffer getData() throws Exception { if(buffer == null) { throw new Exception("data body is undefined yet."); } // TODO use BufferUtil.connect. // connect the holding data. BitConnector bitConnector = new BitConnector(); ByteBuffer bitData = bitConnector.connect(pictureStartCode, version, temporalReference, pictureSize, customWidth, customHeight, pictureType, deblockingFlag, quantizer, extraInformationFlag, extraInformation, extra); int size = bitData.remaining() + buffer.remaining(); // add buffer. ByteBuffer data = ByteBuffer.allocate(size); data.put(bitData); data.put(buffer.duplicate()); data.flip(); return data; } /** * {@inheritDoc} */ @Override public void load(IReadChannel channel) throws Exception { channel.position(super.getReadPosition()); buffer = BufferUtil.safeRead(channel, getSize() - getReadPosition()); } /** * {@inheritDoc} */ @Override public void minimumLoad(IReadChannel channel) throws Exception { // for minimumload there is nothing to do. super.setWidth(width); super.setHeight(height); super.setDts(0); super.setReadPosition(channel.position()); super.setSize(channel.size()); super.update(); } /** * {@inheritDoc} */ @Override protected void requestUpdate() throws Exception { if(buffer == null) { throw new Exception("body buffer is undefined yet."); } BitConnector connector = new BitConnector(); setData(BufferUtil.connect(connector.connect(pictureStartCode, version, temporalReference, pictureSize, customWidth, customHeight, pictureType, deblockingFlag, quantizer, extraInformationFlag, extraInformation, extra), buffer)); } /** * {@inheritDoc} */ @Override public void setPts(long pts) { super.setPts(pts); } /** * {@inheritDoc} */ @Override public ByteBuffer getPackBuffer() throws Exception { // for flv1 getPacketBuffer = getData. return getData(); } /** * {@inheritDoc} */ @Override public CodecType getCodecType() { return CodecType.FLV1; } }