Package entagged.audioformats.asf.io

Source Code of entagged.audioformats.asf.io.StreamChunkReader

/*
* Entagged Audio Tag library
* Copyright (c) 2004-2005 Christian Laireiter <liree@web.de>
*
* This library 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 2.1 of the License, or (at your option) any later version.
* This library 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, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
*/
package entagged.audioformats.asf.io;

import java.io.IOException;
import java.io.RandomAccessFile;
import java.math.BigInteger;

import entagged.audioformats.asf.data.AudioStreamChunk;
import entagged.audioformats.asf.data.Chunk;
import entagged.audioformats.asf.data.GUID;
import entagged.audioformats.asf.data.StreamChunk;
import entagged.audioformats.asf.data.VideoStreamChunk;
import entagged.audioformats.asf.util.Utils;

/**
* Reads and interprets the data of the audio or video stream information chunk.
* <br>
*
* @author Christian Laireiter
*/
public class StreamChunkReader {

  /**
   * Shouldn't be used for now.
   * 
   */
  protected StreamChunkReader() {
    // Nothin todo
  }

  /**
   * Reads audio and video stream information.
   *
   * @param raf
   *                  input source.
   * @param candidate
   *                  possible audio stream chunk
   * @return Audio Stream Information. <code>null</code> if its not an audio
   *              stream object.
   * @throws IOException
   *                   read errors
   */
  public static StreamChunk read(RandomAccessFile raf, Chunk candidate)
      throws IOException {
    if (raf == null || candidate == null) {
      throw new IllegalArgumentException("Arguments must not be null.");
    }
    if (GUID.GUID_STREAM.equals(candidate.getGuid())) {
      raf.seek(candidate.getPosition());
      return new StreamChunkReader().parseData(raf);
    }
    return null;
  }

  /**
   * Reads audio and video stream information.
   *
   * @param raf
   *                  input source.
   * @return Audio Stream Information. <code>null</code> if its not an audio
   *              stream object.
   * @throws IOException
   *                   read errors
   */
  private StreamChunk parseData(RandomAccessFile raf) throws IOException {
    StreamChunk result = null;
    long chunkStart = raf.getFilePointer();
    GUID guid = Utils.readGUID(raf);
    if (GUID.GUID_STREAM.equals(guid)) {
      BigInteger chunkLength = Utils.readBig64(raf);
      // Now comes GUID indicating whether stream content type is audio or
      // video
      GUID streamTypeGUID = Utils.readGUID(raf);
      if (GUID.GUID_AUDIOSTREAM.equals(streamTypeGUID)
          || GUID.GUID_VIDEOSTREAM.equals(streamTypeGUID)) {

        // A guid is indicating whether the stream is error
        // concealed
        GUID errorConcealment = Utils.readGUID(raf);
        /*
         * Read the Time Offset
         */
        long timeOffset = Utils.readUINT64(raf);

        long typeSpecificDataSize = Utils.readUINT32(raf);
        long streamSpecificDataSize = Utils.readUINT32(raf);

        /*
         * Read a bitfield. (Contains streamnumber, and whether
         * the stream content is encrypted.)
         */
        int mask = Utils.readUINT16(raf);
        int streamNumber = mask & 127;
        boolean contentEncrypted = (mask & (1 << 15)) != 0;
       
        /*
         * Skip a reserved field
         */
        raf.skipBytes(4);

        if (GUID.GUID_AUDIOSTREAM.equals(streamTypeGUID)) {
          /*
           * Reading audio specific information
           */
          AudioStreamChunk audioStreamChunk = new AudioStreamChunk(
              chunkStart, chunkLength);
          result = audioStreamChunk;

          /*
           * read WAVEFORMATEX and format extension.
           */
          long compressionFormat = Utils.readUINT16(raf);
          long channelCount = Utils.readUINT16(raf);
          long samplingRate = Utils.readUINT32(raf);
          long avgBytesPerSec = Utils.readUINT32(raf);
          long blockAlignment = Utils.readUINT16(raf);
          int bitsPerSample = Utils.readUINT16(raf);
          int codecSpecificDataSize = Utils.readUINT16(raf);
          byte[] codecSpecificData = new byte[codecSpecificDataSize];
          raf.readFully(codecSpecificData);

          audioStreamChunk.setCompressionFormat(compressionFormat);
          audioStreamChunk.setChannelCount(channelCount);
          audioStreamChunk.setSamplingRate(samplingRate);
          audioStreamChunk.setAverageBytesPerSec(avgBytesPerSec);
          audioStreamChunk.setErrorConcealment(errorConcealment);
          audioStreamChunk.setBlockAlignment(blockAlignment);
          audioStreamChunk.setBitsPerSample (bitsPerSample);
          audioStreamChunk.setCodecData (codecSpecificData);
        } else if (GUID.GUID_VIDEOSTREAM.equals(streamTypeGUID)) {
          /*
           * Reading video specific information
           */
          VideoStreamChunk videoStreamChunk = new VideoStreamChunk(
              chunkStart, chunkLength);
          result = videoStreamChunk;

          long pictureWidth = Utils.readUINT32(raf);
          long pictureHeight = Utils.readUINT32(raf);

          // Skipt unknown field
          raf.skipBytes(1);

          /*
           * Now read the format specific data
           */
          // Size of the data section
          Utils.readUINT16(raf);
         
          raf.skipBytes(16);
          byte[] fourCC = new byte[4];
          raf.read(fourCC);
 
          videoStreamChunk.setPictureWidth(pictureWidth);
          videoStreamChunk.setPictureHeight(pictureHeight);
          videoStreamChunk.setCodecId(fourCC);
        }

        /*
         * Setting common values for audio and video
         */
        result.setStreamNumber(streamNumber);
        result.setStreamSpecificDataSize(streamSpecificDataSize);
        result.setTypeSpecificDataSize(typeSpecificDataSize);
        result.setTimeOffset(timeOffset);
        result.setContentEncrypted(contentEncrypted);
      }
    }
    return result;
  }

}
TOP

Related Classes of entagged.audioformats.asf.io.StreamChunkReader

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.