Skip to content

Commit

Permalink
H.264/H.265 Annex B. reading + ST 2094-10 (unfinished)
Browse files Browse the repository at this point in the history
  • Loading branch information
igorzep committed May 2, 2018
1 parent 2c239fc commit 4fd7d1f
Show file tree
Hide file tree
Showing 38 changed files with 4,076 additions and 80 deletions.
14 changes: 14 additions & 0 deletions src/main/java/band/full/core/ArrayMath.java
Original file line number Diff line number Diff line change
Expand Up @@ -40,4 +40,18 @@ public static double[] apply(double[] in, double[] out,

return out;
}

private final static char[] HEX = "0123456789ABCDEF".toCharArray();

public static String toHexString(byte[] bytes) {
char[] chars = new char[bytes.length * 2];

for (int i = 0, j = 0; i < bytes.length;) {
int v = bytes[i++] & 0xFF;
chars[j++] = HEX[v >>> 4];
chars[j++] = HEX[v & 0x0F];
}

return new String(chars);
}
}
5 changes: 5 additions & 0 deletions src/main/java/band/full/core/color/CIEXYZ.java
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,11 @@ public CIExyY CIExyY() {
return new CIExyY(X / sum, Y / sum, Y);
}

public CIExyY CIExyY(double yScale) {
double sum = X + Y + Z;
return new CIExyY(X / sum, Y / sum, Y * yScale);
}

public CIExy CIExy() {
double sum = X + Y + Z;
return new CIExy(X / sum, Y / sum);
Expand Down
72 changes: 72 additions & 0 deletions src/main/java/band/full/video/atsc/ATSC1.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
package band.full.video.atsc;

import band.full.video.itu.T35;
import band.full.video.itu.nal.RbspReader;
import band.full.video.itu.nal.RbspWriter;
import band.full.video.itu.nal.Structure;
import band.full.video.smpte.st2094.ST2094_10;

import java.io.PrintStream;

/**
* <code>ATSC1_data()</code>
*
* @author Igor Malinin
* @see <a href=
* "https://www.scte.org/documents/pdf/Standards/ANSI_SCTE%20128-1%202013.pdf">
* ANSI/SCTE 128-1 2013</a>
*/
public class ATSC1 implements T35, Structure {
/**
* A fixed 8-bit field, the value of which shall be 0xB5.
*/
public static final int COUNTRY_CODE = UNITED_STATES;

/**
* A fixed 16-bit field registered by the ATSC. The value shall be 0x0031.
*/
public static final int PROVIDER_CODE = 0x0031;

/**
* This is a 32 bit code that indicates the contents of the
* <code>user_structure()</code>.
*/
public static final int USER_IDENTIFIER = 0x47413934; // "GA94"

public static final byte MARKER_BITS = (byte) 0xFF;

public short user_data_type_code; // u8
public Structure user_data_type_structure;
public byte[] bytes;

@Override
public void read(RbspReader reader) {
user_data_type_code = reader.readUShort(8);
if (user_data_type_code == 0x09) {
ST2094_10 dm = new ST2094_10();
dm.read(reader);
user_data_type_structure = dm;
int marker_bits = reader.readByte();
if (marker_bits != -1) throw new IllegalStateException();

} else {
bytes = reader.readTrailingBits();
}
}

@Override
public void write(RbspWriter writer) {
writer.writeU(8, user_data_type_code);
if (user_data_type_code == 0x09) {
user_data_type_structure.write(writer);
writer.writeS8(MARKER_BITS);
} else {
writer.writeBytes(bytes);
}
}

@Override
public void print(PrintStream ps) {
// TODO Auto-generated method stub
}
}
14 changes: 14 additions & 0 deletions src/main/java/band/full/video/itu/T35.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package band.full.video.itu;

/**
* Procedure for the allocation of ITU-T defined codes for non-standard
* facilities.
*
* @author Igor Malinin
* @see <a href=
* "https://www.itu.int/rec/dologin_pub.asp?lang=e&id=T-REC-T.35-200002-I!!PDF-E&type=items">
* Rec. ITU-T T.35 (02/2000)</a>
*/
public interface T35 {
public static final int UNITED_STATES = 0b10110101; // 0xB5
}
23 changes: 23 additions & 0 deletions src/main/java/band/full/video/itu/h264/H264ReaderAnnexB.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package band.full.video.itu.h264;

import band.full.video.itu.nal.NalReaderAnnexB;
import band.full.video.itu.nal.RbspReader;

import java.io.IOException;
import java.io.InputStream;

public class H264ReaderAnnexB extends NalReaderAnnexB<NALUnit> {
public H264ReaderAnnexB(InputStream in) throws IOException {
super(in);
}

/** for unit testing */
H264ReaderAnnexB(byte[] nal) {
super(nal);
}

@Override
protected NALUnit create(boolean zero_byte, RbspReader nalu) {
return NALUnit.create(zero_byte, nalu);
}
}
40 changes: 40 additions & 0 deletions src/main/java/band/full/video/itu/h264/NALU.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
package band.full.video.itu.h264;

import static band.full.core.ArrayMath.toHexString;

import band.full.video.itu.nal.RbspReader;
import band.full.video.itu.nal.RbspWriter;

import java.io.PrintStream;

/**
* Generic NAL Unit for all unknow types, stores RBSP bytes.
*
* @author Igor Malinin
*/
public class NALU extends NALUnit {
public byte[] bytes;

public NALU(NALUnitType type) {
super(type);
}

@Override
public void read(RbspReader reader) {
bytes = reader.readTrailingBits();
}

@Override
public void write(RbspWriter writer) {
writer.writeTrailingBits(bytes);
}

@Override
public void print(PrintStream ps) {
ps.println(" size: " + bytes.length);
if (bytes.length <= 256) {
ps.print(" bytes: 0x");
ps.println(toHexString(bytes));
}
}
}
45 changes: 45 additions & 0 deletions src/main/java/band/full/video/itu/h264/NALUnit.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
package band.full.video.itu.h264;

import band.full.video.itu.nal.NalUnit;
import band.full.video.itu.nal.RbspReader;

public abstract class NALUnit extends NalUnit {
// nal_unit_header
public byte nal_ref_idc;
public final NALUnitType type;

public NALUnit(NALUnitType type) {
this.type = type;
}

@Override
public String getTypeString() {
return type.fullName + " (" + type.shortName + ")";
}

@Override
public String getHeaderParamsString() {
return "RefIDC " + nal_ref_idc;
}

public static NALUnit create(RbspReader reader) {
return create(false, reader);
}

public static NALUnit create(boolean zero_byte, RbspReader reader) {
// nal_unit_header
if (reader.readU1())
throw new IllegalStateException("forbidden_zero_bit is 1");

byte nal_ref_idc = reader.readUByte(2);
NALUnitType type = NALUnitType.get(reader.readUInt(5));
NALUnit nalu = type.createNALU();

nalu.zero_byte = zero_byte;
nalu.nal_ref_idc = nal_ref_idc;

// *_rbsp()
nalu.read(reader);
return nalu;
}
}
79 changes: 79 additions & 0 deletions src/main/java/band/full/video/itu/h264/NALUnitType.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
package band.full.video.itu.h264;

import java.util.function.Supplier;

public enum NALUnitType {
UNSPEC0("Unspecified 0"),
CS_NIDR("Coded slice of a non-IDR picture"),
CS_A("Coded slice data partition A"),
CS_B("Coded slice data partition B"),
CS_C("Coded slice data partition C"),
CS_IDR("Coded slice of an IDR picture"),
SEI_NUT("Supplemental enhancement information"),
SPS_NUT("Sequence parameter set"),
PPS_NUT("Picture parameter set"),
AUD_NUT("Access unit delimiter"),
EOS_NUT("End of sequence"),
EOB_NUT("End of bitstream"),
FD_NUT("Filler data"),
SPS_EXT("Sequence parameter set extension"),
PREFIX_NUT("Prefix NAL unit"),
SUBSPS_NUT("Subset sequence parameter set"),
DPS_NUT("Depth parameter set"),
RSV_NVCL17("Reserved 17"),
RSV_NVCL18("Reserved 18"),
CS_AUX("Coded slice of an auxiliary coded picture without partitioning"),
CS_EXT("Coded slice extension"),
CS_3D("Coded slice extension for a depth view component or a 3D-AVC texture view component"),
RSV_NVCL22("Reserved 22"),
RSV_NVCL23("Reserved 23"),
UNSPEC24("Unspecified 24"),
UNSPEC25("Unspecified 25"),
UNSPEC26("Unspecified 26"),
UNSPEC27("Unspecified 27"),
UNSPEC28("Unspecified 28"),
UNSPEC29("Unspecified 29"),
UNSPEC30("Unspecified 30"),
UNSPEC31("Unspecified 31");

public final String shortName;
public final String fullName;
public final Supplier<NALUnit> constructor;

private NALUnitType(String fullName) {
this(null, fullName, null);
}

private NALUnitType(String fullName, Supplier<NALUnit> constructor) {
this(null, fullName, constructor);
}

private NALUnitType(String shortName, String fullName,
Supplier<NALUnit> constructor) {
String name = name();

this.shortName = name.endsWith("_NUT")
? name.substring(0, name.length() - 4)
: name;

this.fullName = fullName;

this.constructor = constructor == null
? () -> new NALU(this)
: constructor;
}

public NALUnit createNALU() {
return constructor.get();
}

private static NALUnitType[] CACHE = values();

public static NALUnitType get(int ordinal) {
try {
return CACHE[ordinal];
} catch (IndexOutOfBoundsException e) {
return null;
}
}
}
42 changes: 42 additions & 0 deletions src/main/java/band/full/video/itu/h265/AUD.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
package band.full.video.itu.h265;

import static band.full.video.itu.h265.NALUnitType.AUD_NUT;

import band.full.video.itu.nal.RbspReader;
import band.full.video.itu.nal.RbspWriter;

import java.io.PrintStream;

/**
* 7.3.2.5 Access unit delimiter RBSP syntax
* <p>
* <code>access_unit_delimiter_rbsp()</code>
*
* @author Igor Malinin
*/
public class AUD extends NALUnit {
public byte pic_type;
public byte[] trailing_bits;

public AUD() {
super(AUD_NUT);
}

@Override
public void read(RbspReader reader) {
pic_type = reader.readUByte(3);
trailing_bits = reader.readTrailingBits();
}

@Override
public void write(RbspWriter writer) {
writer.writeU(3, pic_type);
writer.writeTrailingBits(trailing_bits);
}

@Override
public void print(PrintStream ps) {
ps.print(" pic_type: ");
ps.println(pic_type);
}
}
23 changes: 23 additions & 0 deletions src/main/java/band/full/video/itu/h265/H265ReaderAnnexB.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package band.full.video.itu.h265;

import band.full.video.itu.nal.NalReaderAnnexB;
import band.full.video.itu.nal.RbspReader;

import java.io.IOException;
import java.io.InputStream;

public class H265ReaderAnnexB extends NalReaderAnnexB<NALUnit> {
public H265ReaderAnnexB(InputStream in) throws IOException {
super(in);
}

/** for unit testing */
H265ReaderAnnexB(byte[] nal) {
super(nal);
}

@Override
protected NALUnit create(boolean zero_byte, RbspReader nalu) {
return NALUnit.create(zero_byte, nalu);
}
}
Loading

0 comments on commit 4fd7d1f

Please sign in to comment.