/*
* myLib - https://github.com/taktod/myLib
* Copyright (c) 2014 ttProject. All rights reserved.
*
* Licensed under The MIT license.
*/
package com.ttProject.media.aac;
import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.List;
import org.apache.log4j.Logger;
import com.ttProject.media.Manager;
import com.ttProject.media.aac.frame.Aac;
import com.ttProject.media.extra.Bit1;
import com.ttProject.media.extra.Bit2;
import com.ttProject.media.extra.Bit3;
import com.ttProject.media.extra.Bit4;
import com.ttProject.media.extra.Bit5;
import com.ttProject.media.extra.Bit8;
import com.ttProject.media.extra.BitLoader;
import com.ttProject.nio.channels.ByteReadChannel;
import com.ttProject.nio.channels.IReadChannel;
/**
* ADTS方式であるとして、Aacのデータを解析します。
* @see http://blog-imgs-18-origin.fc2.com/n/a/n/nanncyatte/aacfileheader.png
* @author taktod
*/
public class AacManager extends Manager<Frame> {
/** ロガー */
private Logger logger = Logger.getLogger(AacManager.class);
/**
* adtsの形式としてデータを取り出します。
*/
@Override
public List<Frame> getUnits(ByteBuffer data) throws Exception {
ByteBuffer buffer = appendBuffer(data);
if(buffer == null) {
return null;
}
IReadChannel bufferChannel = new ByteReadChannel(buffer);
List<Frame> result = new ArrayList<Frame>();
while(true) {
int position = bufferChannel.position();
Frame frame = getUnit(bufferChannel);
if(frame == null) {
buffer.position(position);
break;
}
frame.analyze(bufferChannel);
logger.info("size:" + bufferChannel.size() + " pos:" + (position + frame.getSize()));
bufferChannel.position(position + frame.getSize());
result.add(frame);
}
return result;
}
@Override
public Frame getUnit(IReadChannel source) throws Exception {
// frameUnitを解析します。
// headerは7バイトで構成されているので、7バイト存在しない場合は処理できません。
if(source.size() - source.position() < 7) {
return null;
}
int position = source.position();
Bit4 syncBit_1 = new Bit4();
Bit8 syncBit_2 = new Bit8();
Bit1 id = new Bit1();
Bit2 layer = new Bit2();
Bit1 protectionAbsent = new Bit1();
Bit2 profile = new Bit2();
Bit4 samplingFrequenceIndex = new Bit4();
Bit1 privateBit = new Bit1();
Bit3 channelConfiguration = new Bit3();
Bit1 originalFlg = new Bit1();
Bit1 home = new Bit1();
Bit1 copyrightIdentificationBit = new Bit1();
Bit1 copyrightIdentificationStart = new Bit1();
Bit5 frameSize_1 = new Bit5();
Bit8 frameSize_2 = new Bit8();
Bit3 adtsBufferFullness_1 = new Bit3();
Bit8 adtsBufferFullness_2 = new Bit8();
Bit2 noRawDataBlocksInFrame = new Bit2();
BitLoader bitLoader = new BitLoader(source);
bitLoader.load(
syncBit_1, syncBit_2, id, layer, protectionAbsent, profile, samplingFrequenceIndex,
privateBit, channelConfiguration, originalFlg, home,
copyrightIdentificationBit, copyrightIdentificationStart, frameSize_1, frameSize_2,
adtsBufferFullness_1, adtsBufferFullness_2, noRawDataBlocksInFrame);
int size = (frameSize_1.get() << 8) + frameSize_2.get();
Aac aac = new Aac(position, size, id, layer, protectionAbsent, profile, samplingFrequenceIndex, privateBit, channelConfiguration, originalFlg, home, copyrightIdentificationBit, copyrightIdentificationStart, size, (adtsBufferFullness_1.get() << 8) + adtsBufferFullness_2.get(), noRawDataBlocksInFrame);
if(aac.getPosition() + aac.getSize() > source.size()) {
return null;
}
return aac;
}
}