/* * myLib - https://github.com/taktod/myLib * Copyright (c) 2014 ttProject. All rights reserved. * * Licensed under The MIT license. */ package com.ttProject.frame.h265; import java.nio.ByteBuffer; import java.util.ArrayList; import java.util.List; import org.apache.log4j.Logger; import com.ttProject.nio.channels.ByteReadChannel; import com.ttProject.nio.channels.IReadChannel; import com.ttProject.unit.ISelector; import com.ttProject.unit.extra.BitLoader; import com.ttProject.unit.extra.bit.Bit1; import com.ttProject.unit.extra.bit.Bit12; import com.ttProject.unit.extra.bit.Bit16; import com.ttProject.unit.extra.bit.Bit2; import com.ttProject.unit.extra.bit.Bit3; import com.ttProject.unit.extra.bit.Bit32; import com.ttProject.unit.extra.bit.Bit4; import com.ttProject.unit.extra.bit.Bit48; import com.ttProject.unit.extra.bit.Bit5; import com.ttProject.unit.extra.bit.Bit6; import com.ttProject.unit.extra.bit.Bit8; import com.ttProject.util.BufferUtil; import com.ttProject.util.HexUtil; /** * configData for h264 * hvcC for mp4 is this data. * @author taktod * 01 01 60 00 00 00 80 00 00 00 00 00 5D F0 00 FC FD F8 F8 00 00 0F 03 20 00 01 00 18 40 01 0C 01 FF FF 01 60 00 00 03 00 80 00 00 03 00 00 03 00 5D 95 C0 90 21 00 01 00 29 42 01 01 01 60 00 00 03 00 80 00 00 03 00 00 03 00 5D A0 07 82 00 B4 59 65 79 24 DA F0 10 10 00 00 03 00 30 00 00 05 60 80 22 00 01 00 06 44 01 C1 73 D1 89 */ public class ConfigData { /** logger */ private Logger logger = Logger.getLogger(ConfigData.class); private H265FrameSelector selector = null; private Bit8 configurationVersion = new Bit8(); private Bit2 generalProfileSpace = new Bit2(); private Bit1 generalTierFlag = new Bit1(); private Bit5 generalProfileIdc = new Bit5(); private Bit32 generalProfileCompatibilityFlags = new Bit32(); private Bit48 generalConstraintIndicatorFlags = new Bit48(); private Bit8 generalLevelIdc = new Bit8(); private Bit4 reserved1 = new Bit4(); private Bit12 minSpatialSegmentationIdc = new Bit12(); private Bit6 reserved2 = new Bit6(); private Bit2 parallelismType = new Bit2(); private Bit6 reserved3 = new Bit6(); private Bit2 chromaFormat = new Bit2(); private Bit5 reserved4 = new Bit5(); private Bit3 bitDepthLumaMinus8 = new Bit3(); private Bit5 reserved5 = new Bit5(); private Bit3 bitDepthChromaMinus8 = new Bit3(); private Bit16 avgFrameRate = new Bit16(); private Bit2 constantFrameRate = new Bit2(); private Bit3 numTemporalLayers = new Bit3(); private Bit1 temporalIdNested = new Bit1(); private Bit2 lengthSizeMinusOne = new Bit2(); private Bit8 numOfArrays = new Bit8(); private Bit1 arrayCompleteness; private Bit1 reserved; private Bit6 nalUnitType; private Bit16 numNalus; private Bit16 nalUnitLength; private List<H265Frame> nalList = new ArrayList<H265Frame>(); public void setSelector(H265FrameSelector selector) { this.selector = selector; } /** * ref the byte size of data nal size information. * @return */ public int getNalSizeBytes() { return lengthSizeMinusOne.get() + 1; } /** * analyze h265 ConfigData * @param channel * @throws Exception */ public void analyze(IReadChannel channel) throws Exception { ISelector selector = null; if(this.selector != null) { selector = this.selector; } else { selector = new H265FrameSelector(); } BitLoader loader = new BitLoader(channel); loader.load(configurationVersion, generalProfileSpace, generalTierFlag, generalProfileIdc, generalProfileCompatibilityFlags, generalConstraintIndicatorFlags, generalLevelIdc, reserved1, minSpatialSegmentationIdc, reserved2, parallelismType, reserved3, chromaFormat, reserved4, bitDepthLumaMinus8, reserved5, bitDepthChromaMinus8, avgFrameRate, constantFrameRate, numTemporalLayers, temporalIdNested, lengthSizeMinusOne, numOfArrays); logger.info(numOfArrays.get()); for(int i = 0;i < numOfArrays.get();i ++) { arrayCompleteness = new Bit1(); reserved = new Bit1(); nalUnitType = new Bit6(); numNalus = new Bit16(); loader.load(arrayCompleteness, reserved, nalUnitType, numNalus); logger.info(nalUnitType.get()); logger.info(Type.getType(nalUnitType.get())); logger.info(numNalus.get()); for(int j = 0;j < numNalus.get();j ++) { nalUnitLength = new Bit16(); loader.load(nalUnitLength); logger.info(nalUnitLength.get()); ByteBuffer data = BufferUtil.safeRead(channel, nalUnitLength.get()); logger.info(HexUtil.toHex(data, true)); IReadChannel nalChannel = new ByteReadChannel(data); H265Frame nal = (H265Frame)selector.select(nalChannel); nalList.add(nal); } } } }