Package net.sourceforge.jaad.aac

Source Code of net.sourceforge.jaad.aac.DecoderConfig

/*
*  Copyright (C) 2011 in-somnia
*
*  This file is part of JAAD.
*
*  JAAD is free software; you can redistribute it and/or modify it
*  under the terms of the GNU Lesser General Public License as
*  published by the Free Software Foundation; either version 3 of the
*  License, or (at your option) any later version.
*
*  JAAD is distributed in the hope that it will be useful, but WITHOUT
*  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
*  or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General
*  Public License for more details.
*
*  You should have received a copy of the GNU Lesser General Public
*  License along with this library.
*  If not, see <http://www.gnu.org/licenses/>.
*/
package net.sourceforge.jaad.aac;

import net.sourceforge.jaad.aac.syntax.BitStream;
import net.sourceforge.jaad.aac.syntax.Constants;
import net.sourceforge.jaad.aac.syntax.PCE;

/**
* DecoderConfig that must be passed to the <code>Decoder</code> constructor.
* Typically it is created via one of the static parsing methods.
* @author in-somnia
*/
public class DecoderConfig implements Constants {

  private Profile profile, extProfile;
  private SampleFrequency sampleFrequency;
  private ChannelConfiguration channelConfiguration;
  private boolean frameLengthFlag;
  private boolean dependsOnCoreCoder;
  private int coreCoderDelay;
  private boolean extensionFlag;
  //extension: SBR
  private boolean sbrPresent, downSampledSBR;
  //extension: error resilience
  private boolean sectionDataResilience, scalefactorResilience, spectralDataResilience;

  private DecoderConfig() {
    profile = Profile.AAC_MAIN;
    extProfile = Profile.UNKNOWN;
    sampleFrequency = SampleFrequency.SAMPLE_FREQUENCY_NONE;
    channelConfiguration = ChannelConfiguration.CHANNEL_CONFIG_UNSUPPORTED;
    frameLengthFlag = false;
    sbrPresent = false;
    downSampledSBR = false;
    sectionDataResilience = false;
    scalefactorResilience = false;
    spectralDataResilience = false;
  }

  /* ========== gets/sets ========== */
  public ChannelConfiguration getChannelConfiguration() {
    return channelConfiguration;
  }

  public void setChannelConfiguration(ChannelConfiguration channelConfiguration) {
    this.channelConfiguration = channelConfiguration;
  }

  public int getCoreCoderDelay() {
    return coreCoderDelay;
  }

  public void setCoreCoderDelay(int coreCoderDelay) {
    this.coreCoderDelay = coreCoderDelay;
  }

  public boolean isDependsOnCoreCoder() {
    return dependsOnCoreCoder;
  }

  public void setDependsOnCoreCoder(boolean dependsOnCoreCoder) {
    this.dependsOnCoreCoder = dependsOnCoreCoder;
  }

  public Profile getExtObjectType() {
    return extProfile;
  }

  public void setExtObjectType(Profile extObjectType) {
    this.extProfile = extObjectType;
  }

  public int getFrameLength() {
    return frameLengthFlag ? WINDOW_SMALL_LEN_LONG : WINDOW_LEN_LONG;
  }

  public boolean isSmallFrameUsed() {
    return frameLengthFlag;
  }

  public void setSmallFrameUsed(boolean shortFrame) {
    this.frameLengthFlag = shortFrame;
  }

  public Profile getProfile() {
    return profile;
  }

  public void setProfile(Profile profile) {
    this.profile = profile;
  }

  public SampleFrequency getSampleFrequency() {
    return sampleFrequency;
  }

  public void setSampleFrequency(SampleFrequency sampleFrequency) {
    this.sampleFrequency = sampleFrequency;
  }

  //=========== SBR =============
  public boolean isSBRPresent() {
    return sbrPresent;
  }

  public void setSBRPresent(boolean sbrPresent) {
    this.sbrPresent = sbrPresent;
  }

  public boolean isSBRDownSampled() {
    return downSampledSBR;
  }

  //=========== ER =============
  public boolean isScalefactorResilienceUsed() {
    return scalefactorResilience;
  }

  public boolean isSectionDataResilienceUsed() {
    return sectionDataResilience;
  }

  public boolean isSpectralDataResilienceUsed() {
    return spectralDataResilience;
  }

  /* ======== static builder ========= */
  /**
   * Parses the input arrays as a DecoderSpecificInfo, as used in MP4
   * containers.
   * @return a DecoderConfig
   */
  static DecoderConfig parseMP4DecoderSpecificInfo(byte[] data) throws AACException {
    final BitStream in = new BitStream(data);
    final DecoderConfig config = new DecoderConfig();

    try {
      config.profile = readProfile(in);

      int sf = in.readBits(4);
      if(sf==0xF) config.sampleFrequency = SampleFrequency.forFrequency(in.readBits(24));
      else config.sampleFrequency = SampleFrequency.forInt(sf);
      config.channelConfiguration = ChannelConfiguration.forInt(in.readBits(4));

      switch(config.profile) {
        case AAC_SBR:
          config.extProfile = config.profile;
          config.sbrPresent = true;
          sf = in.readBits(4);
          //TODO: 24 bits already read; read again?
          //if(sf==0xF) config.sampleFrequency = SampleFrequency.forFrequency(in.readBits(24));
          //if sample frequencies are the same: downsample SBR
          config.downSampledSBR = config.sampleFrequency.getIndex()==sf;
          config.sampleFrequency = SampleFrequency.forInt(sf);
          config.profile = readProfile(in);
          break;
        case AAC_MAIN:
        case AAC_LC:
        case AAC_SSR:
        case AAC_LTP:
        case ER_AAC_LC:
        case ER_AAC_LTP:
        case ER_AAC_LD:
          //ga-specific info:
          config.frameLengthFlag = in.readBool();
          if(config.frameLengthFlag) throw new AACException("config uses 960-sample frames, not yet supported"); //TODO: are 960-frames working yet?
          config.dependsOnCoreCoder = in.readBool();
          if(config.dependsOnCoreCoder) config.coreCoderDelay = in.readBits(14);
          else config.coreCoderDelay = 0;
          config.extensionFlag = in.readBool();

          if(config.extensionFlag) {
            if(config.profile.isErrorResilientProfile()) {
              config.sectionDataResilience = in.readBool();
              config.scalefactorResilience = in.readBool();
              config.spectralDataResilience = in.readBool();
            }
            //extensionFlag3
            in.skipBit();
          }

          if(config.channelConfiguration==ChannelConfiguration.CHANNEL_CONFIG_NONE) {
            //TODO: is this working correct? -> ISO 14496-3 part 1: 1.A.4.3
            in.skipBits(3); //PCE
            PCE pce = new PCE();
            pce.decode(in);
            config.profile = pce.getProfile();
            config.sampleFrequency = pce.getSampleFrequency();
            config.channelConfiguration = ChannelConfiguration.forInt(pce.getChannelCount());
          }

          if(in.getBitsLeft()>10) readSyncExtension(in, config);
          break;
        default:
          throw new AACException("profile not supported: "+config.profile.getIndex());
      }
      return config;
    }
    finally {
      in.destroy();
    }
  }

  private static Profile readProfile(BitStream in) throws AACException {
    int i = in.readBits(5);
    if(i==31) i = 32+in.readBits(6);
    return Profile.forInt(i);
  }

  private static void readSyncExtension(BitStream in, DecoderConfig config) throws AACException {
    final int type = in.readBits(11);
    switch(type) {
      case 0x2B7:
        final Profile profile = Profile.forInt(in.readBits(5));

        if(profile.equals(Profile.AAC_SBR)) {
          config.sbrPresent = in.readBool();
          if(config.sbrPresent) {
            config.profile = profile;

            int tmp = in.readBits(4);

            if(tmp==config.sampleFrequency.getIndex()) config.downSampledSBR = true;
            if(tmp==15) {
              throw new AACException("sample rate specified explicitly, not supported yet!");
              //tmp = in.readBits(24);
            }
          }
        }
        break;
    }
  }
}
TOP

Related Classes of net.sourceforge.jaad.aac.DecoderConfig

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.