/*
* myLib - https://github.com/taktod/myLib
* Copyright (c) 2014 ttProject. All rights reserved.
*
* Licensed under The MIT license.
*/
package com.ttProject.frame.h264;
import org.apache.log4j.Logger;
import com.ttProject.frame.VideoSelector;
import com.ttProject.frame.h264.type.AccessUnitDelimiter;
import com.ttProject.frame.h264.type.FilterData;
import com.ttProject.frame.h264.type.PictureParameterSet;
import com.ttProject.frame.h264.type.SequenceParameterSet;
import com.ttProject.frame.h264.type.Slice;
import com.ttProject.frame.h264.type.SliceIDR;
import com.ttProject.frame.h264.type.SupplementalEnhancementInformation;
import com.ttProject.nio.channels.IReadChannel;
import com.ttProject.unit.IUnit;
import com.ttProject.unit.extra.BitLoader;
import com.ttProject.unit.extra.bit.Bit1;
import com.ttProject.unit.extra.bit.Bit2;
import com.ttProject.unit.extra.bit.Bit5;
/**
* selector for h264 frame
* @author taktod
*/
public class H264FrameSelector extends VideoSelector {
/** logger */
@SuppressWarnings("unused")
private Logger logger = Logger.getLogger(H264FrameSelector.class);
// TODO we need to handle with multiple sps and pps.(in some case, spsext.)
/** sps */
private SequenceParameterSet sps = null;
/** pps */
private PictureParameterSet pps = null;
/**
* {@inheritDoc}
*/
@Override
public IUnit select(IReadChannel channel) throws Exception {
if(channel.position() == channel.size()) {
return null;
}
BitLoader loader = new BitLoader(channel);
Bit1 forbiddenZeroBit = new Bit1();
Bit2 nalRefIdc = new Bit2();
Bit5 type = new Bit5();
loader.load(forbiddenZeroBit, nalRefIdc, type);
H264Frame frame = null;
switch(Type.getType(type.get())) {
case AccessUnitDelimiter:
frame = new AccessUnitDelimiter(forbiddenZeroBit, nalRefIdc, type);
break;
case PictureParameterSet:
frame = new PictureParameterSet(forbiddenZeroBit, nalRefIdc, type);
pps = (PictureParameterSet)frame;
break;
case SequenceParameterSet:
frame = new SequenceParameterSet(forbiddenZeroBit, nalRefIdc, type);
sps = (SequenceParameterSet)frame;
break;
case Slice: // innerFrame
frame = new Slice(forbiddenZeroBit, nalRefIdc, type);
break;
case SliceIDR: // keyFrame
frame = new SliceIDR(forbiddenZeroBit, nalRefIdc, type);
break;
case SupplementalEnhancementInformation:
frame = new SupplementalEnhancementInformation(forbiddenZeroBit, nalRefIdc, type);
break;
case FilterData:
frame = new FilterData(forbiddenZeroBit, nalRefIdc, type);
break;
default:
throw new Exception("unexpected frame:" + type.get() + " / " + Type.getType(type.get()));
}
setup(frame);
if(!(frame instanceof SequenceParameterSet)) {
frame.setSps(sps);
if(!(frame instanceof PictureParameterSet)) {
frame.setPps(pps);
}
}
frame.minimumLoad(channel);
/* if(frame instanceof SequenceParameterSet) {
// ref for many data for sps.
SequenceParameterSet sps = (SequenceParameterSet)frame;
logger.info(sps.getNalHrdBpPresentFlag());
logger.info(sps.getVclHrdBpPresentFlag());
logger.info(sps.getCpbDpbDelaysPresentFlag());
logger.info(sps.getInitialCpbRemovalDelayLengthMinus1());
logger.info("timeOffsetLength" + sps.getTimeOffsetLength());
}*/
return frame;
}
}