diff options
Diffstat (limited to 'isoparser/src/main/java/com/googlecode/mp4parser/h264')
40 files changed, 5153 insertions, 0 deletions
diff --git a/isoparser/src/main/java/com/googlecode/mp4parser/h264/.svn/all-wcprops b/isoparser/src/main/java/com/googlecode/mp4parser/h264/.svn/all-wcprops new file mode 100644 index 0000000..6a318ac --- /dev/null +++ b/isoparser/src/main/java/com/googlecode/mp4parser/h264/.svn/all-wcprops @@ -0,0 +1,23 @@ +K 25 +svn:wc:ra_dav:version-url +V 77 +/svn/!svn/ver/528/trunk/isoparser/src/main/java/com/googlecode/mp4parser/h264 +END +CharCache.java +K 25 +svn:wc:ra_dav:version-url +V 92 +/svn/!svn/ver/236/trunk/isoparser/src/main/java/com/googlecode/mp4parser/h264/CharCache.java +END +BTree.java +K 25 +svn:wc:ra_dav:version-url +V 88 +/svn/!svn/ver/236/trunk/isoparser/src/main/java/com/googlecode/mp4parser/h264/BTree.java +END +Debug.java +K 25 +svn:wc:ra_dav:version-url +V 88 +/svn/!svn/ver/236/trunk/isoparser/src/main/java/com/googlecode/mp4parser/h264/Debug.java +END diff --git a/isoparser/src/main/java/com/googlecode/mp4parser/h264/.svn/entries b/isoparser/src/main/java/com/googlecode/mp4parser/h264/.svn/entries new file mode 100644 index 0000000..a6fb43e --- /dev/null +++ b/isoparser/src/main/java/com/googlecode/mp4parser/h264/.svn/entries @@ -0,0 +1,139 @@ +10 + +dir +778 +http://mp4parser.googlecode.com/svn/trunk/isoparser/src/main/java/com/googlecode/mp4parser/h264 +http://mp4parser.googlecode.com/svn + + + +2012-04-26T13:35:04.700844Z +528 +hoemmagnus@gmail.com + + + + + + + + + + + + + + +7decde4b-c250-0410-a0da-51896bc88be6 + +model +dir + +CharCache.java +file + + + + +2012-09-14T17:27:51.457232Z +c3b2a16e50a2b43f07cc729ba83f6b84 +2011-09-20T18:03:23.375910Z +236 +Sebastian.Annies@gmail.com + + + + + + + + + + + + + + + + + + + + + +1868 + +BTree.java +file + + + + +2012-09-14T17:27:51.457232Z +3dd3d07d1bd0c3bdbcb2aeb45c375f1d +2011-09-20T18:03:23.375910Z +236 +Sebastian.Annies@gmail.com + + + + + + + + + + + + + + + + + + + + + +2116 + +Debug.java +file + + + + +2012-09-14T17:27:51.457232Z +f136a4c416c039d97eedee9f96667284 +2011-09-20T18:03:23.375910Z +236 +Sebastian.Annies@gmail.com + + + + + + + + + + + + + + + + + + + + + +2796 + +write +dir + +read +dir + diff --git a/isoparser/src/main/java/com/googlecode/mp4parser/h264/.svn/text-base/BTree.java.svn-base b/isoparser/src/main/java/com/googlecode/mp4parser/h264/.svn/text-base/BTree.java.svn-base new file mode 100644 index 0000000..57391ba --- /dev/null +++ b/isoparser/src/main/java/com/googlecode/mp4parser/h264/.svn/text-base/BTree.java.svn-base @@ -0,0 +1,69 @@ +/* +Copyright (c) 2011 Stanislav Vitvitskiy + +Permission is hereby granted, free of charge, to any person obtaining a copy of this +software and associated documentation files (the "Software"), to deal in the Software +without restriction, including without limitation the rights to use, copy, modify, +merge, publish, distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice shall be included in all copies or +substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, +INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR +PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE +FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE +OR OTHER DEALINGS IN THE SOFTWARE. +*/ +package com.googlecode.mp4parser.h264; + + +/** + * Simple BTree implementation needed for haffman tables + * + * @author Stanislav Vitvitskiy + */ +public class BTree { + private BTree zero; + private BTree one; + private Object value; + + /** + * Adds a leaf value to a binary path specified by path + * + * @param str + * @param value + */ + public void addString(String path, Object value) { + if (path.length() == 0) { + this.value = value; + return; + } + char charAt = path.charAt(0); + BTree branch; + if (charAt == '0') { + if (zero == null) + zero = new BTree(); + branch = zero; + } else { + if (one == null) + one = new BTree(); + branch = one; + } + branch.addString(path.substring(1), value); + } + + public BTree down(int b) { + if (b == 0) + return zero; + else + return one; + } + + public Object getValue() { + return value; + } +}
\ No newline at end of file diff --git a/isoparser/src/main/java/com/googlecode/mp4parser/h264/.svn/text-base/CharCache.java.svn-base b/isoparser/src/main/java/com/googlecode/mp4parser/h264/.svn/text-base/CharCache.java.svn-base new file mode 100644 index 0000000..2fe8ead --- /dev/null +++ b/isoparser/src/main/java/com/googlecode/mp4parser/h264/.svn/text-base/CharCache.java.svn-base @@ -0,0 +1,57 @@ +/* +Copyright (c) 2011 Stanislav Vitvitskiy + +Permission is hereby granted, free of charge, to any person obtaining a copy of this +software and associated documentation files (the "Software"), to deal in the Software +without restriction, including without limitation the rights to use, copy, modify, +merge, publish, distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice shall be included in all copies or +substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, +INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR +PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE +FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE +OR OTHER DEALINGS IN THE SOFTWARE. +*/ +package com.googlecode.mp4parser.h264; + +public class CharCache { + private char[] cache; + private int pos; + + public CharCache(int capacity) { + cache = new char[capacity]; + } + + public void append(String str) { + char[] chars = str.toCharArray(); + int available = cache.length - pos; + int toWrite = chars.length < available ? chars.length : available; + System.arraycopy(chars, 0, cache, pos, toWrite); + pos += toWrite; + } + + public String toString() { + return new String(cache, 0, pos); + } + + public void clear() { + pos = 0; + } + + public void append(char c) { + if (pos < cache.length - 1) { + cache[pos] = c; + pos++; + } + } + + public int length() { + return pos; + } +} diff --git a/isoparser/src/main/java/com/googlecode/mp4parser/h264/.svn/text-base/Debug.java.svn-base b/isoparser/src/main/java/com/googlecode/mp4parser/h264/.svn/text-base/Debug.java.svn-base new file mode 100644 index 0000000..d0bea73 --- /dev/null +++ b/isoparser/src/main/java/com/googlecode/mp4parser/h264/.svn/text-base/Debug.java.svn-base @@ -0,0 +1,88 @@ +/* +Copyright (c) 2011 Stanislav Vitvitskiy + +Permission is hereby granted, free of charge, to any person obtaining a copy of this +software and associated documentation files (the "Software"), to deal in the Software +without restriction, including without limitation the rights to use, copy, modify, +merge, publish, distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice shall be included in all copies or +substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, +INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR +PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE +FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE +OR OTHER DEALINGS IN THE SOFTWARE. +*/ +package com.googlecode.mp4parser.h264; + +import java.nio.ShortBuffer; + +public class Debug { + public final static void print8x8(int[] output) { + int i = 0; + for (int x = 0; x < 8; x++) { + for (int y = 0; y < 8; y++) { + System.out.printf("%3d, ", output[i]); + i++; + } + System.out.println(); + } + } + + public final static void print8x8(short[] output) { + int i = 0; + for (int x = 0; x < 8; x++) { + for (int y = 0; y < 8; y++) { + System.out.printf("%3d, ", output[i]); + i++; + } + System.out.println(); + } + } + + public final static void print8x8(ShortBuffer output) { + for (int x = 0; x < 8; x++) { + for (int y = 0; y < 8; y++) { + System.out.printf("%3d, ", output.get()); + } + System.out.println(); + } + } + + public static void print(short[] table) { + int i = 0; + for (int x = 0; x < 8; x++) { + for (int y = 0; y < 8; y++) { + System.out.printf("%3d, ", table[i]); + i++; + } + System.out.println(); + } + } + + public static void trace(String format, Object... args) { + // System.out.printf("> " + format + "\n", args); + } + + public final static boolean debug = false; + + public static void print(int i) { + if (debug) + System.out.print(i); + } + + public static void print(String string) { + if (debug) + System.out.print(string); + } + + public static void println(String string) { + if (debug) + System.out.println(string); + } +} diff --git a/isoparser/src/main/java/com/googlecode/mp4parser/h264/BTree.java b/isoparser/src/main/java/com/googlecode/mp4parser/h264/BTree.java new file mode 100644 index 0000000..57391ba --- /dev/null +++ b/isoparser/src/main/java/com/googlecode/mp4parser/h264/BTree.java @@ -0,0 +1,69 @@ +/* +Copyright (c) 2011 Stanislav Vitvitskiy + +Permission is hereby granted, free of charge, to any person obtaining a copy of this +software and associated documentation files (the "Software"), to deal in the Software +without restriction, including without limitation the rights to use, copy, modify, +merge, publish, distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice shall be included in all copies or +substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, +INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR +PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE +FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE +OR OTHER DEALINGS IN THE SOFTWARE. +*/ +package com.googlecode.mp4parser.h264; + + +/** + * Simple BTree implementation needed for haffman tables + * + * @author Stanislav Vitvitskiy + */ +public class BTree { + private BTree zero; + private BTree one; + private Object value; + + /** + * Adds a leaf value to a binary path specified by path + * + * @param str + * @param value + */ + public void addString(String path, Object value) { + if (path.length() == 0) { + this.value = value; + return; + } + char charAt = path.charAt(0); + BTree branch; + if (charAt == '0') { + if (zero == null) + zero = new BTree(); + branch = zero; + } else { + if (one == null) + one = new BTree(); + branch = one; + } + branch.addString(path.substring(1), value); + } + + public BTree down(int b) { + if (b == 0) + return zero; + else + return one; + } + + public Object getValue() { + return value; + } +}
\ No newline at end of file diff --git a/isoparser/src/main/java/com/googlecode/mp4parser/h264/CharCache.java b/isoparser/src/main/java/com/googlecode/mp4parser/h264/CharCache.java new file mode 100644 index 0000000..2fe8ead --- /dev/null +++ b/isoparser/src/main/java/com/googlecode/mp4parser/h264/CharCache.java @@ -0,0 +1,57 @@ +/* +Copyright (c) 2011 Stanislav Vitvitskiy + +Permission is hereby granted, free of charge, to any person obtaining a copy of this +software and associated documentation files (the "Software"), to deal in the Software +without restriction, including without limitation the rights to use, copy, modify, +merge, publish, distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice shall be included in all copies or +substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, +INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR +PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE +FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE +OR OTHER DEALINGS IN THE SOFTWARE. +*/ +package com.googlecode.mp4parser.h264; + +public class CharCache { + private char[] cache; + private int pos; + + public CharCache(int capacity) { + cache = new char[capacity]; + } + + public void append(String str) { + char[] chars = str.toCharArray(); + int available = cache.length - pos; + int toWrite = chars.length < available ? chars.length : available; + System.arraycopy(chars, 0, cache, pos, toWrite); + pos += toWrite; + } + + public String toString() { + return new String(cache, 0, pos); + } + + public void clear() { + pos = 0; + } + + public void append(char c) { + if (pos < cache.length - 1) { + cache[pos] = c; + pos++; + } + } + + public int length() { + return pos; + } +} diff --git a/isoparser/src/main/java/com/googlecode/mp4parser/h264/Debug.java b/isoparser/src/main/java/com/googlecode/mp4parser/h264/Debug.java new file mode 100644 index 0000000..d0bea73 --- /dev/null +++ b/isoparser/src/main/java/com/googlecode/mp4parser/h264/Debug.java @@ -0,0 +1,88 @@ +/* +Copyright (c) 2011 Stanislav Vitvitskiy + +Permission is hereby granted, free of charge, to any person obtaining a copy of this +software and associated documentation files (the "Software"), to deal in the Software +without restriction, including without limitation the rights to use, copy, modify, +merge, publish, distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice shall be included in all copies or +substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, +INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR +PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE +FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE +OR OTHER DEALINGS IN THE SOFTWARE. +*/ +package com.googlecode.mp4parser.h264; + +import java.nio.ShortBuffer; + +public class Debug { + public final static void print8x8(int[] output) { + int i = 0; + for (int x = 0; x < 8; x++) { + for (int y = 0; y < 8; y++) { + System.out.printf("%3d, ", output[i]); + i++; + } + System.out.println(); + } + } + + public final static void print8x8(short[] output) { + int i = 0; + for (int x = 0; x < 8; x++) { + for (int y = 0; y < 8; y++) { + System.out.printf("%3d, ", output[i]); + i++; + } + System.out.println(); + } + } + + public final static void print8x8(ShortBuffer output) { + for (int x = 0; x < 8; x++) { + for (int y = 0; y < 8; y++) { + System.out.printf("%3d, ", output.get()); + } + System.out.println(); + } + } + + public static void print(short[] table) { + int i = 0; + for (int x = 0; x < 8; x++) { + for (int y = 0; y < 8; y++) { + System.out.printf("%3d, ", table[i]); + i++; + } + System.out.println(); + } + } + + public static void trace(String format, Object... args) { + // System.out.printf("> " + format + "\n", args); + } + + public final static boolean debug = false; + + public static void print(int i) { + if (debug) + System.out.print(i); + } + + public static void print(String string) { + if (debug) + System.out.print(string); + } + + public static void println(String string) { + if (debug) + System.out.println(string); + } +} diff --git a/isoparser/src/main/java/com/googlecode/mp4parser/h264/model/.svn/all-wcprops b/isoparser/src/main/java/com/googlecode/mp4parser/h264/model/.svn/all-wcprops new file mode 100644 index 0000000..87c4f5d --- /dev/null +++ b/isoparser/src/main/java/com/googlecode/mp4parser/h264/model/.svn/all-wcprops @@ -0,0 +1,59 @@ +K 25 +svn:wc:ra_dav:version-url +V 83 +/svn/!svn/ver/528/trunk/isoparser/src/main/java/com/googlecode/mp4parser/h264/model +END +HRDParameters.java +K 25 +svn:wc:ra_dav:version-url +V 102 +/svn/!svn/ver/381/trunk/isoparser/src/main/java/com/googlecode/mp4parser/h264/model/HRDParameters.java +END +ChromaFormat.java +K 25 +svn:wc:ra_dav:version-url +V 101 +/svn/!svn/ver/244/trunk/isoparser/src/main/java/com/googlecode/mp4parser/h264/model/ChromaFormat.java +END +BitstreamElement.java +K 25 +svn:wc:ra_dav:version-url +V 105 +/svn/!svn/ver/236/trunk/isoparser/src/main/java/com/googlecode/mp4parser/h264/model/BitstreamElement.java +END +SeqParameterSet.java +K 25 +svn:wc:ra_dav:version-url +V 104 +/svn/!svn/ver/377/trunk/isoparser/src/main/java/com/googlecode/mp4parser/h264/model/SeqParameterSet.java +END +ScalingMatrix.java +K 25 +svn:wc:ra_dav:version-url +V 102 +/svn/!svn/ver/244/trunk/isoparser/src/main/java/com/googlecode/mp4parser/h264/model/ScalingMatrix.java +END +VUIParameters.java +K 25 +svn:wc:ra_dav:version-url +V 102 +/svn/!svn/ver/244/trunk/isoparser/src/main/java/com/googlecode/mp4parser/h264/model/VUIParameters.java +END +PictureParameterSet.java +K 25 +svn:wc:ra_dav:version-url +V 108 +/svn/!svn/ver/528/trunk/isoparser/src/main/java/com/googlecode/mp4parser/h264/model/PictureParameterSet.java +END +ScalingList.java +K 25 +svn:wc:ra_dav:version-url +V 100 +/svn/!svn/ver/244/trunk/isoparser/src/main/java/com/googlecode/mp4parser/h264/model/ScalingList.java +END +AspectRatio.java +K 25 +svn:wc:ra_dav:version-url +V 100 +/svn/!svn/ver/236/trunk/isoparser/src/main/java/com/googlecode/mp4parser/h264/model/AspectRatio.java +END diff --git a/isoparser/src/main/java/com/googlecode/mp4parser/h264/model/.svn/entries b/isoparser/src/main/java/com/googlecode/mp4parser/h264/model/.svn/entries new file mode 100644 index 0000000..57346e5 --- /dev/null +++ b/isoparser/src/main/java/com/googlecode/mp4parser/h264/model/.svn/entries @@ -0,0 +1,334 @@ +10 + +dir +778 +http://mp4parser.googlecode.com/svn/trunk/isoparser/src/main/java/com/googlecode/mp4parser/h264/model +http://mp4parser.googlecode.com/svn + + + +2012-04-26T13:35:04.700844Z +528 +hoemmagnus@gmail.com + + + + + + + + + + + + + + +7decde4b-c250-0410-a0da-51896bc88be6 + +HRDParameters.java +file + + + + +2012-09-14T17:27:51.377231Z +b975fc17f18909ecfd3e15a29d8fb70e +2012-03-06T23:45:39.821994Z +381 +Sebastian.Annies@gmail.com + + + + + + + + + + + + + + + + + + + + + +2410 + +ChromaFormat.java +file + + + + +2012-09-14T17:27:51.377231Z +55075c51ac229ada06e17133f52fbc2b +2011-10-15T21:12:03.008630Z +244 +Sebastian.Annies@gmail.com + + + + + + + + + + + + + + + + + + + + + +2498 + +BitstreamElement.java +file + + + + +2012-09-14T17:27:51.377231Z +36a082110b2e0d7feab53e78bd5447e9 +2011-09-20T18:03:23.375910Z +236 +Sebastian.Annies@gmail.com + + + + + + + + + + + + + + + + + + + + + +1287 + +SeqParameterSet.java +file + + + + +2012-09-14T17:27:51.377231Z +f5f16b7f8e3609e73614f978009d472a +2012-03-05T23:28:24.666173Z +377 +Sebastian.Annies@gmail.com + + + + + + + + + + + + + + + + + + + + + +28600 + +ScalingMatrix.java +file + + + + +2012-09-14T17:27:51.377231Z +d7e4473348da54dc5434b84745704e62 +2011-10-15T21:12:03.008630Z +244 +Sebastian.Annies@gmail.com + + + + + + + + + + + + + + + + + + + + + +1582 + +VUIParameters.java +file + + + + +2012-09-14T17:27:51.377231Z +c39f83d225178ec9873004550130700b +2011-10-15T21:12:03.008630Z +244 +Sebastian.Annies@gmail.com + + + + + + + + + + + + + + + + + + + + + +4563 + +PictureParameterSet.java +file + + + + +2012-09-14T17:27:51.377231Z +bfe87344433e296b0c8b953ddad5e78f +2012-04-26T13:35:04.700844Z +528 +hoemmagnus@gmail.com + + + + + + + + + + + + + + + + + + + + + +19980 + +ScalingList.java +file + + + + +2012-09-14T17:27:51.377231Z +6f3a11866f0bcd61a9868f949a3c5c27 +2011-10-15T21:12:03.008630Z +244 +Sebastian.Annies@gmail.com + + + + + + + + + + + + + + + + + + + + + +2945 + +AspectRatio.java +file + + + + +2012-09-14T17:27:51.377231Z +4471abf932d16399567945fce05d656c +2011-09-20T18:03:23.375910Z +236 +Sebastian.Annies@gmail.com + + + + + + + + + + + + + + + + + + + + + +1640 + diff --git a/isoparser/src/main/java/com/googlecode/mp4parser/h264/model/.svn/text-base/AspectRatio.java.svn-base b/isoparser/src/main/java/com/googlecode/mp4parser/h264/model/.svn/text-base/AspectRatio.java.svn-base new file mode 100644 index 0000000..bc66b1a --- /dev/null +++ b/isoparser/src/main/java/com/googlecode/mp4parser/h264/model/.svn/text-base/AspectRatio.java.svn-base @@ -0,0 +1,50 @@ +/* +Copyright (c) 2011 Stanislav Vitvitskiy + +Permission is hereby granted, free of charge, to any person obtaining a copy of this +software and associated documentation files (the "Software"), to deal in the Software +without restriction, including without limitation the rights to use, copy, modify, +merge, publish, distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice shall be included in all copies or +substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, +INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR +PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE +FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE +OR OTHER DEALINGS IN THE SOFTWARE. +*/ +package com.googlecode.mp4parser.h264.model; + +/** + * Aspect ratio + * <p/> + * dynamic enum + * + * @author Stanislav Vitvitskiy + */ +public class AspectRatio { + + public static final AspectRatio Extended_SAR = new AspectRatio(255); + + private int value; + + private AspectRatio(int value) { + this.value = value; + } + + public static AspectRatio fromValue(int value) { + if (value == Extended_SAR.value) { + return Extended_SAR; + } + return new AspectRatio(value); + } + + public int getValue() { + return value; + } +} diff --git a/isoparser/src/main/java/com/googlecode/mp4parser/h264/model/.svn/text-base/BitstreamElement.java.svn-base b/isoparser/src/main/java/com/googlecode/mp4parser/h264/model/.svn/text-base/BitstreamElement.java.svn-base new file mode 100644 index 0000000..f16c5e9 --- /dev/null +++ b/isoparser/src/main/java/com/googlecode/mp4parser/h264/model/.svn/text-base/BitstreamElement.java.svn-base @@ -0,0 +1,29 @@ +/* +Copyright (c) 2011 Stanislav Vitvitskiy + +Permission is hereby granted, free of charge, to any person obtaining a copy of this +software and associated documentation files (the "Software"), to deal in the Software +without restriction, including without limitation the rights to use, copy, modify, +merge, publish, distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice shall be included in all copies or +substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, +INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR +PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE +FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE +OR OTHER DEALINGS IN THE SOFTWARE. +*/ +package com.googlecode.mp4parser.h264.model; + +import java.io.IOException; +import java.io.OutputStream; + +public abstract class BitstreamElement { + + public abstract void write(OutputStream out) throws IOException; +} diff --git a/isoparser/src/main/java/com/googlecode/mp4parser/h264/model/.svn/text-base/ChromaFormat.java.svn-base b/isoparser/src/main/java/com/googlecode/mp4parser/h264/model/.svn/text-base/ChromaFormat.java.svn-base new file mode 100644 index 0000000..2af2966 --- /dev/null +++ b/isoparser/src/main/java/com/googlecode/mp4parser/h264/model/.svn/text-base/ChromaFormat.java.svn-base @@ -0,0 +1,77 @@ +/* +Copyright (c) 2011 Stanislav Vitvitskiy + +Permission is hereby granted, free of charge, to any person obtaining a copy of this +software and associated documentation files (the "Software"), to deal in the Software +without restriction, including without limitation the rights to use, copy, modify, +merge, publish, distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice shall be included in all copies or +substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, +INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR +PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE +FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE +OR OTHER DEALINGS IN THE SOFTWARE. +*/ +package com.googlecode.mp4parser.h264.model; + +/** + * Chroma format enum + * + * @author Stanislav Vitvitskiy + */ +public class ChromaFormat { + public static ChromaFormat MONOCHROME = new ChromaFormat(0, 0, 0); + public static ChromaFormat YUV_420 = new ChromaFormat(1, 2, 2); + public static ChromaFormat YUV_422 = new ChromaFormat(2, 2, 1); + public static ChromaFormat YUV_444 = new ChromaFormat(3, 1, 1); + + private int id; + private int subWidth; + private int subHeight; + + public ChromaFormat(int id, int subWidth, int subHeight) { + this.id = id; + this.subWidth = subWidth; + this.subHeight = subHeight; + } + + public static ChromaFormat fromId(int id) { + if (id == MONOCHROME.id) { + return MONOCHROME; + } else if (id == YUV_420.id) { + return YUV_420; + } else if (id == YUV_422.id) { + return YUV_422; + } else if (id == YUV_444.id) { + return YUV_444; + } + return null; + } + + public int getId() { + return id; + } + + public int getSubWidth() { + return subWidth; + } + + public int getSubHeight() { + return subHeight; + } + + @Override + public String toString() { + return "ChromaFormat{" + "\n" + + "id=" + id + ",\n" + + " subWidth=" + subWidth + ",\n" + + " subHeight=" + subHeight + + '}'; + } +} diff --git a/isoparser/src/main/java/com/googlecode/mp4parser/h264/model/.svn/text-base/HRDParameters.java.svn-base b/isoparser/src/main/java/com/googlecode/mp4parser/h264/model/.svn/text-base/HRDParameters.java.svn-base new file mode 100644 index 0000000..f713ab2 --- /dev/null +++ b/isoparser/src/main/java/com/googlecode/mp4parser/h264/model/.svn/text-base/HRDParameters.java.svn-base @@ -0,0 +1,53 @@ +/* +Copyright (c) 2011 Stanislav Vitvitskiy + +Permission is hereby granted, free of charge, to any person obtaining a copy of this +software and associated documentation files (the "Software"), to deal in the Software +without restriction, including without limitation the rights to use, copy, modify, +merge, publish, distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice shall be included in all copies or +substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, +INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR +PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE +FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE +OR OTHER DEALINGS IN THE SOFTWARE. +*/ +package com.googlecode.mp4parser.h264.model; + +import java.util.Arrays; + +public class HRDParameters { + + public int cpb_cnt_minus1; + public int bit_rate_scale; + public int cpb_size_scale; + public int[] bit_rate_value_minus1; + public int[] cpb_size_value_minus1; + public boolean[] cbr_flag; + public int initial_cpb_removal_delay_length_minus1; + public int cpb_removal_delay_length_minus1; + public int dpb_output_delay_length_minus1; + public int time_offset_length; + + @Override + public String toString() { + return "HRDParameters{" + + "cpb_cnt_minus1=" + cpb_cnt_minus1 + + ", bit_rate_scale=" + bit_rate_scale + + ", cpb_size_scale=" + cpb_size_scale + + ", bit_rate_value_minus1=" + Arrays.toString(bit_rate_value_minus1) + + ", cpb_size_value_minus1=" + Arrays.toString(cpb_size_value_minus1) + + ", cbr_flag=" + Arrays.toString(cbr_flag) + + ", initial_cpb_removal_delay_length_minus1=" + initial_cpb_removal_delay_length_minus1 + + ", cpb_removal_delay_length_minus1=" + cpb_removal_delay_length_minus1 + + ", dpb_output_delay_length_minus1=" + dpb_output_delay_length_minus1 + + ", time_offset_length=" + time_offset_length + + '}'; + } +} diff --git a/isoparser/src/main/java/com/googlecode/mp4parser/h264/model/.svn/text-base/PictureParameterSet.java.svn-base b/isoparser/src/main/java/com/googlecode/mp4parser/h264/model/.svn/text-base/PictureParameterSet.java.svn-base new file mode 100644 index 0000000..9154c38 --- /dev/null +++ b/isoparser/src/main/java/com/googlecode/mp4parser/h264/model/.svn/text-base/PictureParameterSet.java.svn-base @@ -0,0 +1,406 @@ +/* +Copyright (c) 2011 Stanislav Vitvitskiy + +Permission is hereby granted, free of charge, to any person obtaining a copy of this +software and associated documentation files (the "Software"), to deal in the Software +without restriction, including without limitation the rights to use, copy, modify, +merge, publish, distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice shall be included in all copies or +substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, +INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR +PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE +FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE +OR OTHER DEALINGS IN THE SOFTWARE. +*/ +package com.googlecode.mp4parser.h264.model; + +import com.googlecode.mp4parser.h264.read.CAVLCReader; +import com.googlecode.mp4parser.h264.write.CAVLCWriter; + +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.util.Arrays; + +/** + * Picture Parameter Set entity of H264 bitstream + * <p/> + * capable to serialize / deserialize with CAVLC bitstream + * + * @author Stanislav Vitvitskiy + */ +public class PictureParameterSet extends BitstreamElement { + + public static class PPSExt { + public boolean transform_8x8_mode_flag; + public ScalingMatrix scalindMatrix = new ScalingMatrix(); + public int second_chroma_qp_index_offset; + public boolean[] pic_scaling_list_present_flag; + + @Override + public String toString() { + return "PPSExt{" + + "transform_8x8_mode_flag=" + transform_8x8_mode_flag + + ", scalindMatrix=" + scalindMatrix + + ", second_chroma_qp_index_offset=" + second_chroma_qp_index_offset + + ", pic_scaling_list_present_flag=" + pic_scaling_list_present_flag + + '}'; + } + } + + public boolean entropy_coding_mode_flag; + public int num_ref_idx_l0_active_minus1; + public int num_ref_idx_l1_active_minus1; + public int slice_group_change_rate_minus1; + public int pic_parameter_set_id; + public int seq_parameter_set_id; + public boolean pic_order_present_flag; + public int num_slice_groups_minus1; + public int slice_group_map_type; + public boolean weighted_pred_flag; + public int weighted_bipred_idc; + public int pic_init_qp_minus26; + public int pic_init_qs_minus26; + public int chroma_qp_index_offset; + public boolean deblocking_filter_control_present_flag; + public boolean constrained_intra_pred_flag; + public boolean redundant_pic_cnt_present_flag; + public int[] top_left; + public int[] bottom_right; + public int[] run_length_minus1; + public boolean slice_group_change_direction_flag; + public int[] slice_group_id; + public PPSExt extended; + + public static PictureParameterSet read(byte[] b) throws IOException { + return read(new ByteArrayInputStream(b)); + } + + public static PictureParameterSet read(InputStream is) throws IOException { + CAVLCReader reader = new CAVLCReader(is); + PictureParameterSet pps = new PictureParameterSet(); + + pps.pic_parameter_set_id = reader.readUE("PPS: pic_parameter_set_id"); + pps.seq_parameter_set_id = reader.readUE("PPS: seq_parameter_set_id"); + pps.entropy_coding_mode_flag = reader + .readBool("PPS: entropy_coding_mode_flag"); + pps.pic_order_present_flag = reader + .readBool("PPS: pic_order_present_flag"); + pps.num_slice_groups_minus1 = reader + .readUE("PPS: num_slice_groups_minus1"); + if (pps.num_slice_groups_minus1 > 0) { + pps.slice_group_map_type = reader + .readUE("PPS: slice_group_map_type"); + pps.top_left = new int[pps.num_slice_groups_minus1 + 1]; + pps.bottom_right = new int[pps.num_slice_groups_minus1 + 1]; + pps.run_length_minus1 = new int[pps.num_slice_groups_minus1 + 1]; + if (pps.slice_group_map_type == 0) + for (int iGroup = 0; iGroup <= pps.num_slice_groups_minus1; iGroup++) + pps.run_length_minus1[iGroup] = reader + .readUE("PPS: run_length_minus1"); + else if (pps.slice_group_map_type == 2) + for (int iGroup = 0; iGroup < pps.num_slice_groups_minus1; iGroup++) { + pps.top_left[iGroup] = reader.readUE("PPS: top_left"); + pps.bottom_right[iGroup] = reader + .readUE("PPS: bottom_right"); + } + else if (pps.slice_group_map_type == 3 + || pps.slice_group_map_type == 4 + || pps.slice_group_map_type == 5) { + pps.slice_group_change_direction_flag = reader + .readBool("PPS: slice_group_change_direction_flag"); + pps.slice_group_change_rate_minus1 = reader + .readUE("PPS: slice_group_change_rate_minus1"); + } else if (pps.slice_group_map_type == 6) { + int NumberBitsPerSliceGroupId; + if (pps.num_slice_groups_minus1 + 1 > 4) + NumberBitsPerSliceGroupId = 3; + else if (pps.num_slice_groups_minus1 + 1 > 2) + NumberBitsPerSliceGroupId = 2; + else + NumberBitsPerSliceGroupId = 1; + int pic_size_in_map_units_minus1 = reader + .readUE("PPS: pic_size_in_map_units_minus1"); + pps.slice_group_id = new int[pic_size_in_map_units_minus1 + 1]; + for (int i = 0; i <= pic_size_in_map_units_minus1; i++) { + pps.slice_group_id[i] = reader.readU( + NumberBitsPerSliceGroupId, "PPS: slice_group_id [" + + i + "]f"); + } + } + } + pps.num_ref_idx_l0_active_minus1 = reader + .readUE("PPS: num_ref_idx_l0_active_minus1"); + pps.num_ref_idx_l1_active_minus1 = reader + .readUE("PPS: num_ref_idx_l1_active_minus1"); + pps.weighted_pred_flag = reader.readBool("PPS: weighted_pred_flag"); + pps.weighted_bipred_idc = (int) reader.readNBit(2, + "PPS: weighted_bipred_idc"); + pps.pic_init_qp_minus26 = reader.readSE("PPS: pic_init_qp_minus26"); + pps.pic_init_qs_minus26 = reader.readSE("PPS: pic_init_qs_minus26"); + pps.chroma_qp_index_offset = reader + .readSE("PPS: chroma_qp_index_offset"); + pps.deblocking_filter_control_present_flag = reader + .readBool("PPS: deblocking_filter_control_present_flag"); + pps.constrained_intra_pred_flag = reader + .readBool("PPS: constrained_intra_pred_flag"); + pps.redundant_pic_cnt_present_flag = reader + .readBool("PPS: redundant_pic_cnt_present_flag"); + if (reader.moreRBSPData()) { + pps.extended = new PictureParameterSet.PPSExt(); + pps.extended.transform_8x8_mode_flag = reader + .readBool("PPS: transform_8x8_mode_flag"); + boolean pic_scaling_matrix_present_flag = reader + .readBool("PPS: pic_scaling_matrix_present_flag"); + if (pic_scaling_matrix_present_flag) { + for (int i = 0; i < 6 + 2 * (pps.extended.transform_8x8_mode_flag ? 1 + : 0); i++) { + boolean pic_scaling_list_present_flag = reader + .readBool("PPS: pic_scaling_list_present_flag"); + if (pic_scaling_list_present_flag) { + pps.extended.scalindMatrix.ScalingList4x4 = new ScalingList[8]; + pps.extended.scalindMatrix.ScalingList8x8 = new ScalingList[8]; + if (i < 6) { + pps.extended.scalindMatrix.ScalingList4x4[i] = ScalingList + .read(reader, 16); + } else { + pps.extended.scalindMatrix.ScalingList8x8[i - 6] = ScalingList + .read(reader, 64); + } + } + } + } + pps.extended.second_chroma_qp_index_offset = reader + .readSE("PPS: second_chroma_qp_index_offset"); + } + + reader.readTrailingBits(); + + return pps; + } + + public void write(OutputStream out) throws IOException { + CAVLCWriter writer = new CAVLCWriter(out); + + writer.writeUE(pic_parameter_set_id, "PPS: pic_parameter_set_id"); + writer.writeUE(seq_parameter_set_id, "PPS: seq_parameter_set_id"); + writer.writeBool(entropy_coding_mode_flag, + "PPS: entropy_coding_mode_flag"); + writer.writeBool(pic_order_present_flag, "PPS: pic_order_present_flag"); + writer.writeUE(num_slice_groups_minus1, "PPS: num_slice_groups_minus1"); + if (num_slice_groups_minus1 > 0) { + writer.writeUE(slice_group_map_type, "PPS: slice_group_map_type"); + int[] top_left = new int[1]; + int[] bottom_right = new int[1]; + int[] run_length_minus1 = new int[1]; + if (slice_group_map_type == 0) { + for (int iGroup = 0; iGroup <= num_slice_groups_minus1; iGroup++) { + writer.writeUE(run_length_minus1[iGroup], "PPS: "); + } + } else if (slice_group_map_type == 2) { + for (int iGroup = 0; iGroup < num_slice_groups_minus1; iGroup++) { + writer.writeUE(top_left[iGroup], "PPS: "); + writer.writeUE(bottom_right[iGroup], "PPS: "); + } + } else if (slice_group_map_type == 3 || slice_group_map_type == 4 + || slice_group_map_type == 5) { + writer.writeBool(slice_group_change_direction_flag, + "PPS: slice_group_change_direction_flag"); + writer.writeUE(slice_group_change_rate_minus1, + "PPS: slice_group_change_rate_minus1"); + } else if (slice_group_map_type == 6) { + int NumberBitsPerSliceGroupId; + if (num_slice_groups_minus1 + 1 > 4) + NumberBitsPerSliceGroupId = 3; + else if (num_slice_groups_minus1 + 1 > 2) + NumberBitsPerSliceGroupId = 2; + else + NumberBitsPerSliceGroupId = 1; + writer.writeUE(slice_group_id.length, "PPS: "); + for (int i = 0; i <= slice_group_id.length; i++) { + writer.writeU(slice_group_id[i], NumberBitsPerSliceGroupId); + } + } + } + writer.writeUE(num_ref_idx_l0_active_minus1, + "PPS: num_ref_idx_l0_active_minus1"); + writer.writeUE(num_ref_idx_l1_active_minus1, + "PPS: num_ref_idx_l1_active_minus1"); + writer.writeBool(weighted_pred_flag, "PPS: weighted_pred_flag"); + writer.writeNBit(weighted_bipred_idc, 2, "PPS: weighted_bipred_idc"); + writer.writeSE(pic_init_qp_minus26, "PPS: pic_init_qp_minus26"); + writer.writeSE(pic_init_qs_minus26, "PPS: pic_init_qs_minus26"); + writer.writeSE(chroma_qp_index_offset, "PPS: chroma_qp_index_offset"); + writer.writeBool(deblocking_filter_control_present_flag, + "PPS: deblocking_filter_control_present_flag"); + writer.writeBool(constrained_intra_pred_flag, + "PPS: constrained_intra_pred_flag"); + writer.writeBool(redundant_pic_cnt_present_flag, + "PPS: redundant_pic_cnt_present_flag"); + if (extended != null) { + writer.writeBool(extended.transform_8x8_mode_flag, + "PPS: transform_8x8_mode_flag"); + writer.writeBool(extended.scalindMatrix != null, + "PPS: scalindMatrix"); + if (extended.scalindMatrix != null) { + for (int i = 0; i < 6 + 2 * (extended.transform_8x8_mode_flag ? 1 + : 0); i++) { + if (i < 6) { + writer + .writeBool( + extended.scalindMatrix.ScalingList4x4[i] != null, + "PPS: "); + if (extended.scalindMatrix.ScalingList4x4[i] != null) { + extended.scalindMatrix.ScalingList4x4[i] + .write(writer); + } + + } else { + writer + .writeBool( + extended.scalindMatrix.ScalingList8x8[i - 6] != null, + "PPS: "); + if (extended.scalindMatrix.ScalingList8x8[i - 6] != null) { + extended.scalindMatrix.ScalingList8x8[i - 6] + .write(writer); + } + } + } + } + writer.writeSE(extended.second_chroma_qp_index_offset, "PPS: "); + } + + writer.writeTrailingBits(); + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + Arrays.hashCode(bottom_right); + result = prime * result + chroma_qp_index_offset; + result = prime * result + (constrained_intra_pred_flag ? 1231 : 1237); + result = prime * result + + (deblocking_filter_control_present_flag ? 1231 : 1237); + result = prime * result + (entropy_coding_mode_flag ? 1231 : 1237); + result = prime * result + + ((extended == null) ? 0 : extended.hashCode()); + result = prime * result + num_ref_idx_l0_active_minus1; + result = prime * result + num_ref_idx_l1_active_minus1; + result = prime * result + num_slice_groups_minus1; + result = prime * result + pic_init_qp_minus26; + result = prime * result + pic_init_qs_minus26; + result = prime * result + (pic_order_present_flag ? 1231 : 1237); + result = prime * result + pic_parameter_set_id; + result = prime * result + + (redundant_pic_cnt_present_flag ? 1231 : 1237); + result = prime * result + Arrays.hashCode(run_length_minus1); + result = prime * result + seq_parameter_set_id; + result = prime * result + + (slice_group_change_direction_flag ? 1231 : 1237); + result = prime * result + slice_group_change_rate_minus1; + result = prime * result + Arrays.hashCode(slice_group_id); + result = prime * result + slice_group_map_type; + result = prime * result + Arrays.hashCode(top_left); + result = prime * result + weighted_bipred_idc; + result = prime * result + (weighted_pred_flag ? 1231 : 1237); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + PictureParameterSet other = (PictureParameterSet) obj; + if (!Arrays.equals(bottom_right, other.bottom_right)) + return false; + if (chroma_qp_index_offset != other.chroma_qp_index_offset) + return false; + if (constrained_intra_pred_flag != other.constrained_intra_pred_flag) + return false; + if (deblocking_filter_control_present_flag != other.deblocking_filter_control_present_flag) + return false; + if (entropy_coding_mode_flag != other.entropy_coding_mode_flag) + return false; + if (extended == null) { + if (other.extended != null) + return false; + } else if (!extended.equals(other.extended)) + return false; + if (num_ref_idx_l0_active_minus1 != other.num_ref_idx_l0_active_minus1) + return false; + if (num_ref_idx_l1_active_minus1 != other.num_ref_idx_l1_active_minus1) + return false; + if (num_slice_groups_minus1 != other.num_slice_groups_minus1) + return false; + if (pic_init_qp_minus26 != other.pic_init_qp_minus26) + return false; + if (pic_init_qs_minus26 != other.pic_init_qs_minus26) + return false; + if (pic_order_present_flag != other.pic_order_present_flag) + return false; + if (pic_parameter_set_id != other.pic_parameter_set_id) + return false; + if (redundant_pic_cnt_present_flag != other.redundant_pic_cnt_present_flag) + return false; + if (!Arrays.equals(run_length_minus1, other.run_length_minus1)) + return false; + if (seq_parameter_set_id != other.seq_parameter_set_id) + return false; + if (slice_group_change_direction_flag != other.slice_group_change_direction_flag) + return false; + if (slice_group_change_rate_minus1 != other.slice_group_change_rate_minus1) + return false; + if (!Arrays.equals(slice_group_id, other.slice_group_id)) + return false; + if (slice_group_map_type != other.slice_group_map_type) + return false; + if (!Arrays.equals(top_left, other.top_left)) + return false; + if (weighted_bipred_idc != other.weighted_bipred_idc) + return false; + if (weighted_pred_flag != other.weighted_pred_flag) + return false; + return true; + } + + @Override + public String toString() { + return "PictureParameterSet{" + + "\n entropy_coding_mode_flag=" + entropy_coding_mode_flag + + ",\n num_ref_idx_l0_active_minus1=" + num_ref_idx_l0_active_minus1 + + ",\n num_ref_idx_l1_active_minus1=" + num_ref_idx_l1_active_minus1 + + ",\n slice_group_change_rate_minus1=" + slice_group_change_rate_minus1 + + ",\n pic_parameter_set_id=" + pic_parameter_set_id + + ",\n seq_parameter_set_id=" + seq_parameter_set_id + + ",\n pic_order_present_flag=" + pic_order_present_flag + + ",\n num_slice_groups_minus1=" + num_slice_groups_minus1 + + ",\n slice_group_map_type=" + slice_group_map_type + + ",\n weighted_pred_flag=" + weighted_pred_flag + + ",\n weighted_bipred_idc=" + weighted_bipred_idc + + ",\n pic_init_qp_minus26=" + pic_init_qp_minus26 + + ",\n pic_init_qs_minus26=" + pic_init_qs_minus26 + + ",\n chroma_qp_index_offset=" + chroma_qp_index_offset + + ",\n deblocking_filter_control_present_flag=" + deblocking_filter_control_present_flag + + ",\n constrained_intra_pred_flag=" + constrained_intra_pred_flag + + ",\n redundant_pic_cnt_present_flag=" + redundant_pic_cnt_present_flag + + ",\n top_left=" + top_left + + ",\n bottom_right=" + bottom_right + + ",\n run_length_minus1=" + run_length_minus1 + + ",\n slice_group_change_direction_flag=" + slice_group_change_direction_flag + + ",\n slice_group_id=" + slice_group_id + + ",\n extended=" + extended + + '}'; + } +} diff --git a/isoparser/src/main/java/com/googlecode/mp4parser/h264/model/.svn/text-base/ScalingList.java.svn-base b/isoparser/src/main/java/com/googlecode/mp4parser/h264/model/.svn/text-base/ScalingList.java.svn-base new file mode 100644 index 0000000..5d272bf --- /dev/null +++ b/isoparser/src/main/java/com/googlecode/mp4parser/h264/model/.svn/text-base/ScalingList.java.svn-base @@ -0,0 +1,83 @@ +/* +Copyright (c) 2011 Stanislav Vitvitskiy + +Permission is hereby granted, free of charge, to any person obtaining a copy of this +software and associated documentation files (the "Software"), to deal in the Software +without restriction, including without limitation the rights to use, copy, modify, +merge, publish, distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice shall be included in all copies or +substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, +INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR +PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE +FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE +OR OTHER DEALINGS IN THE SOFTWARE. +*/ +package com.googlecode.mp4parser.h264.model; + +import com.googlecode.mp4parser.h264.read.CAVLCReader; +import com.googlecode.mp4parser.h264.write.CAVLCWriter; + +import java.io.IOException; + +/** + * Scaling list entity + * <p/> + * capable to serialize / deserialize with CAVLC bitstream + * + * @author Stanislav Vitvitskiy + */ +public class ScalingList { + + public int[] scalingList; + public boolean useDefaultScalingMatrixFlag; + + public void write(CAVLCWriter out) throws IOException { + if (useDefaultScalingMatrixFlag) { + out.writeSE(0, "SPS: "); + return; + } + + int lastScale = 8; + int nextScale = 8; + for (int j = 0; j < scalingList.length; j++) { + if (nextScale != 0) { + int deltaScale = scalingList[j] - lastScale - 256; + out.writeSE(deltaScale, "SPS: "); + } + lastScale = scalingList[j]; + } + } + + public static ScalingList read(CAVLCReader is, int sizeOfScalingList) + throws IOException { + + ScalingList sl = new ScalingList(); + sl.scalingList = new int[sizeOfScalingList]; + int lastScale = 8; + int nextScale = 8; + for (int j = 0; j < sizeOfScalingList; j++) { + if (nextScale != 0) { + int deltaScale = is.readSE("deltaScale"); + nextScale = (lastScale + deltaScale + 256) % 256; + sl.useDefaultScalingMatrixFlag = (j == 0 && nextScale == 0); + } + sl.scalingList[j] = nextScale == 0 ? lastScale : nextScale; + lastScale = sl.scalingList[j]; + } + return sl; + } + + @Override + public String toString() { + return "ScalingList{" + + "scalingList=" + scalingList + + ", useDefaultScalingMatrixFlag=" + useDefaultScalingMatrixFlag + + '}'; + } +}
\ No newline at end of file diff --git a/isoparser/src/main/java/com/googlecode/mp4parser/h264/model/.svn/text-base/ScalingMatrix.java.svn-base b/isoparser/src/main/java/com/googlecode/mp4parser/h264/model/.svn/text-base/ScalingMatrix.java.svn-base new file mode 100644 index 0000000..d04af8e --- /dev/null +++ b/isoparser/src/main/java/com/googlecode/mp4parser/h264/model/.svn/text-base/ScalingMatrix.java.svn-base @@ -0,0 +1,37 @@ +/* +Copyright (c) 2011 Stanislav Vitvitskiy + +Permission is hereby granted, free of charge, to any person obtaining a copy of this +software and associated documentation files (the "Software"), to deal in the Software +without restriction, including without limitation the rights to use, copy, modify, +merge, publish, distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice shall be included in all copies or +substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, +INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR +PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE +FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE +OR OTHER DEALINGS IN THE SOFTWARE. +*/ +package com.googlecode.mp4parser.h264.model; + +import java.util.Arrays; + +public class ScalingMatrix { + + public ScalingList[] ScalingList4x4; + public ScalingList[] ScalingList8x8; + + @Override + public String toString() { + return "ScalingMatrix{" + + "ScalingList4x4=" + (ScalingList4x4 == null ? null : Arrays.asList(ScalingList4x4)) + "\n" + + ", ScalingList8x8=" + (ScalingList8x8 == null ? null : Arrays.asList(ScalingList8x8)) + "\n" + + '}'; + } +}
\ No newline at end of file diff --git a/isoparser/src/main/java/com/googlecode/mp4parser/h264/model/.svn/text-base/SeqParameterSet.java.svn-base b/isoparser/src/main/java/com/googlecode/mp4parser/h264/model/.svn/text-base/SeqParameterSet.java.svn-base new file mode 100644 index 0000000..4894df8 --- /dev/null +++ b/isoparser/src/main/java/com/googlecode/mp4parser/h264/model/.svn/text-base/SeqParameterSet.java.svn-base @@ -0,0 +1,556 @@ +/* +Copyright (c) 2011 Stanislav Vitvitskiy + +Permission is hereby granted, free of charge, to any person obtaining a copy of this +software and associated documentation files (the "Software"), to deal in the Software +without restriction, including without limitation the rights to use, copy, modify, +merge, publish, distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice shall be included in all copies or +substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, +INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR +PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE +FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE +OR OTHER DEALINGS IN THE SOFTWARE. +*/ +package com.googlecode.mp4parser.h264.model; + +import com.googlecode.mp4parser.h264.read.CAVLCReader; +import com.googlecode.mp4parser.h264.write.CAVLCWriter; + +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; + +/** + * Sequence Parameter Set structure of h264 bitstream + * <p/> + * capable to serialize and deserialize with CAVLC bitstream + * + * @author Stanislav Vitvitskiy + */ +public class SeqParameterSet extends BitstreamElement { + public int pic_order_cnt_type; + public boolean field_pic_flag; + public boolean delta_pic_order_always_zero_flag; + public boolean weighted_pred_flag; + public int weighted_bipred_idc; + public boolean entropy_coding_mode_flag; + public boolean mb_adaptive_frame_field_flag; + public boolean direct_8x8_inference_flag; + public ChromaFormat chroma_format_idc; + public int log2_max_frame_num_minus4; + public int log2_max_pic_order_cnt_lsb_minus4; + public int pic_height_in_map_units_minus1; + public int pic_width_in_mbs_minus1; + public int bit_depth_luma_minus8; + public int bit_depth_chroma_minus8; + public boolean qpprime_y_zero_transform_bypass_flag; + public int profile_idc; + public boolean constraint_set_0_flag; + public boolean constraint_set_1_flag; + public boolean constraint_set_2_flag; + public boolean constraint_set_3_flag; + public int level_idc; + public int seq_parameter_set_id; + public boolean residual_color_transform_flag; + public int offset_for_non_ref_pic; + public int offset_for_top_to_bottom_field; + public int num_ref_frames; + public boolean gaps_in_frame_num_value_allowed_flag; + public boolean frame_mbs_only_flag; + public boolean frame_cropping_flag; + public int frame_crop_left_offset; + public int frame_crop_right_offset; + public int frame_crop_top_offset; + public int frame_crop_bottom_offset; + public int[] offsetForRefFrame; + public VUIParameters vuiParams; + public ScalingMatrix scalingMatrix; + public int num_ref_frames_in_pic_order_cnt_cycle; + + public static SeqParameterSet read(InputStream is) throws IOException { + CAVLCReader reader = new CAVLCReader(is); + SeqParameterSet sps = new SeqParameterSet(); + + sps.profile_idc = (int) reader.readNBit(8, "SPS: profile_idc"); + sps.constraint_set_0_flag = reader + .readBool("SPS: constraint_set_0_flag"); + sps.constraint_set_1_flag = reader + .readBool("SPS: constraint_set_1_flag"); + sps.constraint_set_2_flag = reader + .readBool("SPS: constraint_set_2_flag"); + sps.constraint_set_3_flag = reader + .readBool("SPS: constraint_set_3_flag"); + reader.readNBit(4, "SPS: reserved_zero_4bits"); + sps.level_idc = (int) reader.readNBit(8, "SPS: level_idc"); + sps.seq_parameter_set_id = reader.readUE("SPS: seq_parameter_set_id"); + + if (sps.profile_idc == 100 || sps.profile_idc == 110 + || sps.profile_idc == 122 || sps.profile_idc == 144) { + sps.chroma_format_idc = ChromaFormat.fromId(reader + .readUE("SPS: chroma_format_idc")); + if (sps.chroma_format_idc == ChromaFormat.YUV_444) { + sps.residual_color_transform_flag = reader + .readBool("SPS: residual_color_transform_flag"); + } + sps.bit_depth_luma_minus8 = reader + .readUE("SPS: bit_depth_luma_minus8"); + sps.bit_depth_chroma_minus8 = reader + .readUE("SPS: bit_depth_chroma_minus8"); + sps.qpprime_y_zero_transform_bypass_flag = reader + .readBool("SPS: qpprime_y_zero_transform_bypass_flag"); + boolean seqScalingMatrixPresent = reader + .readBool("SPS: seq_scaling_matrix_present_lag"); + if (seqScalingMatrixPresent) { + readScalingListMatrix(reader, sps); + } + } else { + sps.chroma_format_idc = ChromaFormat.YUV_420; + } + sps.log2_max_frame_num_minus4 = reader + .readUE("SPS: log2_max_frame_num_minus4"); + sps.pic_order_cnt_type = reader.readUE("SPS: pic_order_cnt_type"); + if (sps.pic_order_cnt_type == 0) { + sps.log2_max_pic_order_cnt_lsb_minus4 = reader + .readUE("SPS: log2_max_pic_order_cnt_lsb_minus4"); + } else if (sps.pic_order_cnt_type == 1) { + sps.delta_pic_order_always_zero_flag = reader + .readBool("SPS: delta_pic_order_always_zero_flag"); + sps.offset_for_non_ref_pic = reader + .readSE("SPS: offset_for_non_ref_pic"); + sps.offset_for_top_to_bottom_field = reader + .readSE("SPS: offset_for_top_to_bottom_field"); + sps.num_ref_frames_in_pic_order_cnt_cycle = reader + .readUE("SPS: num_ref_frames_in_pic_order_cnt_cycle"); + sps.offsetForRefFrame = new int[sps.num_ref_frames_in_pic_order_cnt_cycle]; + for (int i = 0; i < sps.num_ref_frames_in_pic_order_cnt_cycle; i++) { + sps.offsetForRefFrame[i] = reader + .readSE("SPS: offsetForRefFrame [" + i + "]"); + } + } + sps.num_ref_frames = reader.readUE("SPS: num_ref_frames"); + sps.gaps_in_frame_num_value_allowed_flag = reader + .readBool("SPS: gaps_in_frame_num_value_allowed_flag"); + sps.pic_width_in_mbs_minus1 = reader + .readUE("SPS: pic_width_in_mbs_minus1"); + sps.pic_height_in_map_units_minus1 = reader + .readUE("SPS: pic_height_in_map_units_minus1"); + sps.frame_mbs_only_flag = reader.readBool("SPS: frame_mbs_only_flag"); + if (!sps.frame_mbs_only_flag) { + sps.mb_adaptive_frame_field_flag = reader + .readBool("SPS: mb_adaptive_frame_field_flag"); + } + sps.direct_8x8_inference_flag = reader + .readBool("SPS: direct_8x8_inference_flag"); + sps.frame_cropping_flag = reader.readBool("SPS: frame_cropping_flag"); + if (sps.frame_cropping_flag) { + sps.frame_crop_left_offset = reader + .readUE("SPS: frame_crop_left_offset"); + sps.frame_crop_right_offset = reader + .readUE("SPS: frame_crop_right_offset"); + sps.frame_crop_top_offset = reader + .readUE("SPS: frame_crop_top_offset"); + sps.frame_crop_bottom_offset = reader + .readUE("SPS: frame_crop_bottom_offset"); + } + boolean vui_parameters_present_flag = reader + .readBool("SPS: vui_parameters_present_flag"); + if (vui_parameters_present_flag) + sps.vuiParams = ReadVUIParameters(reader); + + reader.readTrailingBits(); + + return sps; + } + + private static void readScalingListMatrix(CAVLCReader reader, + SeqParameterSet sps) throws IOException { + sps.scalingMatrix = new ScalingMatrix(); + for (int i = 0; i < 8; i++) { + boolean seqScalingListPresentFlag = reader + .readBool("SPS: seqScalingListPresentFlag"); + if (seqScalingListPresentFlag) { + sps.scalingMatrix.ScalingList4x4 = new ScalingList[8]; + sps.scalingMatrix.ScalingList8x8 = new ScalingList[8]; + if (i < 6) { + sps.scalingMatrix.ScalingList4x4[i] = ScalingList.read( + reader, 16); + } else { + sps.scalingMatrix.ScalingList8x8[i - 6] = ScalingList.read( + reader, 64); + } + } + } + } + + private static VUIParameters ReadVUIParameters(CAVLCReader reader) + throws IOException { + VUIParameters vuip = new VUIParameters(); + vuip.aspect_ratio_info_present_flag = reader + .readBool("VUI: aspect_ratio_info_present_flag"); + if (vuip.aspect_ratio_info_present_flag) { + vuip.aspect_ratio = AspectRatio.fromValue((int) reader.readNBit(8, + "VUI: aspect_ratio")); + if (vuip.aspect_ratio == AspectRatio.Extended_SAR) { + vuip.sar_width = (int) reader.readNBit(16, "VUI: sar_width"); + vuip.sar_height = (int) reader.readNBit(16, "VUI: sar_height"); + } + } + vuip.overscan_info_present_flag = reader + .readBool("VUI: overscan_info_present_flag"); + if (vuip.overscan_info_present_flag) { + vuip.overscan_appropriate_flag = reader + .readBool("VUI: overscan_appropriate_flag"); + } + vuip.video_signal_type_present_flag = reader + .readBool("VUI: video_signal_type_present_flag"); + if (vuip.video_signal_type_present_flag) { + vuip.video_format = (int) reader.readNBit(3, "VUI: video_format"); + vuip.video_full_range_flag = reader + .readBool("VUI: video_full_range_flag"); + vuip.colour_description_present_flag = reader + .readBool("VUI: colour_description_present_flag"); + if (vuip.colour_description_present_flag) { + vuip.colour_primaries = (int) reader.readNBit(8, + "VUI: colour_primaries"); + vuip.transfer_characteristics = (int) reader.readNBit(8, + "VUI: transfer_characteristics"); + vuip.matrix_coefficients = (int) reader.readNBit(8, + "VUI: matrix_coefficients"); + } + } + vuip.chroma_loc_info_present_flag = reader + .readBool("VUI: chroma_loc_info_present_flag"); + if (vuip.chroma_loc_info_present_flag) { + vuip.chroma_sample_loc_type_top_field = reader + .readUE("VUI chroma_sample_loc_type_top_field"); + vuip.chroma_sample_loc_type_bottom_field = reader + .readUE("VUI chroma_sample_loc_type_bottom_field"); + } + vuip.timing_info_present_flag = reader + .readBool("VUI: timing_info_present_flag"); + if (vuip.timing_info_present_flag) { + vuip.num_units_in_tick = (int) reader.readNBit(32, + "VUI: num_units_in_tick"); + vuip.time_scale = (int) reader.readNBit(32, "VUI: time_scale"); + vuip.fixed_frame_rate_flag = reader + .readBool("VUI: fixed_frame_rate_flag"); + } + boolean nal_hrd_parameters_present_flag = reader + .readBool("VUI: nal_hrd_parameters_present_flag"); + if (nal_hrd_parameters_present_flag) + vuip.nalHRDParams = readHRDParameters(reader); + boolean vcl_hrd_parameters_present_flag = reader + .readBool("VUI: vcl_hrd_parameters_present_flag"); + if (vcl_hrd_parameters_present_flag) + vuip.vclHRDParams = readHRDParameters(reader); + if (nal_hrd_parameters_present_flag || vcl_hrd_parameters_present_flag) { + vuip.low_delay_hrd_flag = reader + .readBool("VUI: low_delay_hrd_flag"); + } + vuip.pic_struct_present_flag = reader + .readBool("VUI: pic_struct_present_flag"); + boolean bitstream_restriction_flag = reader + .readBool("VUI: bitstream_restriction_flag"); + if (bitstream_restriction_flag) { + vuip.bitstreamRestriction = new VUIParameters.BitstreamRestriction(); + vuip.bitstreamRestriction.motion_vectors_over_pic_boundaries_flag = reader + .readBool("VUI: motion_vectors_over_pic_boundaries_flag"); + vuip.bitstreamRestriction.max_bytes_per_pic_denom = reader + .readUE("VUI max_bytes_per_pic_denom"); + vuip.bitstreamRestriction.max_bits_per_mb_denom = reader + .readUE("VUI max_bits_per_mb_denom"); + vuip.bitstreamRestriction.log2_max_mv_length_horizontal = reader + .readUE("VUI log2_max_mv_length_horizontal"); + vuip.bitstreamRestriction.log2_max_mv_length_vertical = reader + .readUE("VUI log2_max_mv_length_vertical"); + vuip.bitstreamRestriction.num_reorder_frames = reader + .readUE("VUI num_reorder_frames"); + vuip.bitstreamRestriction.max_dec_frame_buffering = reader + .readUE("VUI max_dec_frame_buffering"); + } + + return vuip; + } + + private static HRDParameters readHRDParameters(CAVLCReader reader) + throws IOException { + HRDParameters hrd = new HRDParameters(); + hrd.cpb_cnt_minus1 = reader.readUE("SPS: cpb_cnt_minus1"); + hrd.bit_rate_scale = (int) reader.readNBit(4, "HRD: bit_rate_scale"); + hrd.cpb_size_scale = (int) reader.readNBit(4, "HRD: cpb_size_scale"); + hrd.bit_rate_value_minus1 = new int[hrd.cpb_cnt_minus1 + 1]; + hrd.cpb_size_value_minus1 = new int[hrd.cpb_cnt_minus1 + 1]; + hrd.cbr_flag = new boolean[hrd.cpb_cnt_minus1 + 1]; + + for (int SchedSelIdx = 0; SchedSelIdx <= hrd.cpb_cnt_minus1; SchedSelIdx++) { + hrd.bit_rate_value_minus1[SchedSelIdx] = reader + .readUE("HRD: bit_rate_value_minus1"); + hrd.cpb_size_value_minus1[SchedSelIdx] = reader + .readUE("HRD: cpb_size_value_minus1"); + hrd.cbr_flag[SchedSelIdx] = reader.readBool("HRD: cbr_flag"); + } + hrd.initial_cpb_removal_delay_length_minus1 = (int) reader.readNBit(5, + "HRD: initial_cpb_removal_delay_length_minus1"); + hrd.cpb_removal_delay_length_minus1 = (int) reader.readNBit(5, + "HRD: cpb_removal_delay_length_minus1"); + hrd.dpb_output_delay_length_minus1 = (int) reader.readNBit(5, + "HRD: dpb_output_delay_length_minus1"); + hrd.time_offset_length = (int) reader.readNBit(5, + "HRD: time_offset_length"); + return hrd; + } + + public void write(OutputStream out) throws IOException { + CAVLCWriter writer = new CAVLCWriter(out); + + writer.writeNBit(profile_idc, 8, "SPS: profile_idc"); + writer.writeBool(constraint_set_0_flag, "SPS: constraint_set_0_flag"); + writer.writeBool(constraint_set_1_flag, "SPS: constraint_set_1_flag"); + writer.writeBool(constraint_set_2_flag, "SPS: constraint_set_2_flag"); + writer.writeBool(constraint_set_3_flag, "SPS: constraint_set_3_flag"); + writer.writeNBit(0, 4, "SPS: reserved"); + writer.writeNBit(level_idc, 8, "SPS: level_idc"); + writer.writeUE(seq_parameter_set_id, "SPS: seq_parameter_set_id"); + + if (profile_idc == 100 || profile_idc == 110 || profile_idc == 122 + || profile_idc == 144) { + writer.writeUE(chroma_format_idc.getId(), "SPS: chroma_format_idc"); + if (chroma_format_idc == ChromaFormat.YUV_444) { + writer.writeBool(residual_color_transform_flag, + "SPS: residual_color_transform_flag"); + } + writer.writeUE(bit_depth_luma_minus8, "SPS: "); + writer.writeUE(bit_depth_chroma_minus8, "SPS: "); + writer.writeBool(qpprime_y_zero_transform_bypass_flag, + "SPS: qpprime_y_zero_transform_bypass_flag"); + writer.writeBool(scalingMatrix != null, "SPS: "); + if (scalingMatrix != null) { + for (int i = 0; i < 8; i++) { + if (i < 6) { + writer.writeBool( + scalingMatrix.ScalingList4x4[i] != null, + "SPS: "); + if (scalingMatrix.ScalingList4x4[i] != null) { + scalingMatrix.ScalingList4x4[i].write(writer); + } + } else { + writer.writeBool( + scalingMatrix.ScalingList8x8[i - 6] != null, + "SPS: "); + if (scalingMatrix.ScalingList8x8[i - 6] != null) { + scalingMatrix.ScalingList8x8[i - 6].write(writer); + } + } + } + } + } + writer.writeUE(log2_max_frame_num_minus4, + "SPS: log2_max_frame_num_minus4"); + writer.writeUE(pic_order_cnt_type, "SPS: pic_order_cnt_type"); + if (pic_order_cnt_type == 0) { + writer.writeUE(log2_max_pic_order_cnt_lsb_minus4, + "SPS: log2_max_pic_order_cnt_lsb_minus4"); + } else if (pic_order_cnt_type == 1) { + writer.writeBool(delta_pic_order_always_zero_flag, + "SPS: delta_pic_order_always_zero_flag"); + writer.writeSE(offset_for_non_ref_pic, + "SPS: offset_for_non_ref_pic"); + writer.writeSE(offset_for_top_to_bottom_field, + "SPS: offset_for_top_to_bottom_field"); + writer.writeUE(offsetForRefFrame.length, "SPS: "); + for (int i = 0; i < offsetForRefFrame.length; i++) + writer.writeSE(offsetForRefFrame[i], "SPS: "); + } + writer.writeUE(num_ref_frames, "SPS: num_ref_frames"); + writer.writeBool(gaps_in_frame_num_value_allowed_flag, + "SPS: gaps_in_frame_num_value_allowed_flag"); + writer.writeUE(pic_width_in_mbs_minus1, "SPS: pic_width_in_mbs_minus1"); + writer.writeUE(pic_height_in_map_units_minus1, + "SPS: pic_height_in_map_units_minus1"); + writer.writeBool(frame_mbs_only_flag, "SPS: frame_mbs_only_flag"); + if (!frame_mbs_only_flag) { + writer.writeBool(mb_adaptive_frame_field_flag, + "SPS: mb_adaptive_frame_field_flag"); + } + writer.writeBool(direct_8x8_inference_flag, + "SPS: direct_8x8_inference_flag"); + writer.writeBool(frame_cropping_flag, "SPS: frame_cropping_flag"); + if (frame_cropping_flag) { + writer.writeUE(frame_crop_left_offset, + "SPS: frame_crop_left_offset"); + writer.writeUE(frame_crop_right_offset, + "SPS: frame_crop_right_offset"); + writer.writeUE(frame_crop_top_offset, "SPS: frame_crop_top_offset"); + writer.writeUE(frame_crop_bottom_offset, + "SPS: frame_crop_bottom_offset"); + } + writer.writeBool(vuiParams != null, "SPS: "); + if (vuiParams != null) + writeVUIParameters(vuiParams, writer); + + writer.writeTrailingBits(); + } + + private void writeVUIParameters(VUIParameters vuip, CAVLCWriter writer) + throws IOException { + writer.writeBool(vuip.aspect_ratio_info_present_flag, + "VUI: aspect_ratio_info_present_flag"); + if (vuip.aspect_ratio_info_present_flag) { + writer.writeNBit(vuip.aspect_ratio.getValue(), 8, + "VUI: aspect_ratio"); + if (vuip.aspect_ratio == AspectRatio.Extended_SAR) { + writer.writeNBit(vuip.sar_width, 16, "VUI: sar_width"); + writer.writeNBit(vuip.sar_height, 16, "VUI: sar_height"); + } + } + writer.writeBool(vuip.overscan_info_present_flag, + "VUI: overscan_info_present_flag"); + if (vuip.overscan_info_present_flag) { + writer.writeBool(vuip.overscan_appropriate_flag, + "VUI: overscan_appropriate_flag"); + } + writer.writeBool(vuip.video_signal_type_present_flag, + "VUI: video_signal_type_present_flag"); + if (vuip.video_signal_type_present_flag) { + writer.writeNBit(vuip.video_format, 3, "VUI: video_format"); + writer.writeBool(vuip.video_full_range_flag, + "VUI: video_full_range_flag"); + writer.writeBool(vuip.colour_description_present_flag, + "VUI: colour_description_present_flag"); + if (vuip.colour_description_present_flag) { + writer.writeNBit(vuip.colour_primaries, 8, + "VUI: colour_primaries"); + writer.writeNBit(vuip.transfer_characteristics, 8, + "VUI: transfer_characteristics"); + writer.writeNBit(vuip.matrix_coefficients, 8, + "VUI: matrix_coefficients"); + } + } + writer.writeBool(vuip.chroma_loc_info_present_flag, + "VUI: chroma_loc_info_present_flag"); + if (vuip.chroma_loc_info_present_flag) { + writer.writeUE(vuip.chroma_sample_loc_type_top_field, + "VUI: chroma_sample_loc_type_top_field"); + writer.writeUE(vuip.chroma_sample_loc_type_bottom_field, + "VUI: chroma_sample_loc_type_bottom_field"); + } + writer.writeBool(vuip.timing_info_present_flag, + "VUI: timing_info_present_flag"); + if (vuip.timing_info_present_flag) { + writer.writeNBit(vuip.num_units_in_tick, 32, + "VUI: num_units_in_tick"); + writer.writeNBit(vuip.time_scale, 32, "VUI: time_scale"); + writer.writeBool(vuip.fixed_frame_rate_flag, + "VUI: fixed_frame_rate_flag"); + } + writer.writeBool(vuip.nalHRDParams != null, "VUI: "); + if (vuip.nalHRDParams != null) { + writeHRDParameters(vuip.nalHRDParams, writer); + } + writer.writeBool(vuip.vclHRDParams != null, "VUI: "); + if (vuip.vclHRDParams != null) { + writeHRDParameters(vuip.vclHRDParams, writer); + } + + if (vuip.nalHRDParams != null || vuip.vclHRDParams != null) { + writer + .writeBool(vuip.low_delay_hrd_flag, + "VUI: low_delay_hrd_flag"); + } + writer.writeBool(vuip.pic_struct_present_flag, + "VUI: pic_struct_present_flag"); + writer.writeBool(vuip.bitstreamRestriction != null, "VUI: "); + if (vuip.bitstreamRestriction != null) { + writer + .writeBool( + vuip.bitstreamRestriction.motion_vectors_over_pic_boundaries_flag, + "VUI: motion_vectors_over_pic_boundaries_flag"); + writer.writeUE(vuip.bitstreamRestriction.max_bytes_per_pic_denom, + "VUI: max_bytes_per_pic_denom"); + writer.writeUE(vuip.bitstreamRestriction.max_bits_per_mb_denom, + "VUI: max_bits_per_mb_denom"); + writer.writeUE( + vuip.bitstreamRestriction.log2_max_mv_length_horizontal, + "VUI: log2_max_mv_length_horizontal"); + writer.writeUE( + vuip.bitstreamRestriction.log2_max_mv_length_vertical, + "VUI: log2_max_mv_length_vertical"); + writer.writeUE(vuip.bitstreamRestriction.num_reorder_frames, + "VUI: num_reorder_frames"); + writer.writeUE(vuip.bitstreamRestriction.max_dec_frame_buffering, + "VUI: max_dec_frame_buffering"); + } + + } + + private void writeHRDParameters(HRDParameters hrd, CAVLCWriter writer) + throws IOException { + writer.writeUE(hrd.cpb_cnt_minus1, "HRD: cpb_cnt_minus1"); + writer.writeNBit(hrd.bit_rate_scale, 4, "HRD: bit_rate_scale"); + writer.writeNBit(hrd.cpb_size_scale, 4, "HRD: cpb_size_scale"); + + for (int SchedSelIdx = 0; SchedSelIdx <= hrd.cpb_cnt_minus1; SchedSelIdx++) { + writer.writeUE(hrd.bit_rate_value_minus1[SchedSelIdx], "HRD: "); + writer.writeUE(hrd.cpb_size_value_minus1[SchedSelIdx], "HRD: "); + writer.writeBool(hrd.cbr_flag[SchedSelIdx], "HRD: "); + } + writer.writeNBit(hrd.initial_cpb_removal_delay_length_minus1, 5, + "HRD: initial_cpb_removal_delay_length_minus1"); + writer.writeNBit(hrd.cpb_removal_delay_length_minus1, 5, + "HRD: cpb_removal_delay_length_minus1"); + writer.writeNBit(hrd.dpb_output_delay_length_minus1, 5, + "HRD: dpb_output_delay_length_minus1"); + writer.writeNBit(hrd.time_offset_length, 5, "HRD: time_offset_length"); + } + + @Override + public String toString() { + return "SeqParameterSet{ " + + "\n pic_order_cnt_type=" + pic_order_cnt_type + + ", \n field_pic_flag=" + field_pic_flag + + ", \n delta_pic_order_always_zero_flag=" + delta_pic_order_always_zero_flag + + ", \n weighted_pred_flag=" + weighted_pred_flag + + ", \n weighted_bipred_idc=" + weighted_bipred_idc + + ", \n entropy_coding_mode_flag=" + entropy_coding_mode_flag + + ", \n mb_adaptive_frame_field_flag=" + mb_adaptive_frame_field_flag + + ", \n direct_8x8_inference_flag=" + direct_8x8_inference_flag + + ", \n chroma_format_idc=" + chroma_format_idc + + ", \n log2_max_frame_num_minus4=" + log2_max_frame_num_minus4 + + ", \n log2_max_pic_order_cnt_lsb_minus4=" + log2_max_pic_order_cnt_lsb_minus4 + + ", \n pic_height_in_map_units_minus1=" + pic_height_in_map_units_minus1 + + ", \n pic_width_in_mbs_minus1=" + pic_width_in_mbs_minus1 + + ", \n bit_depth_luma_minus8=" + bit_depth_luma_minus8 + + ", \n bit_depth_chroma_minus8=" + bit_depth_chroma_minus8 + + ", \n qpprime_y_zero_transform_bypass_flag=" + qpprime_y_zero_transform_bypass_flag + + ", \n profile_idc=" + profile_idc + + ", \n constraint_set_0_flag=" + constraint_set_0_flag + + ", \n constraint_set_1_flag=" + constraint_set_1_flag + + ", \n constraint_set_2_flag=" + constraint_set_2_flag + + ", \n constraint_set_3_flag=" + constraint_set_3_flag + + ", \n level_idc=" + level_idc + + ", \n seq_parameter_set_id=" + seq_parameter_set_id + + ", \n residual_color_transform_flag=" + residual_color_transform_flag + + ", \n offset_for_non_ref_pic=" + offset_for_non_ref_pic + + ", \n offset_for_top_to_bottom_field=" + offset_for_top_to_bottom_field + + ", \n num_ref_frames=" + num_ref_frames + + ", \n gaps_in_frame_num_value_allowed_flag=" + gaps_in_frame_num_value_allowed_flag + + ", \n frame_mbs_only_flag=" + frame_mbs_only_flag + + ", \n frame_cropping_flag=" + frame_cropping_flag + + ", \n frame_crop_left_offset=" + frame_crop_left_offset + + ", \n frame_crop_right_offset=" + frame_crop_right_offset + + ", \n frame_crop_top_offset=" + frame_crop_top_offset + + ", \n frame_crop_bottom_offset=" + frame_crop_bottom_offset + + ", \n offsetForRefFrame=" + offsetForRefFrame + + ", \n vuiParams=" + vuiParams + + ", \n scalingMatrix=" + scalingMatrix + + ", \n num_ref_frames_in_pic_order_cnt_cycle=" + num_ref_frames_in_pic_order_cnt_cycle + + '}'; + } +}
\ No newline at end of file diff --git a/isoparser/src/main/java/com/googlecode/mp4parser/h264/model/.svn/text-base/VUIParameters.java.svn-base b/isoparser/src/main/java/com/googlecode/mp4parser/h264/model/.svn/text-base/VUIParameters.java.svn-base new file mode 100644 index 0000000..eec7880 --- /dev/null +++ b/isoparser/src/main/java/com/googlecode/mp4parser/h264/model/.svn/text-base/VUIParameters.java.svn-base @@ -0,0 +1,94 @@ +/* +Copyright (c) 2011 Stanislav Vitvitskiy + +Permission is hereby granted, free of charge, to any person obtaining a copy of this +software and associated documentation files (the "Software"), to deal in the Software +without restriction, including without limitation the rights to use, copy, modify, +merge, publish, distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice shall be included in all copies or +substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, +INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR +PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE +FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE +OR OTHER DEALINGS IN THE SOFTWARE. +*/ +package com.googlecode.mp4parser.h264.model; + +public class VUIParameters { + + public static class BitstreamRestriction { + + public boolean motion_vectors_over_pic_boundaries_flag; + public int max_bytes_per_pic_denom; + public int max_bits_per_mb_denom; + public int log2_max_mv_length_horizontal; + public int log2_max_mv_length_vertical; + public int num_reorder_frames; + public int max_dec_frame_buffering; + + } + + public boolean aspect_ratio_info_present_flag; + public int sar_width; + public int sar_height; + public boolean overscan_info_present_flag; + public boolean overscan_appropriate_flag; + public boolean video_signal_type_present_flag; + public int video_format; + public boolean video_full_range_flag; + public boolean colour_description_present_flag; + public int colour_primaries; + public int transfer_characteristics; + public int matrix_coefficients; + public boolean chroma_loc_info_present_flag; + public int chroma_sample_loc_type_top_field; + public int chroma_sample_loc_type_bottom_field; + public boolean timing_info_present_flag; + public int num_units_in_tick; + public int time_scale; + public boolean fixed_frame_rate_flag; + public boolean low_delay_hrd_flag; + public boolean pic_struct_present_flag; + public HRDParameters nalHRDParams; + public HRDParameters vclHRDParams; + + public BitstreamRestriction bitstreamRestriction; + public AspectRatio aspect_ratio; + + @Override + public String toString() { + return "VUIParameters{" + "\n" + + "aspect_ratio_info_present_flag=" + aspect_ratio_info_present_flag + "\n" + + ", sar_width=" + sar_width + "\n" + + ", sar_height=" + sar_height + "\n" + + ", overscan_info_present_flag=" + overscan_info_present_flag + "\n" + + ", overscan_appropriate_flag=" + overscan_appropriate_flag + "\n" + + ", video_signal_type_present_flag=" + video_signal_type_present_flag + "\n" + + ", video_format=" + video_format + "\n" + + ", video_full_range_flag=" + video_full_range_flag + "\n" + + ", colour_description_present_flag=" + colour_description_present_flag + "\n" + + ", colour_primaries=" + colour_primaries + "\n" + + ", transfer_characteristics=" + transfer_characteristics + "\n" + + ", matrix_coefficients=" + matrix_coefficients + "\n" + + ", chroma_loc_info_present_flag=" + chroma_loc_info_present_flag + "\n" + + ", chroma_sample_loc_type_top_field=" + chroma_sample_loc_type_top_field + "\n" + + ", chroma_sample_loc_type_bottom_field=" + chroma_sample_loc_type_bottom_field + "\n" + + ", timing_info_present_flag=" + timing_info_present_flag + "\n" + + ", num_units_in_tick=" + num_units_in_tick + "\n" + + ", time_scale=" + time_scale + "\n" + + ", fixed_frame_rate_flag=" + fixed_frame_rate_flag + "\n" + + ", low_delay_hrd_flag=" + low_delay_hrd_flag + "\n" + + ", pic_struct_present_flag=" + pic_struct_present_flag + "\n" + + ", nalHRDParams=" + nalHRDParams + "\n" + + ", vclHRDParams=" + vclHRDParams + "\n" + + ", bitstreamRestriction=" + bitstreamRestriction + "\n" + + ", aspect_ratio=" + aspect_ratio + "\n" + + '}'; + } +} diff --git a/isoparser/src/main/java/com/googlecode/mp4parser/h264/model/AspectRatio.java b/isoparser/src/main/java/com/googlecode/mp4parser/h264/model/AspectRatio.java new file mode 100644 index 0000000..bc66b1a --- /dev/null +++ b/isoparser/src/main/java/com/googlecode/mp4parser/h264/model/AspectRatio.java @@ -0,0 +1,50 @@ +/* +Copyright (c) 2011 Stanislav Vitvitskiy + +Permission is hereby granted, free of charge, to any person obtaining a copy of this +software and associated documentation files (the "Software"), to deal in the Software +without restriction, including without limitation the rights to use, copy, modify, +merge, publish, distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice shall be included in all copies or +substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, +INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR +PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE +FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE +OR OTHER DEALINGS IN THE SOFTWARE. +*/ +package com.googlecode.mp4parser.h264.model; + +/** + * Aspect ratio + * <p/> + * dynamic enum + * + * @author Stanislav Vitvitskiy + */ +public class AspectRatio { + + public static final AspectRatio Extended_SAR = new AspectRatio(255); + + private int value; + + private AspectRatio(int value) { + this.value = value; + } + + public static AspectRatio fromValue(int value) { + if (value == Extended_SAR.value) { + return Extended_SAR; + } + return new AspectRatio(value); + } + + public int getValue() { + return value; + } +} diff --git a/isoparser/src/main/java/com/googlecode/mp4parser/h264/model/BitstreamElement.java b/isoparser/src/main/java/com/googlecode/mp4parser/h264/model/BitstreamElement.java new file mode 100644 index 0000000..f16c5e9 --- /dev/null +++ b/isoparser/src/main/java/com/googlecode/mp4parser/h264/model/BitstreamElement.java @@ -0,0 +1,29 @@ +/* +Copyright (c) 2011 Stanislav Vitvitskiy + +Permission is hereby granted, free of charge, to any person obtaining a copy of this +software and associated documentation files (the "Software"), to deal in the Software +without restriction, including without limitation the rights to use, copy, modify, +merge, publish, distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice shall be included in all copies or +substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, +INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR +PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE +FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE +OR OTHER DEALINGS IN THE SOFTWARE. +*/ +package com.googlecode.mp4parser.h264.model; + +import java.io.IOException; +import java.io.OutputStream; + +public abstract class BitstreamElement { + + public abstract void write(OutputStream out) throws IOException; +} diff --git a/isoparser/src/main/java/com/googlecode/mp4parser/h264/model/ChromaFormat.java b/isoparser/src/main/java/com/googlecode/mp4parser/h264/model/ChromaFormat.java new file mode 100644 index 0000000..2af2966 --- /dev/null +++ b/isoparser/src/main/java/com/googlecode/mp4parser/h264/model/ChromaFormat.java @@ -0,0 +1,77 @@ +/* +Copyright (c) 2011 Stanislav Vitvitskiy + +Permission is hereby granted, free of charge, to any person obtaining a copy of this +software and associated documentation files (the "Software"), to deal in the Software +without restriction, including without limitation the rights to use, copy, modify, +merge, publish, distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice shall be included in all copies or +substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, +INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR +PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE +FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE +OR OTHER DEALINGS IN THE SOFTWARE. +*/ +package com.googlecode.mp4parser.h264.model; + +/** + * Chroma format enum + * + * @author Stanislav Vitvitskiy + */ +public class ChromaFormat { + public static ChromaFormat MONOCHROME = new ChromaFormat(0, 0, 0); + public static ChromaFormat YUV_420 = new ChromaFormat(1, 2, 2); + public static ChromaFormat YUV_422 = new ChromaFormat(2, 2, 1); + public static ChromaFormat YUV_444 = new ChromaFormat(3, 1, 1); + + private int id; + private int subWidth; + private int subHeight; + + public ChromaFormat(int id, int subWidth, int subHeight) { + this.id = id; + this.subWidth = subWidth; + this.subHeight = subHeight; + } + + public static ChromaFormat fromId(int id) { + if (id == MONOCHROME.id) { + return MONOCHROME; + } else if (id == YUV_420.id) { + return YUV_420; + } else if (id == YUV_422.id) { + return YUV_422; + } else if (id == YUV_444.id) { + return YUV_444; + } + return null; + } + + public int getId() { + return id; + } + + public int getSubWidth() { + return subWidth; + } + + public int getSubHeight() { + return subHeight; + } + + @Override + public String toString() { + return "ChromaFormat{" + "\n" + + "id=" + id + ",\n" + + " subWidth=" + subWidth + ",\n" + + " subHeight=" + subHeight + + '}'; + } +} diff --git a/isoparser/src/main/java/com/googlecode/mp4parser/h264/model/HRDParameters.java b/isoparser/src/main/java/com/googlecode/mp4parser/h264/model/HRDParameters.java new file mode 100644 index 0000000..f713ab2 --- /dev/null +++ b/isoparser/src/main/java/com/googlecode/mp4parser/h264/model/HRDParameters.java @@ -0,0 +1,53 @@ +/* +Copyright (c) 2011 Stanislav Vitvitskiy + +Permission is hereby granted, free of charge, to any person obtaining a copy of this +software and associated documentation files (the "Software"), to deal in the Software +without restriction, including without limitation the rights to use, copy, modify, +merge, publish, distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice shall be included in all copies or +substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, +INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR +PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE +FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE +OR OTHER DEALINGS IN THE SOFTWARE. +*/ +package com.googlecode.mp4parser.h264.model; + +import java.util.Arrays; + +public class HRDParameters { + + public int cpb_cnt_minus1; + public int bit_rate_scale; + public int cpb_size_scale; + public int[] bit_rate_value_minus1; + public int[] cpb_size_value_minus1; + public boolean[] cbr_flag; + public int initial_cpb_removal_delay_length_minus1; + public int cpb_removal_delay_length_minus1; + public int dpb_output_delay_length_minus1; + public int time_offset_length; + + @Override + public String toString() { + return "HRDParameters{" + + "cpb_cnt_minus1=" + cpb_cnt_minus1 + + ", bit_rate_scale=" + bit_rate_scale + + ", cpb_size_scale=" + cpb_size_scale + + ", bit_rate_value_minus1=" + Arrays.toString(bit_rate_value_minus1) + + ", cpb_size_value_minus1=" + Arrays.toString(cpb_size_value_minus1) + + ", cbr_flag=" + Arrays.toString(cbr_flag) + + ", initial_cpb_removal_delay_length_minus1=" + initial_cpb_removal_delay_length_minus1 + + ", cpb_removal_delay_length_minus1=" + cpb_removal_delay_length_minus1 + + ", dpb_output_delay_length_minus1=" + dpb_output_delay_length_minus1 + + ", time_offset_length=" + time_offset_length + + '}'; + } +} diff --git a/isoparser/src/main/java/com/googlecode/mp4parser/h264/model/PictureParameterSet.java b/isoparser/src/main/java/com/googlecode/mp4parser/h264/model/PictureParameterSet.java new file mode 100644 index 0000000..9154c38 --- /dev/null +++ b/isoparser/src/main/java/com/googlecode/mp4parser/h264/model/PictureParameterSet.java @@ -0,0 +1,406 @@ +/* +Copyright (c) 2011 Stanislav Vitvitskiy + +Permission is hereby granted, free of charge, to any person obtaining a copy of this +software and associated documentation files (the "Software"), to deal in the Software +without restriction, including without limitation the rights to use, copy, modify, +merge, publish, distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice shall be included in all copies or +substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, +INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR +PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE +FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE +OR OTHER DEALINGS IN THE SOFTWARE. +*/ +package com.googlecode.mp4parser.h264.model; + +import com.googlecode.mp4parser.h264.read.CAVLCReader; +import com.googlecode.mp4parser.h264.write.CAVLCWriter; + +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.util.Arrays; + +/** + * Picture Parameter Set entity of H264 bitstream + * <p/> + * capable to serialize / deserialize with CAVLC bitstream + * + * @author Stanislav Vitvitskiy + */ +public class PictureParameterSet extends BitstreamElement { + + public static class PPSExt { + public boolean transform_8x8_mode_flag; + public ScalingMatrix scalindMatrix = new ScalingMatrix(); + public int second_chroma_qp_index_offset; + public boolean[] pic_scaling_list_present_flag; + + @Override + public String toString() { + return "PPSExt{" + + "transform_8x8_mode_flag=" + transform_8x8_mode_flag + + ", scalindMatrix=" + scalindMatrix + + ", second_chroma_qp_index_offset=" + second_chroma_qp_index_offset + + ", pic_scaling_list_present_flag=" + pic_scaling_list_present_flag + + '}'; + } + } + + public boolean entropy_coding_mode_flag; + public int num_ref_idx_l0_active_minus1; + public int num_ref_idx_l1_active_minus1; + public int slice_group_change_rate_minus1; + public int pic_parameter_set_id; + public int seq_parameter_set_id; + public boolean pic_order_present_flag; + public int num_slice_groups_minus1; + public int slice_group_map_type; + public boolean weighted_pred_flag; + public int weighted_bipred_idc; + public int pic_init_qp_minus26; + public int pic_init_qs_minus26; + public int chroma_qp_index_offset; + public boolean deblocking_filter_control_present_flag; + public boolean constrained_intra_pred_flag; + public boolean redundant_pic_cnt_present_flag; + public int[] top_left; + public int[] bottom_right; + public int[] run_length_minus1; + public boolean slice_group_change_direction_flag; + public int[] slice_group_id; + public PPSExt extended; + + public static PictureParameterSet read(byte[] b) throws IOException { + return read(new ByteArrayInputStream(b)); + } + + public static PictureParameterSet read(InputStream is) throws IOException { + CAVLCReader reader = new CAVLCReader(is); + PictureParameterSet pps = new PictureParameterSet(); + + pps.pic_parameter_set_id = reader.readUE("PPS: pic_parameter_set_id"); + pps.seq_parameter_set_id = reader.readUE("PPS: seq_parameter_set_id"); + pps.entropy_coding_mode_flag = reader + .readBool("PPS: entropy_coding_mode_flag"); + pps.pic_order_present_flag = reader + .readBool("PPS: pic_order_present_flag"); + pps.num_slice_groups_minus1 = reader + .readUE("PPS: num_slice_groups_minus1"); + if (pps.num_slice_groups_minus1 > 0) { + pps.slice_group_map_type = reader + .readUE("PPS: slice_group_map_type"); + pps.top_left = new int[pps.num_slice_groups_minus1 + 1]; + pps.bottom_right = new int[pps.num_slice_groups_minus1 + 1]; + pps.run_length_minus1 = new int[pps.num_slice_groups_minus1 + 1]; + if (pps.slice_group_map_type == 0) + for (int iGroup = 0; iGroup <= pps.num_slice_groups_minus1; iGroup++) + pps.run_length_minus1[iGroup] = reader + .readUE("PPS: run_length_minus1"); + else if (pps.slice_group_map_type == 2) + for (int iGroup = 0; iGroup < pps.num_slice_groups_minus1; iGroup++) { + pps.top_left[iGroup] = reader.readUE("PPS: top_left"); + pps.bottom_right[iGroup] = reader + .readUE("PPS: bottom_right"); + } + else if (pps.slice_group_map_type == 3 + || pps.slice_group_map_type == 4 + || pps.slice_group_map_type == 5) { + pps.slice_group_change_direction_flag = reader + .readBool("PPS: slice_group_change_direction_flag"); + pps.slice_group_change_rate_minus1 = reader + .readUE("PPS: slice_group_change_rate_minus1"); + } else if (pps.slice_group_map_type == 6) { + int NumberBitsPerSliceGroupId; + if (pps.num_slice_groups_minus1 + 1 > 4) + NumberBitsPerSliceGroupId = 3; + else if (pps.num_slice_groups_minus1 + 1 > 2) + NumberBitsPerSliceGroupId = 2; + else + NumberBitsPerSliceGroupId = 1; + int pic_size_in_map_units_minus1 = reader + .readUE("PPS: pic_size_in_map_units_minus1"); + pps.slice_group_id = new int[pic_size_in_map_units_minus1 + 1]; + for (int i = 0; i <= pic_size_in_map_units_minus1; i++) { + pps.slice_group_id[i] = reader.readU( + NumberBitsPerSliceGroupId, "PPS: slice_group_id [" + + i + "]f"); + } + } + } + pps.num_ref_idx_l0_active_minus1 = reader + .readUE("PPS: num_ref_idx_l0_active_minus1"); + pps.num_ref_idx_l1_active_minus1 = reader + .readUE("PPS: num_ref_idx_l1_active_minus1"); + pps.weighted_pred_flag = reader.readBool("PPS: weighted_pred_flag"); + pps.weighted_bipred_idc = (int) reader.readNBit(2, + "PPS: weighted_bipred_idc"); + pps.pic_init_qp_minus26 = reader.readSE("PPS: pic_init_qp_minus26"); + pps.pic_init_qs_minus26 = reader.readSE("PPS: pic_init_qs_minus26"); + pps.chroma_qp_index_offset = reader + .readSE("PPS: chroma_qp_index_offset"); + pps.deblocking_filter_control_present_flag = reader + .readBool("PPS: deblocking_filter_control_present_flag"); + pps.constrained_intra_pred_flag = reader + .readBool("PPS: constrained_intra_pred_flag"); + pps.redundant_pic_cnt_present_flag = reader + .readBool("PPS: redundant_pic_cnt_present_flag"); + if (reader.moreRBSPData()) { + pps.extended = new PictureParameterSet.PPSExt(); + pps.extended.transform_8x8_mode_flag = reader + .readBool("PPS: transform_8x8_mode_flag"); + boolean pic_scaling_matrix_present_flag = reader + .readBool("PPS: pic_scaling_matrix_present_flag"); + if (pic_scaling_matrix_present_flag) { + for (int i = 0; i < 6 + 2 * (pps.extended.transform_8x8_mode_flag ? 1 + : 0); i++) { + boolean pic_scaling_list_present_flag = reader + .readBool("PPS: pic_scaling_list_present_flag"); + if (pic_scaling_list_present_flag) { + pps.extended.scalindMatrix.ScalingList4x4 = new ScalingList[8]; + pps.extended.scalindMatrix.ScalingList8x8 = new ScalingList[8]; + if (i < 6) { + pps.extended.scalindMatrix.ScalingList4x4[i] = ScalingList + .read(reader, 16); + } else { + pps.extended.scalindMatrix.ScalingList8x8[i - 6] = ScalingList + .read(reader, 64); + } + } + } + } + pps.extended.second_chroma_qp_index_offset = reader + .readSE("PPS: second_chroma_qp_index_offset"); + } + + reader.readTrailingBits(); + + return pps; + } + + public void write(OutputStream out) throws IOException { + CAVLCWriter writer = new CAVLCWriter(out); + + writer.writeUE(pic_parameter_set_id, "PPS: pic_parameter_set_id"); + writer.writeUE(seq_parameter_set_id, "PPS: seq_parameter_set_id"); + writer.writeBool(entropy_coding_mode_flag, + "PPS: entropy_coding_mode_flag"); + writer.writeBool(pic_order_present_flag, "PPS: pic_order_present_flag"); + writer.writeUE(num_slice_groups_minus1, "PPS: num_slice_groups_minus1"); + if (num_slice_groups_minus1 > 0) { + writer.writeUE(slice_group_map_type, "PPS: slice_group_map_type"); + int[] top_left = new int[1]; + int[] bottom_right = new int[1]; + int[] run_length_minus1 = new int[1]; + if (slice_group_map_type == 0) { + for (int iGroup = 0; iGroup <= num_slice_groups_minus1; iGroup++) { + writer.writeUE(run_length_minus1[iGroup], "PPS: "); + } + } else if (slice_group_map_type == 2) { + for (int iGroup = 0; iGroup < num_slice_groups_minus1; iGroup++) { + writer.writeUE(top_left[iGroup], "PPS: "); + writer.writeUE(bottom_right[iGroup], "PPS: "); + } + } else if (slice_group_map_type == 3 || slice_group_map_type == 4 + || slice_group_map_type == 5) { + writer.writeBool(slice_group_change_direction_flag, + "PPS: slice_group_change_direction_flag"); + writer.writeUE(slice_group_change_rate_minus1, + "PPS: slice_group_change_rate_minus1"); + } else if (slice_group_map_type == 6) { + int NumberBitsPerSliceGroupId; + if (num_slice_groups_minus1 + 1 > 4) + NumberBitsPerSliceGroupId = 3; + else if (num_slice_groups_minus1 + 1 > 2) + NumberBitsPerSliceGroupId = 2; + else + NumberBitsPerSliceGroupId = 1; + writer.writeUE(slice_group_id.length, "PPS: "); + for (int i = 0; i <= slice_group_id.length; i++) { + writer.writeU(slice_group_id[i], NumberBitsPerSliceGroupId); + } + } + } + writer.writeUE(num_ref_idx_l0_active_minus1, + "PPS: num_ref_idx_l0_active_minus1"); + writer.writeUE(num_ref_idx_l1_active_minus1, + "PPS: num_ref_idx_l1_active_minus1"); + writer.writeBool(weighted_pred_flag, "PPS: weighted_pred_flag"); + writer.writeNBit(weighted_bipred_idc, 2, "PPS: weighted_bipred_idc"); + writer.writeSE(pic_init_qp_minus26, "PPS: pic_init_qp_minus26"); + writer.writeSE(pic_init_qs_minus26, "PPS: pic_init_qs_minus26"); + writer.writeSE(chroma_qp_index_offset, "PPS: chroma_qp_index_offset"); + writer.writeBool(deblocking_filter_control_present_flag, + "PPS: deblocking_filter_control_present_flag"); + writer.writeBool(constrained_intra_pred_flag, + "PPS: constrained_intra_pred_flag"); + writer.writeBool(redundant_pic_cnt_present_flag, + "PPS: redundant_pic_cnt_present_flag"); + if (extended != null) { + writer.writeBool(extended.transform_8x8_mode_flag, + "PPS: transform_8x8_mode_flag"); + writer.writeBool(extended.scalindMatrix != null, + "PPS: scalindMatrix"); + if (extended.scalindMatrix != null) { + for (int i = 0; i < 6 + 2 * (extended.transform_8x8_mode_flag ? 1 + : 0); i++) { + if (i < 6) { + writer + .writeBool( + extended.scalindMatrix.ScalingList4x4[i] != null, + "PPS: "); + if (extended.scalindMatrix.ScalingList4x4[i] != null) { + extended.scalindMatrix.ScalingList4x4[i] + .write(writer); + } + + } else { + writer + .writeBool( + extended.scalindMatrix.ScalingList8x8[i - 6] != null, + "PPS: "); + if (extended.scalindMatrix.ScalingList8x8[i - 6] != null) { + extended.scalindMatrix.ScalingList8x8[i - 6] + .write(writer); + } + } + } + } + writer.writeSE(extended.second_chroma_qp_index_offset, "PPS: "); + } + + writer.writeTrailingBits(); + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + Arrays.hashCode(bottom_right); + result = prime * result + chroma_qp_index_offset; + result = prime * result + (constrained_intra_pred_flag ? 1231 : 1237); + result = prime * result + + (deblocking_filter_control_present_flag ? 1231 : 1237); + result = prime * result + (entropy_coding_mode_flag ? 1231 : 1237); + result = prime * result + + ((extended == null) ? 0 : extended.hashCode()); + result = prime * result + num_ref_idx_l0_active_minus1; + result = prime * result + num_ref_idx_l1_active_minus1; + result = prime * result + num_slice_groups_minus1; + result = prime * result + pic_init_qp_minus26; + result = prime * result + pic_init_qs_minus26; + result = prime * result + (pic_order_present_flag ? 1231 : 1237); + result = prime * result + pic_parameter_set_id; + result = prime * result + + (redundant_pic_cnt_present_flag ? 1231 : 1237); + result = prime * result + Arrays.hashCode(run_length_minus1); + result = prime * result + seq_parameter_set_id; + result = prime * result + + (slice_group_change_direction_flag ? 1231 : 1237); + result = prime * result + slice_group_change_rate_minus1; + result = prime * result + Arrays.hashCode(slice_group_id); + result = prime * result + slice_group_map_type; + result = prime * result + Arrays.hashCode(top_left); + result = prime * result + weighted_bipred_idc; + result = prime * result + (weighted_pred_flag ? 1231 : 1237); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + PictureParameterSet other = (PictureParameterSet) obj; + if (!Arrays.equals(bottom_right, other.bottom_right)) + return false; + if (chroma_qp_index_offset != other.chroma_qp_index_offset) + return false; + if (constrained_intra_pred_flag != other.constrained_intra_pred_flag) + return false; + if (deblocking_filter_control_present_flag != other.deblocking_filter_control_present_flag) + return false; + if (entropy_coding_mode_flag != other.entropy_coding_mode_flag) + return false; + if (extended == null) { + if (other.extended != null) + return false; + } else if (!extended.equals(other.extended)) + return false; + if (num_ref_idx_l0_active_minus1 != other.num_ref_idx_l0_active_minus1) + return false; + if (num_ref_idx_l1_active_minus1 != other.num_ref_idx_l1_active_minus1) + return false; + if (num_slice_groups_minus1 != other.num_slice_groups_minus1) + return false; + if (pic_init_qp_minus26 != other.pic_init_qp_minus26) + return false; + if (pic_init_qs_minus26 != other.pic_init_qs_minus26) + return false; + if (pic_order_present_flag != other.pic_order_present_flag) + return false; + if (pic_parameter_set_id != other.pic_parameter_set_id) + return false; + if (redundant_pic_cnt_present_flag != other.redundant_pic_cnt_present_flag) + return false; + if (!Arrays.equals(run_length_minus1, other.run_length_minus1)) + return false; + if (seq_parameter_set_id != other.seq_parameter_set_id) + return false; + if (slice_group_change_direction_flag != other.slice_group_change_direction_flag) + return false; + if (slice_group_change_rate_minus1 != other.slice_group_change_rate_minus1) + return false; + if (!Arrays.equals(slice_group_id, other.slice_group_id)) + return false; + if (slice_group_map_type != other.slice_group_map_type) + return false; + if (!Arrays.equals(top_left, other.top_left)) + return false; + if (weighted_bipred_idc != other.weighted_bipred_idc) + return false; + if (weighted_pred_flag != other.weighted_pred_flag) + return false; + return true; + } + + @Override + public String toString() { + return "PictureParameterSet{" + + "\n entropy_coding_mode_flag=" + entropy_coding_mode_flag + + ",\n num_ref_idx_l0_active_minus1=" + num_ref_idx_l0_active_minus1 + + ",\n num_ref_idx_l1_active_minus1=" + num_ref_idx_l1_active_minus1 + + ",\n slice_group_change_rate_minus1=" + slice_group_change_rate_minus1 + + ",\n pic_parameter_set_id=" + pic_parameter_set_id + + ",\n seq_parameter_set_id=" + seq_parameter_set_id + + ",\n pic_order_present_flag=" + pic_order_present_flag + + ",\n num_slice_groups_minus1=" + num_slice_groups_minus1 + + ",\n slice_group_map_type=" + slice_group_map_type + + ",\n weighted_pred_flag=" + weighted_pred_flag + + ",\n weighted_bipred_idc=" + weighted_bipred_idc + + ",\n pic_init_qp_minus26=" + pic_init_qp_minus26 + + ",\n pic_init_qs_minus26=" + pic_init_qs_minus26 + + ",\n chroma_qp_index_offset=" + chroma_qp_index_offset + + ",\n deblocking_filter_control_present_flag=" + deblocking_filter_control_present_flag + + ",\n constrained_intra_pred_flag=" + constrained_intra_pred_flag + + ",\n redundant_pic_cnt_present_flag=" + redundant_pic_cnt_present_flag + + ",\n top_left=" + top_left + + ",\n bottom_right=" + bottom_right + + ",\n run_length_minus1=" + run_length_minus1 + + ",\n slice_group_change_direction_flag=" + slice_group_change_direction_flag + + ",\n slice_group_id=" + slice_group_id + + ",\n extended=" + extended + + '}'; + } +} diff --git a/isoparser/src/main/java/com/googlecode/mp4parser/h264/model/ScalingList.java b/isoparser/src/main/java/com/googlecode/mp4parser/h264/model/ScalingList.java new file mode 100644 index 0000000..5d272bf --- /dev/null +++ b/isoparser/src/main/java/com/googlecode/mp4parser/h264/model/ScalingList.java @@ -0,0 +1,83 @@ +/* +Copyright (c) 2011 Stanislav Vitvitskiy + +Permission is hereby granted, free of charge, to any person obtaining a copy of this +software and associated documentation files (the "Software"), to deal in the Software +without restriction, including without limitation the rights to use, copy, modify, +merge, publish, distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice shall be included in all copies or +substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, +INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR +PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE +FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE +OR OTHER DEALINGS IN THE SOFTWARE. +*/ +package com.googlecode.mp4parser.h264.model; + +import com.googlecode.mp4parser.h264.read.CAVLCReader; +import com.googlecode.mp4parser.h264.write.CAVLCWriter; + +import java.io.IOException; + +/** + * Scaling list entity + * <p/> + * capable to serialize / deserialize with CAVLC bitstream + * + * @author Stanislav Vitvitskiy + */ +public class ScalingList { + + public int[] scalingList; + public boolean useDefaultScalingMatrixFlag; + + public void write(CAVLCWriter out) throws IOException { + if (useDefaultScalingMatrixFlag) { + out.writeSE(0, "SPS: "); + return; + } + + int lastScale = 8; + int nextScale = 8; + for (int j = 0; j < scalingList.length; j++) { + if (nextScale != 0) { + int deltaScale = scalingList[j] - lastScale - 256; + out.writeSE(deltaScale, "SPS: "); + } + lastScale = scalingList[j]; + } + } + + public static ScalingList read(CAVLCReader is, int sizeOfScalingList) + throws IOException { + + ScalingList sl = new ScalingList(); + sl.scalingList = new int[sizeOfScalingList]; + int lastScale = 8; + int nextScale = 8; + for (int j = 0; j < sizeOfScalingList; j++) { + if (nextScale != 0) { + int deltaScale = is.readSE("deltaScale"); + nextScale = (lastScale + deltaScale + 256) % 256; + sl.useDefaultScalingMatrixFlag = (j == 0 && nextScale == 0); + } + sl.scalingList[j] = nextScale == 0 ? lastScale : nextScale; + lastScale = sl.scalingList[j]; + } + return sl; + } + + @Override + public String toString() { + return "ScalingList{" + + "scalingList=" + scalingList + + ", useDefaultScalingMatrixFlag=" + useDefaultScalingMatrixFlag + + '}'; + } +}
\ No newline at end of file diff --git a/isoparser/src/main/java/com/googlecode/mp4parser/h264/model/ScalingMatrix.java b/isoparser/src/main/java/com/googlecode/mp4parser/h264/model/ScalingMatrix.java new file mode 100644 index 0000000..d04af8e --- /dev/null +++ b/isoparser/src/main/java/com/googlecode/mp4parser/h264/model/ScalingMatrix.java @@ -0,0 +1,37 @@ +/* +Copyright (c) 2011 Stanislav Vitvitskiy + +Permission is hereby granted, free of charge, to any person obtaining a copy of this +software and associated documentation files (the "Software"), to deal in the Software +without restriction, including without limitation the rights to use, copy, modify, +merge, publish, distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice shall be included in all copies or +substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, +INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR +PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE +FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE +OR OTHER DEALINGS IN THE SOFTWARE. +*/ +package com.googlecode.mp4parser.h264.model; + +import java.util.Arrays; + +public class ScalingMatrix { + + public ScalingList[] ScalingList4x4; + public ScalingList[] ScalingList8x8; + + @Override + public String toString() { + return "ScalingMatrix{" + + "ScalingList4x4=" + (ScalingList4x4 == null ? null : Arrays.asList(ScalingList4x4)) + "\n" + + ", ScalingList8x8=" + (ScalingList8x8 == null ? null : Arrays.asList(ScalingList8x8)) + "\n" + + '}'; + } +}
\ No newline at end of file diff --git a/isoparser/src/main/java/com/googlecode/mp4parser/h264/model/SeqParameterSet.java b/isoparser/src/main/java/com/googlecode/mp4parser/h264/model/SeqParameterSet.java new file mode 100644 index 0000000..4894df8 --- /dev/null +++ b/isoparser/src/main/java/com/googlecode/mp4parser/h264/model/SeqParameterSet.java @@ -0,0 +1,556 @@ +/* +Copyright (c) 2011 Stanislav Vitvitskiy + +Permission is hereby granted, free of charge, to any person obtaining a copy of this +software and associated documentation files (the "Software"), to deal in the Software +without restriction, including without limitation the rights to use, copy, modify, +merge, publish, distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice shall be included in all copies or +substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, +INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR +PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE +FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE +OR OTHER DEALINGS IN THE SOFTWARE. +*/ +package com.googlecode.mp4parser.h264.model; + +import com.googlecode.mp4parser.h264.read.CAVLCReader; +import com.googlecode.mp4parser.h264.write.CAVLCWriter; + +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; + +/** + * Sequence Parameter Set structure of h264 bitstream + * <p/> + * capable to serialize and deserialize with CAVLC bitstream + * + * @author Stanislav Vitvitskiy + */ +public class SeqParameterSet extends BitstreamElement { + public int pic_order_cnt_type; + public boolean field_pic_flag; + public boolean delta_pic_order_always_zero_flag; + public boolean weighted_pred_flag; + public int weighted_bipred_idc; + public boolean entropy_coding_mode_flag; + public boolean mb_adaptive_frame_field_flag; + public boolean direct_8x8_inference_flag; + public ChromaFormat chroma_format_idc; + public int log2_max_frame_num_minus4; + public int log2_max_pic_order_cnt_lsb_minus4; + public int pic_height_in_map_units_minus1; + public int pic_width_in_mbs_minus1; + public int bit_depth_luma_minus8; + public int bit_depth_chroma_minus8; + public boolean qpprime_y_zero_transform_bypass_flag; + public int profile_idc; + public boolean constraint_set_0_flag; + public boolean constraint_set_1_flag; + public boolean constraint_set_2_flag; + public boolean constraint_set_3_flag; + public int level_idc; + public int seq_parameter_set_id; + public boolean residual_color_transform_flag; + public int offset_for_non_ref_pic; + public int offset_for_top_to_bottom_field; + public int num_ref_frames; + public boolean gaps_in_frame_num_value_allowed_flag; + public boolean frame_mbs_only_flag; + public boolean frame_cropping_flag; + public int frame_crop_left_offset; + public int frame_crop_right_offset; + public int frame_crop_top_offset; + public int frame_crop_bottom_offset; + public int[] offsetForRefFrame; + public VUIParameters vuiParams; + public ScalingMatrix scalingMatrix; + public int num_ref_frames_in_pic_order_cnt_cycle; + + public static SeqParameterSet read(InputStream is) throws IOException { + CAVLCReader reader = new CAVLCReader(is); + SeqParameterSet sps = new SeqParameterSet(); + + sps.profile_idc = (int) reader.readNBit(8, "SPS: profile_idc"); + sps.constraint_set_0_flag = reader + .readBool("SPS: constraint_set_0_flag"); + sps.constraint_set_1_flag = reader + .readBool("SPS: constraint_set_1_flag"); + sps.constraint_set_2_flag = reader + .readBool("SPS: constraint_set_2_flag"); + sps.constraint_set_3_flag = reader + .readBool("SPS: constraint_set_3_flag"); + reader.readNBit(4, "SPS: reserved_zero_4bits"); + sps.level_idc = (int) reader.readNBit(8, "SPS: level_idc"); + sps.seq_parameter_set_id = reader.readUE("SPS: seq_parameter_set_id"); + + if (sps.profile_idc == 100 || sps.profile_idc == 110 + || sps.profile_idc == 122 || sps.profile_idc == 144) { + sps.chroma_format_idc = ChromaFormat.fromId(reader + .readUE("SPS: chroma_format_idc")); + if (sps.chroma_format_idc == ChromaFormat.YUV_444) { + sps.residual_color_transform_flag = reader + .readBool("SPS: residual_color_transform_flag"); + } + sps.bit_depth_luma_minus8 = reader + .readUE("SPS: bit_depth_luma_minus8"); + sps.bit_depth_chroma_minus8 = reader + .readUE("SPS: bit_depth_chroma_minus8"); + sps.qpprime_y_zero_transform_bypass_flag = reader + .readBool("SPS: qpprime_y_zero_transform_bypass_flag"); + boolean seqScalingMatrixPresent = reader + .readBool("SPS: seq_scaling_matrix_present_lag"); + if (seqScalingMatrixPresent) { + readScalingListMatrix(reader, sps); + } + } else { + sps.chroma_format_idc = ChromaFormat.YUV_420; + } + sps.log2_max_frame_num_minus4 = reader + .readUE("SPS: log2_max_frame_num_minus4"); + sps.pic_order_cnt_type = reader.readUE("SPS: pic_order_cnt_type"); + if (sps.pic_order_cnt_type == 0) { + sps.log2_max_pic_order_cnt_lsb_minus4 = reader + .readUE("SPS: log2_max_pic_order_cnt_lsb_minus4"); + } else if (sps.pic_order_cnt_type == 1) { + sps.delta_pic_order_always_zero_flag = reader + .readBool("SPS: delta_pic_order_always_zero_flag"); + sps.offset_for_non_ref_pic = reader + .readSE("SPS: offset_for_non_ref_pic"); + sps.offset_for_top_to_bottom_field = reader + .readSE("SPS: offset_for_top_to_bottom_field"); + sps.num_ref_frames_in_pic_order_cnt_cycle = reader + .readUE("SPS: num_ref_frames_in_pic_order_cnt_cycle"); + sps.offsetForRefFrame = new int[sps.num_ref_frames_in_pic_order_cnt_cycle]; + for (int i = 0; i < sps.num_ref_frames_in_pic_order_cnt_cycle; i++) { + sps.offsetForRefFrame[i] = reader + .readSE("SPS: offsetForRefFrame [" + i + "]"); + } + } + sps.num_ref_frames = reader.readUE("SPS: num_ref_frames"); + sps.gaps_in_frame_num_value_allowed_flag = reader + .readBool("SPS: gaps_in_frame_num_value_allowed_flag"); + sps.pic_width_in_mbs_minus1 = reader + .readUE("SPS: pic_width_in_mbs_minus1"); + sps.pic_height_in_map_units_minus1 = reader + .readUE("SPS: pic_height_in_map_units_minus1"); + sps.frame_mbs_only_flag = reader.readBool("SPS: frame_mbs_only_flag"); + if (!sps.frame_mbs_only_flag) { + sps.mb_adaptive_frame_field_flag = reader + .readBool("SPS: mb_adaptive_frame_field_flag"); + } + sps.direct_8x8_inference_flag = reader + .readBool("SPS: direct_8x8_inference_flag"); + sps.frame_cropping_flag = reader.readBool("SPS: frame_cropping_flag"); + if (sps.frame_cropping_flag) { + sps.frame_crop_left_offset = reader + .readUE("SPS: frame_crop_left_offset"); + sps.frame_crop_right_offset = reader + .readUE("SPS: frame_crop_right_offset"); + sps.frame_crop_top_offset = reader + .readUE("SPS: frame_crop_top_offset"); + sps.frame_crop_bottom_offset = reader + .readUE("SPS: frame_crop_bottom_offset"); + } + boolean vui_parameters_present_flag = reader + .readBool("SPS: vui_parameters_present_flag"); + if (vui_parameters_present_flag) + sps.vuiParams = ReadVUIParameters(reader); + + reader.readTrailingBits(); + + return sps; + } + + private static void readScalingListMatrix(CAVLCReader reader, + SeqParameterSet sps) throws IOException { + sps.scalingMatrix = new ScalingMatrix(); + for (int i = 0; i < 8; i++) { + boolean seqScalingListPresentFlag = reader + .readBool("SPS: seqScalingListPresentFlag"); + if (seqScalingListPresentFlag) { + sps.scalingMatrix.ScalingList4x4 = new ScalingList[8]; + sps.scalingMatrix.ScalingList8x8 = new ScalingList[8]; + if (i < 6) { + sps.scalingMatrix.ScalingList4x4[i] = ScalingList.read( + reader, 16); + } else { + sps.scalingMatrix.ScalingList8x8[i - 6] = ScalingList.read( + reader, 64); + } + } + } + } + + private static VUIParameters ReadVUIParameters(CAVLCReader reader) + throws IOException { + VUIParameters vuip = new VUIParameters(); + vuip.aspect_ratio_info_present_flag = reader + .readBool("VUI: aspect_ratio_info_present_flag"); + if (vuip.aspect_ratio_info_present_flag) { + vuip.aspect_ratio = AspectRatio.fromValue((int) reader.readNBit(8, + "VUI: aspect_ratio")); + if (vuip.aspect_ratio == AspectRatio.Extended_SAR) { + vuip.sar_width = (int) reader.readNBit(16, "VUI: sar_width"); + vuip.sar_height = (int) reader.readNBit(16, "VUI: sar_height"); + } + } + vuip.overscan_info_present_flag = reader + .readBool("VUI: overscan_info_present_flag"); + if (vuip.overscan_info_present_flag) { + vuip.overscan_appropriate_flag = reader + .readBool("VUI: overscan_appropriate_flag"); + } + vuip.video_signal_type_present_flag = reader + .readBool("VUI: video_signal_type_present_flag"); + if (vuip.video_signal_type_present_flag) { + vuip.video_format = (int) reader.readNBit(3, "VUI: video_format"); + vuip.video_full_range_flag = reader + .readBool("VUI: video_full_range_flag"); + vuip.colour_description_present_flag = reader + .readBool("VUI: colour_description_present_flag"); + if (vuip.colour_description_present_flag) { + vuip.colour_primaries = (int) reader.readNBit(8, + "VUI: colour_primaries"); + vuip.transfer_characteristics = (int) reader.readNBit(8, + "VUI: transfer_characteristics"); + vuip.matrix_coefficients = (int) reader.readNBit(8, + "VUI: matrix_coefficients"); + } + } + vuip.chroma_loc_info_present_flag = reader + .readBool("VUI: chroma_loc_info_present_flag"); + if (vuip.chroma_loc_info_present_flag) { + vuip.chroma_sample_loc_type_top_field = reader + .readUE("VUI chroma_sample_loc_type_top_field"); + vuip.chroma_sample_loc_type_bottom_field = reader + .readUE("VUI chroma_sample_loc_type_bottom_field"); + } + vuip.timing_info_present_flag = reader + .readBool("VUI: timing_info_present_flag"); + if (vuip.timing_info_present_flag) { + vuip.num_units_in_tick = (int) reader.readNBit(32, + "VUI: num_units_in_tick"); + vuip.time_scale = (int) reader.readNBit(32, "VUI: time_scale"); + vuip.fixed_frame_rate_flag = reader + .readBool("VUI: fixed_frame_rate_flag"); + } + boolean nal_hrd_parameters_present_flag = reader + .readBool("VUI: nal_hrd_parameters_present_flag"); + if (nal_hrd_parameters_present_flag) + vuip.nalHRDParams = readHRDParameters(reader); + boolean vcl_hrd_parameters_present_flag = reader + .readBool("VUI: vcl_hrd_parameters_present_flag"); + if (vcl_hrd_parameters_present_flag) + vuip.vclHRDParams = readHRDParameters(reader); + if (nal_hrd_parameters_present_flag || vcl_hrd_parameters_present_flag) { + vuip.low_delay_hrd_flag = reader + .readBool("VUI: low_delay_hrd_flag"); + } + vuip.pic_struct_present_flag = reader + .readBool("VUI: pic_struct_present_flag"); + boolean bitstream_restriction_flag = reader + .readBool("VUI: bitstream_restriction_flag"); + if (bitstream_restriction_flag) { + vuip.bitstreamRestriction = new VUIParameters.BitstreamRestriction(); + vuip.bitstreamRestriction.motion_vectors_over_pic_boundaries_flag = reader + .readBool("VUI: motion_vectors_over_pic_boundaries_flag"); + vuip.bitstreamRestriction.max_bytes_per_pic_denom = reader + .readUE("VUI max_bytes_per_pic_denom"); + vuip.bitstreamRestriction.max_bits_per_mb_denom = reader + .readUE("VUI max_bits_per_mb_denom"); + vuip.bitstreamRestriction.log2_max_mv_length_horizontal = reader + .readUE("VUI log2_max_mv_length_horizontal"); + vuip.bitstreamRestriction.log2_max_mv_length_vertical = reader + .readUE("VUI log2_max_mv_length_vertical"); + vuip.bitstreamRestriction.num_reorder_frames = reader + .readUE("VUI num_reorder_frames"); + vuip.bitstreamRestriction.max_dec_frame_buffering = reader + .readUE("VUI max_dec_frame_buffering"); + } + + return vuip; + } + + private static HRDParameters readHRDParameters(CAVLCReader reader) + throws IOException { + HRDParameters hrd = new HRDParameters(); + hrd.cpb_cnt_minus1 = reader.readUE("SPS: cpb_cnt_minus1"); + hrd.bit_rate_scale = (int) reader.readNBit(4, "HRD: bit_rate_scale"); + hrd.cpb_size_scale = (int) reader.readNBit(4, "HRD: cpb_size_scale"); + hrd.bit_rate_value_minus1 = new int[hrd.cpb_cnt_minus1 + 1]; + hrd.cpb_size_value_minus1 = new int[hrd.cpb_cnt_minus1 + 1]; + hrd.cbr_flag = new boolean[hrd.cpb_cnt_minus1 + 1]; + + for (int SchedSelIdx = 0; SchedSelIdx <= hrd.cpb_cnt_minus1; SchedSelIdx++) { + hrd.bit_rate_value_minus1[SchedSelIdx] = reader + .readUE("HRD: bit_rate_value_minus1"); + hrd.cpb_size_value_minus1[SchedSelIdx] = reader + .readUE("HRD: cpb_size_value_minus1"); + hrd.cbr_flag[SchedSelIdx] = reader.readBool("HRD: cbr_flag"); + } + hrd.initial_cpb_removal_delay_length_minus1 = (int) reader.readNBit(5, + "HRD: initial_cpb_removal_delay_length_minus1"); + hrd.cpb_removal_delay_length_minus1 = (int) reader.readNBit(5, + "HRD: cpb_removal_delay_length_minus1"); + hrd.dpb_output_delay_length_minus1 = (int) reader.readNBit(5, + "HRD: dpb_output_delay_length_minus1"); + hrd.time_offset_length = (int) reader.readNBit(5, + "HRD: time_offset_length"); + return hrd; + } + + public void write(OutputStream out) throws IOException { + CAVLCWriter writer = new CAVLCWriter(out); + + writer.writeNBit(profile_idc, 8, "SPS: profile_idc"); + writer.writeBool(constraint_set_0_flag, "SPS: constraint_set_0_flag"); + writer.writeBool(constraint_set_1_flag, "SPS: constraint_set_1_flag"); + writer.writeBool(constraint_set_2_flag, "SPS: constraint_set_2_flag"); + writer.writeBool(constraint_set_3_flag, "SPS: constraint_set_3_flag"); + writer.writeNBit(0, 4, "SPS: reserved"); + writer.writeNBit(level_idc, 8, "SPS: level_idc"); + writer.writeUE(seq_parameter_set_id, "SPS: seq_parameter_set_id"); + + if (profile_idc == 100 || profile_idc == 110 || profile_idc == 122 + || profile_idc == 144) { + writer.writeUE(chroma_format_idc.getId(), "SPS: chroma_format_idc"); + if (chroma_format_idc == ChromaFormat.YUV_444) { + writer.writeBool(residual_color_transform_flag, + "SPS: residual_color_transform_flag"); + } + writer.writeUE(bit_depth_luma_minus8, "SPS: "); + writer.writeUE(bit_depth_chroma_minus8, "SPS: "); + writer.writeBool(qpprime_y_zero_transform_bypass_flag, + "SPS: qpprime_y_zero_transform_bypass_flag"); + writer.writeBool(scalingMatrix != null, "SPS: "); + if (scalingMatrix != null) { + for (int i = 0; i < 8; i++) { + if (i < 6) { + writer.writeBool( + scalingMatrix.ScalingList4x4[i] != null, + "SPS: "); + if (scalingMatrix.ScalingList4x4[i] != null) { + scalingMatrix.ScalingList4x4[i].write(writer); + } + } else { + writer.writeBool( + scalingMatrix.ScalingList8x8[i - 6] != null, + "SPS: "); + if (scalingMatrix.ScalingList8x8[i - 6] != null) { + scalingMatrix.ScalingList8x8[i - 6].write(writer); + } + } + } + } + } + writer.writeUE(log2_max_frame_num_minus4, + "SPS: log2_max_frame_num_minus4"); + writer.writeUE(pic_order_cnt_type, "SPS: pic_order_cnt_type"); + if (pic_order_cnt_type == 0) { + writer.writeUE(log2_max_pic_order_cnt_lsb_minus4, + "SPS: log2_max_pic_order_cnt_lsb_minus4"); + } else if (pic_order_cnt_type == 1) { + writer.writeBool(delta_pic_order_always_zero_flag, + "SPS: delta_pic_order_always_zero_flag"); + writer.writeSE(offset_for_non_ref_pic, + "SPS: offset_for_non_ref_pic"); + writer.writeSE(offset_for_top_to_bottom_field, + "SPS: offset_for_top_to_bottom_field"); + writer.writeUE(offsetForRefFrame.length, "SPS: "); + for (int i = 0; i < offsetForRefFrame.length; i++) + writer.writeSE(offsetForRefFrame[i], "SPS: "); + } + writer.writeUE(num_ref_frames, "SPS: num_ref_frames"); + writer.writeBool(gaps_in_frame_num_value_allowed_flag, + "SPS: gaps_in_frame_num_value_allowed_flag"); + writer.writeUE(pic_width_in_mbs_minus1, "SPS: pic_width_in_mbs_minus1"); + writer.writeUE(pic_height_in_map_units_minus1, + "SPS: pic_height_in_map_units_minus1"); + writer.writeBool(frame_mbs_only_flag, "SPS: frame_mbs_only_flag"); + if (!frame_mbs_only_flag) { + writer.writeBool(mb_adaptive_frame_field_flag, + "SPS: mb_adaptive_frame_field_flag"); + } + writer.writeBool(direct_8x8_inference_flag, + "SPS: direct_8x8_inference_flag"); + writer.writeBool(frame_cropping_flag, "SPS: frame_cropping_flag"); + if (frame_cropping_flag) { + writer.writeUE(frame_crop_left_offset, + "SPS: frame_crop_left_offset"); + writer.writeUE(frame_crop_right_offset, + "SPS: frame_crop_right_offset"); + writer.writeUE(frame_crop_top_offset, "SPS: frame_crop_top_offset"); + writer.writeUE(frame_crop_bottom_offset, + "SPS: frame_crop_bottom_offset"); + } + writer.writeBool(vuiParams != null, "SPS: "); + if (vuiParams != null) + writeVUIParameters(vuiParams, writer); + + writer.writeTrailingBits(); + } + + private void writeVUIParameters(VUIParameters vuip, CAVLCWriter writer) + throws IOException { + writer.writeBool(vuip.aspect_ratio_info_present_flag, + "VUI: aspect_ratio_info_present_flag"); + if (vuip.aspect_ratio_info_present_flag) { + writer.writeNBit(vuip.aspect_ratio.getValue(), 8, + "VUI: aspect_ratio"); + if (vuip.aspect_ratio == AspectRatio.Extended_SAR) { + writer.writeNBit(vuip.sar_width, 16, "VUI: sar_width"); + writer.writeNBit(vuip.sar_height, 16, "VUI: sar_height"); + } + } + writer.writeBool(vuip.overscan_info_present_flag, + "VUI: overscan_info_present_flag"); + if (vuip.overscan_info_present_flag) { + writer.writeBool(vuip.overscan_appropriate_flag, + "VUI: overscan_appropriate_flag"); + } + writer.writeBool(vuip.video_signal_type_present_flag, + "VUI: video_signal_type_present_flag"); + if (vuip.video_signal_type_present_flag) { + writer.writeNBit(vuip.video_format, 3, "VUI: video_format"); + writer.writeBool(vuip.video_full_range_flag, + "VUI: video_full_range_flag"); + writer.writeBool(vuip.colour_description_present_flag, + "VUI: colour_description_present_flag"); + if (vuip.colour_description_present_flag) { + writer.writeNBit(vuip.colour_primaries, 8, + "VUI: colour_primaries"); + writer.writeNBit(vuip.transfer_characteristics, 8, + "VUI: transfer_characteristics"); + writer.writeNBit(vuip.matrix_coefficients, 8, + "VUI: matrix_coefficients"); + } + } + writer.writeBool(vuip.chroma_loc_info_present_flag, + "VUI: chroma_loc_info_present_flag"); + if (vuip.chroma_loc_info_present_flag) { + writer.writeUE(vuip.chroma_sample_loc_type_top_field, + "VUI: chroma_sample_loc_type_top_field"); + writer.writeUE(vuip.chroma_sample_loc_type_bottom_field, + "VUI: chroma_sample_loc_type_bottom_field"); + } + writer.writeBool(vuip.timing_info_present_flag, + "VUI: timing_info_present_flag"); + if (vuip.timing_info_present_flag) { + writer.writeNBit(vuip.num_units_in_tick, 32, + "VUI: num_units_in_tick"); + writer.writeNBit(vuip.time_scale, 32, "VUI: time_scale"); + writer.writeBool(vuip.fixed_frame_rate_flag, + "VUI: fixed_frame_rate_flag"); + } + writer.writeBool(vuip.nalHRDParams != null, "VUI: "); + if (vuip.nalHRDParams != null) { + writeHRDParameters(vuip.nalHRDParams, writer); + } + writer.writeBool(vuip.vclHRDParams != null, "VUI: "); + if (vuip.vclHRDParams != null) { + writeHRDParameters(vuip.vclHRDParams, writer); + } + + if (vuip.nalHRDParams != null || vuip.vclHRDParams != null) { + writer + .writeBool(vuip.low_delay_hrd_flag, + "VUI: low_delay_hrd_flag"); + } + writer.writeBool(vuip.pic_struct_present_flag, + "VUI: pic_struct_present_flag"); + writer.writeBool(vuip.bitstreamRestriction != null, "VUI: "); + if (vuip.bitstreamRestriction != null) { + writer + .writeBool( + vuip.bitstreamRestriction.motion_vectors_over_pic_boundaries_flag, + "VUI: motion_vectors_over_pic_boundaries_flag"); + writer.writeUE(vuip.bitstreamRestriction.max_bytes_per_pic_denom, + "VUI: max_bytes_per_pic_denom"); + writer.writeUE(vuip.bitstreamRestriction.max_bits_per_mb_denom, + "VUI: max_bits_per_mb_denom"); + writer.writeUE( + vuip.bitstreamRestriction.log2_max_mv_length_horizontal, + "VUI: log2_max_mv_length_horizontal"); + writer.writeUE( + vuip.bitstreamRestriction.log2_max_mv_length_vertical, + "VUI: log2_max_mv_length_vertical"); + writer.writeUE(vuip.bitstreamRestriction.num_reorder_frames, + "VUI: num_reorder_frames"); + writer.writeUE(vuip.bitstreamRestriction.max_dec_frame_buffering, + "VUI: max_dec_frame_buffering"); + } + + } + + private void writeHRDParameters(HRDParameters hrd, CAVLCWriter writer) + throws IOException { + writer.writeUE(hrd.cpb_cnt_minus1, "HRD: cpb_cnt_minus1"); + writer.writeNBit(hrd.bit_rate_scale, 4, "HRD: bit_rate_scale"); + writer.writeNBit(hrd.cpb_size_scale, 4, "HRD: cpb_size_scale"); + + for (int SchedSelIdx = 0; SchedSelIdx <= hrd.cpb_cnt_minus1; SchedSelIdx++) { + writer.writeUE(hrd.bit_rate_value_minus1[SchedSelIdx], "HRD: "); + writer.writeUE(hrd.cpb_size_value_minus1[SchedSelIdx], "HRD: "); + writer.writeBool(hrd.cbr_flag[SchedSelIdx], "HRD: "); + } + writer.writeNBit(hrd.initial_cpb_removal_delay_length_minus1, 5, + "HRD: initial_cpb_removal_delay_length_minus1"); + writer.writeNBit(hrd.cpb_removal_delay_length_minus1, 5, + "HRD: cpb_removal_delay_length_minus1"); + writer.writeNBit(hrd.dpb_output_delay_length_minus1, 5, + "HRD: dpb_output_delay_length_minus1"); + writer.writeNBit(hrd.time_offset_length, 5, "HRD: time_offset_length"); + } + + @Override + public String toString() { + return "SeqParameterSet{ " + + "\n pic_order_cnt_type=" + pic_order_cnt_type + + ", \n field_pic_flag=" + field_pic_flag + + ", \n delta_pic_order_always_zero_flag=" + delta_pic_order_always_zero_flag + + ", \n weighted_pred_flag=" + weighted_pred_flag + + ", \n weighted_bipred_idc=" + weighted_bipred_idc + + ", \n entropy_coding_mode_flag=" + entropy_coding_mode_flag + + ", \n mb_adaptive_frame_field_flag=" + mb_adaptive_frame_field_flag + + ", \n direct_8x8_inference_flag=" + direct_8x8_inference_flag + + ", \n chroma_format_idc=" + chroma_format_idc + + ", \n log2_max_frame_num_minus4=" + log2_max_frame_num_minus4 + + ", \n log2_max_pic_order_cnt_lsb_minus4=" + log2_max_pic_order_cnt_lsb_minus4 + + ", \n pic_height_in_map_units_minus1=" + pic_height_in_map_units_minus1 + + ", \n pic_width_in_mbs_minus1=" + pic_width_in_mbs_minus1 + + ", \n bit_depth_luma_minus8=" + bit_depth_luma_minus8 + + ", \n bit_depth_chroma_minus8=" + bit_depth_chroma_minus8 + + ", \n qpprime_y_zero_transform_bypass_flag=" + qpprime_y_zero_transform_bypass_flag + + ", \n profile_idc=" + profile_idc + + ", \n constraint_set_0_flag=" + constraint_set_0_flag + + ", \n constraint_set_1_flag=" + constraint_set_1_flag + + ", \n constraint_set_2_flag=" + constraint_set_2_flag + + ", \n constraint_set_3_flag=" + constraint_set_3_flag + + ", \n level_idc=" + level_idc + + ", \n seq_parameter_set_id=" + seq_parameter_set_id + + ", \n residual_color_transform_flag=" + residual_color_transform_flag + + ", \n offset_for_non_ref_pic=" + offset_for_non_ref_pic + + ", \n offset_for_top_to_bottom_field=" + offset_for_top_to_bottom_field + + ", \n num_ref_frames=" + num_ref_frames + + ", \n gaps_in_frame_num_value_allowed_flag=" + gaps_in_frame_num_value_allowed_flag + + ", \n frame_mbs_only_flag=" + frame_mbs_only_flag + + ", \n frame_cropping_flag=" + frame_cropping_flag + + ", \n frame_crop_left_offset=" + frame_crop_left_offset + + ", \n frame_crop_right_offset=" + frame_crop_right_offset + + ", \n frame_crop_top_offset=" + frame_crop_top_offset + + ", \n frame_crop_bottom_offset=" + frame_crop_bottom_offset + + ", \n offsetForRefFrame=" + offsetForRefFrame + + ", \n vuiParams=" + vuiParams + + ", \n scalingMatrix=" + scalingMatrix + + ", \n num_ref_frames_in_pic_order_cnt_cycle=" + num_ref_frames_in_pic_order_cnt_cycle + + '}'; + } +}
\ No newline at end of file diff --git a/isoparser/src/main/java/com/googlecode/mp4parser/h264/model/VUIParameters.java b/isoparser/src/main/java/com/googlecode/mp4parser/h264/model/VUIParameters.java new file mode 100644 index 0000000..eec7880 --- /dev/null +++ b/isoparser/src/main/java/com/googlecode/mp4parser/h264/model/VUIParameters.java @@ -0,0 +1,94 @@ +/* +Copyright (c) 2011 Stanislav Vitvitskiy + +Permission is hereby granted, free of charge, to any person obtaining a copy of this +software and associated documentation files (the "Software"), to deal in the Software +without restriction, including without limitation the rights to use, copy, modify, +merge, publish, distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice shall be included in all copies or +substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, +INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR +PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE +FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE +OR OTHER DEALINGS IN THE SOFTWARE. +*/ +package com.googlecode.mp4parser.h264.model; + +public class VUIParameters { + + public static class BitstreamRestriction { + + public boolean motion_vectors_over_pic_boundaries_flag; + public int max_bytes_per_pic_denom; + public int max_bits_per_mb_denom; + public int log2_max_mv_length_horizontal; + public int log2_max_mv_length_vertical; + public int num_reorder_frames; + public int max_dec_frame_buffering; + + } + + public boolean aspect_ratio_info_present_flag; + public int sar_width; + public int sar_height; + public boolean overscan_info_present_flag; + public boolean overscan_appropriate_flag; + public boolean video_signal_type_present_flag; + public int video_format; + public boolean video_full_range_flag; + public boolean colour_description_present_flag; + public int colour_primaries; + public int transfer_characteristics; + public int matrix_coefficients; + public boolean chroma_loc_info_present_flag; + public int chroma_sample_loc_type_top_field; + public int chroma_sample_loc_type_bottom_field; + public boolean timing_info_present_flag; + public int num_units_in_tick; + public int time_scale; + public boolean fixed_frame_rate_flag; + public boolean low_delay_hrd_flag; + public boolean pic_struct_present_flag; + public HRDParameters nalHRDParams; + public HRDParameters vclHRDParams; + + public BitstreamRestriction bitstreamRestriction; + public AspectRatio aspect_ratio; + + @Override + public String toString() { + return "VUIParameters{" + "\n" + + "aspect_ratio_info_present_flag=" + aspect_ratio_info_present_flag + "\n" + + ", sar_width=" + sar_width + "\n" + + ", sar_height=" + sar_height + "\n" + + ", overscan_info_present_flag=" + overscan_info_present_flag + "\n" + + ", overscan_appropriate_flag=" + overscan_appropriate_flag + "\n" + + ", video_signal_type_present_flag=" + video_signal_type_present_flag + "\n" + + ", video_format=" + video_format + "\n" + + ", video_full_range_flag=" + video_full_range_flag + "\n" + + ", colour_description_present_flag=" + colour_description_present_flag + "\n" + + ", colour_primaries=" + colour_primaries + "\n" + + ", transfer_characteristics=" + transfer_characteristics + "\n" + + ", matrix_coefficients=" + matrix_coefficients + "\n" + + ", chroma_loc_info_present_flag=" + chroma_loc_info_present_flag + "\n" + + ", chroma_sample_loc_type_top_field=" + chroma_sample_loc_type_top_field + "\n" + + ", chroma_sample_loc_type_bottom_field=" + chroma_sample_loc_type_bottom_field + "\n" + + ", timing_info_present_flag=" + timing_info_present_flag + "\n" + + ", num_units_in_tick=" + num_units_in_tick + "\n" + + ", time_scale=" + time_scale + "\n" + + ", fixed_frame_rate_flag=" + fixed_frame_rate_flag + "\n" + + ", low_delay_hrd_flag=" + low_delay_hrd_flag + "\n" + + ", pic_struct_present_flag=" + pic_struct_present_flag + "\n" + + ", nalHRDParams=" + nalHRDParams + "\n" + + ", vclHRDParams=" + vclHRDParams + "\n" + + ", bitstreamRestriction=" + bitstreamRestriction + "\n" + + ", aspect_ratio=" + aspect_ratio + "\n" + + '}'; + } +} diff --git a/isoparser/src/main/java/com/googlecode/mp4parser/h264/read/.svn/all-wcprops b/isoparser/src/main/java/com/googlecode/mp4parser/h264/read/.svn/all-wcprops new file mode 100644 index 0000000..39f268a --- /dev/null +++ b/isoparser/src/main/java/com/googlecode/mp4parser/h264/read/.svn/all-wcprops @@ -0,0 +1,17 @@ +K 25 +svn:wc:ra_dav:version-url +V 82 +/svn/!svn/ver/377/trunk/isoparser/src/main/java/com/googlecode/mp4parser/h264/read +END +CAVLCReader.java +K 25 +svn:wc:ra_dav:version-url +V 99 +/svn/!svn/ver/377/trunk/isoparser/src/main/java/com/googlecode/mp4parser/h264/read/CAVLCReader.java +END +BitstreamReader.java +K 25 +svn:wc:ra_dav:version-url +V 103 +/svn/!svn/ver/377/trunk/isoparser/src/main/java/com/googlecode/mp4parser/h264/read/BitstreamReader.java +END diff --git a/isoparser/src/main/java/com/googlecode/mp4parser/h264/read/.svn/entries b/isoparser/src/main/java/com/googlecode/mp4parser/h264/read/.svn/entries new file mode 100644 index 0000000..f0111dc --- /dev/null +++ b/isoparser/src/main/java/com/googlecode/mp4parser/h264/read/.svn/entries @@ -0,0 +1,96 @@ +10 + +dir +778 +http://mp4parser.googlecode.com/svn/trunk/isoparser/src/main/java/com/googlecode/mp4parser/h264/read +http://mp4parser.googlecode.com/svn + + + +2012-03-05T23:28:24.666173Z +377 +Sebastian.Annies@gmail.com + + + + + + + + + + + + + + +7decde4b-c250-0410-a0da-51896bc88be6 + +CAVLCReader.java +file + + + + +2012-09-14T17:27:51.457232Z +bcd623b178982adc4723a481ed9ee8c8 +2012-03-05T23:28:24.666173Z +377 +Sebastian.Annies@gmail.com + + + + + + + + + + + + + + + + + + + + + +5069 + +BitstreamReader.java +file + + + + +2012-09-14T17:27:51.457232Z +0a82a1920e98d55c972bc7e536bfb158 +2012-03-05T23:28:24.666173Z +377 +Sebastian.Annies@gmail.com + + + + + + + + + + + + + + + + + + + + + +4982 + diff --git a/isoparser/src/main/java/com/googlecode/mp4parser/h264/read/.svn/text-base/BitstreamReader.java.svn-base b/isoparser/src/main/java/com/googlecode/mp4parser/h264/read/.svn/text-base/BitstreamReader.java.svn-base new file mode 100644 index 0000000..816af6a --- /dev/null +++ b/isoparser/src/main/java/com/googlecode/mp4parser/h264/read/.svn/text-base/BitstreamReader.java.svn-base @@ -0,0 +1,194 @@ +/* +Copyright (c) 2011 Stanislav Vitvitskiy + +Permission is hereby granted, free of charge, to any person obtaining a copy of this +software and associated documentation files (the "Software"), to deal in the Software +without restriction, including without limitation the rights to use, copy, modify, +merge, publish, distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice shall be included in all copies or +substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, +INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR +PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE +FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE +OR OTHER DEALINGS IN THE SOFTWARE. +*/ +package com.googlecode.mp4parser.h264.read; + +import com.googlecode.mp4parser.h264.CharCache; + +import java.io.IOException; +import java.io.InputStream; + +/** + * A dummy implementation of H264 RBSP reading + * + * @author Stanislav Vitvitskiy + */ +public class BitstreamReader { + private InputStream is; + private int curByte; + private int nextByte; + int nBit; + protected static int bitsRead; + + protected CharCache debugBits = new CharCache(50); + + public BitstreamReader(InputStream is) throws IOException { + this.is = is; + curByte = is.read(); + nextByte = is.read(); + } + + /* + * (non-Javadoc) + * + * @see ua.org.jplayer.javcodec.h264.RBSPInputStream#read1Bit() + */ + public int read1Bit() throws IOException { + if (nBit == 8) { + advance(); + if (curByte == -1) { + return -1; + } + } + int res = (curByte >> (7 - nBit)) & 1; + nBit++; + + debugBits.append(res == 0 ? '0' : '1'); + ++bitsRead; + + return res; + } + + /* + * (non-Javadoc) + * + * @see ua.org.jplayer.javcodec.h264.RBSPInputStream#readNBit(int) + */ + public long readNBit(int n) throws IOException { + if (n > 64) + throw new IllegalArgumentException("Can not readByte more then 64 bit"); + + long val = 0; + + for (int i = 0; i < n; i++) { + val <<= 1; + val |= read1Bit(); + } + + return val; + } + + private void advance() throws IOException { + curByte = nextByte; + nextByte = is.read(); + nBit = 0; + } + + /* + * (non-Javadoc) + * + * @see ua.org.jplayer.javcodec.h264.RBSPInputStream#readByte() + */ + public int readByte() throws IOException { + if (nBit > 0) { + advance(); + } + + int res = curByte; + + advance(); + + return res; + } + + /* + * (non-Javadoc) + * + * @see ua.org.jplayer.javcodec.h264.RBSPInputStream#moreRBSPData() + */ + public boolean moreRBSPData() throws IOException { + if (nBit == 8) { + advance(); + } + int tail = 1 << (8 - nBit - 1); + int mask = ((tail << 1) - 1); + boolean hasTail = (curByte & mask) == tail; + + return !(curByte == -1 || (nextByte == -1 && hasTail)); + } + + public long getBitPosition() { + return (bitsRead * 8 + (nBit % 8)); + } + + /* + * (non-Javadoc) + * + * @see ua.org.jplayer.javcodec.h264.RBSPInputStream#readRemainingByte() + */ + public long readRemainingByte() throws IOException { + return readNBit(8 - nBit); + } + + /* + * (non-Javadoc) + * + * @see ua.org.jplayer.javcodec.h264.RBSPInputStream#next_bits(int) + */ + public int peakNextBits(int n) throws IOException { + if (n > 8) + throw new IllegalArgumentException("N should be less then 8"); + if (nBit == 8) { + advance(); + if (curByte == -1) { + return -1; + } + } + int[] bits = new int[16 - nBit]; + + int cnt = 0; + for (int i = nBit; i < 8; i++) { + bits[cnt++] = (curByte >> (7 - i)) & 0x1; + } + + for (int i = 0; i < 8; i++) { + bits[cnt++] = (nextByte >> (7 - i)) & 0x1; + } + + int result = 0; + for (int i = 0; i < n; i++) { + result <<= 1; + result |= bits[i]; + } + + return result; + } + + /* + * (non-Javadoc) + * + * @see ua.org.jplayer.javcodec.h264.RBSPInputStream#byte_aligned() + */ + public boolean isByteAligned() { + return (nBit % 8) == 0; + } + + /* + * (non-Javadoc) + * + * @see ua.org.jplayer.javcodec.h264.RBSPInputStream#close() + */ + public void close() throws IOException { + } + + public int getCurBit() { + return nBit; + } +}
\ No newline at end of file diff --git a/isoparser/src/main/java/com/googlecode/mp4parser/h264/read/.svn/text-base/CAVLCReader.java.svn-base b/isoparser/src/main/java/com/googlecode/mp4parser/h264/read/.svn/text-base/CAVLCReader.java.svn-base new file mode 100644 index 0000000..07c7f71 --- /dev/null +++ b/isoparser/src/main/java/com/googlecode/mp4parser/h264/read/.svn/text-base/CAVLCReader.java.svn-base @@ -0,0 +1,185 @@ +/* +Copyright (c) 2011 Stanislav Vitvitskiy + +Permission is hereby granted, free of charge, to any person obtaining a copy of this +software and associated documentation files (the "Software"), to deal in the Software +without restriction, including without limitation the rights to use, copy, modify, +merge, publish, distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice shall be included in all copies or +substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, +INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR +PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE +FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE +OR OTHER DEALINGS IN THE SOFTWARE. +*/ +package com.googlecode.mp4parser.h264.read; + + +import com.googlecode.mp4parser.h264.BTree; + +import java.io.IOException; +import java.io.InputStream; + +import static com.googlecode.mp4parser.h264.Debug.println; + + +public class CAVLCReader extends BitstreamReader { + + public CAVLCReader(InputStream is) throws IOException { + super(is); + } + + public long readNBit(int n, String message) throws IOException { + long val = readNBit(n); + + trace(message, String.valueOf(val)); + + return val; + } + + /** + * Read unsigned exp-golomb code + * + * @return + * @throws java.io.IOException + * @throws java.io.IOException + */ + private int readUE() throws IOException { + int cnt = 0; + while (read1Bit() == 0) + cnt++; + + int res = 0; + if (cnt > 0) { + long val = readNBit(cnt); + + res = (int) ((1 << cnt) - 1 + val); + } + + return res; + } + + /* + * (non-Javadoc) + * + * @see + * ua.org.jplayer.javcodec.h264.H264BitInputStream#readUE(java.lang.String) + */ + public int readUE(String message) throws IOException { + int res = readUE(); + + trace(message, String.valueOf(res)); + + return res; + } + + public int readSE(String message) throws IOException { + int val = readUE(); + + int sign = ((val & 0x1) << 1) - 1; + val = ((val >> 1) + (val & 0x1)) * sign; + + trace(message, String.valueOf(val)); + + return val; + } + + public boolean readBool(String message) throws IOException { + + boolean res = read1Bit() == 0 ? false : true; + + trace(message, res ? "1" : "0"); + + return res; + } + + public int readU(int i, String string) throws IOException { + return (int) readNBit(i, string); + } + + public byte[] read(int payloadSize) throws IOException { + byte[] result = new byte[payloadSize]; + for (int i = 0; i < payloadSize; i++) { + result[i] = (byte) readByte(); + } + return result; + } + + public boolean readAE() { + // TODO: do it!! + throw new UnsupportedOperationException("Stan"); + } + + public int readTE(int max) throws IOException { + if (max > 1) + return readUE(); + return ~read1Bit() & 0x1; + } + + public int readAEI() { + // TODO: do it!! + throw new UnsupportedOperationException("Stan"); + } + + public int readME(String string) throws IOException { + return readUE(string); + } + + public Object readCE(BTree bt, String message) throws IOException { + while (true) { + int bit = read1Bit(); + bt = bt.down(bit); + if (bt == null) { + throw new RuntimeException("Illegal code"); + } + Object i = bt.getValue(); + if (i != null) { + trace(message, i.toString()); + return i; + } + } + } + + public int readZeroBitCount(String message) throws IOException { + int count = 0; + while (read1Bit() == 0) + count++; + + trace(message, String.valueOf(count)); + + return count; + } + + public void readTrailingBits() throws IOException { + read1Bit(); + readRemainingByte(); + } + + private void trace(String message, String val) { + StringBuilder traceBuilder = new StringBuilder(); + int spaces; + String pos = String.valueOf(bitsRead - debugBits.length()); + spaces = 8 - pos.length(); + + traceBuilder.append("@" + pos); + + for (int i = 0; i < spaces; i++) + traceBuilder.append(' '); + + traceBuilder.append(message); + spaces = 100 - traceBuilder.length() - debugBits.length(); + for (int i = 0; i < spaces; i++) + traceBuilder.append(' '); + traceBuilder.append(debugBits); + traceBuilder.append(" (" + val + ")"); + debugBits.clear(); + + println(traceBuilder.toString()); + } +}
\ No newline at end of file diff --git a/isoparser/src/main/java/com/googlecode/mp4parser/h264/read/BitstreamReader.java b/isoparser/src/main/java/com/googlecode/mp4parser/h264/read/BitstreamReader.java new file mode 100644 index 0000000..816af6a --- /dev/null +++ b/isoparser/src/main/java/com/googlecode/mp4parser/h264/read/BitstreamReader.java @@ -0,0 +1,194 @@ +/* +Copyright (c) 2011 Stanislav Vitvitskiy + +Permission is hereby granted, free of charge, to any person obtaining a copy of this +software and associated documentation files (the "Software"), to deal in the Software +without restriction, including without limitation the rights to use, copy, modify, +merge, publish, distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice shall be included in all copies or +substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, +INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR +PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE +FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE +OR OTHER DEALINGS IN THE SOFTWARE. +*/ +package com.googlecode.mp4parser.h264.read; + +import com.googlecode.mp4parser.h264.CharCache; + +import java.io.IOException; +import java.io.InputStream; + +/** + * A dummy implementation of H264 RBSP reading + * + * @author Stanislav Vitvitskiy + */ +public class BitstreamReader { + private InputStream is; + private int curByte; + private int nextByte; + int nBit; + protected static int bitsRead; + + protected CharCache debugBits = new CharCache(50); + + public BitstreamReader(InputStream is) throws IOException { + this.is = is; + curByte = is.read(); + nextByte = is.read(); + } + + /* + * (non-Javadoc) + * + * @see ua.org.jplayer.javcodec.h264.RBSPInputStream#read1Bit() + */ + public int read1Bit() throws IOException { + if (nBit == 8) { + advance(); + if (curByte == -1) { + return -1; + } + } + int res = (curByte >> (7 - nBit)) & 1; + nBit++; + + debugBits.append(res == 0 ? '0' : '1'); + ++bitsRead; + + return res; + } + + /* + * (non-Javadoc) + * + * @see ua.org.jplayer.javcodec.h264.RBSPInputStream#readNBit(int) + */ + public long readNBit(int n) throws IOException { + if (n > 64) + throw new IllegalArgumentException("Can not readByte more then 64 bit"); + + long val = 0; + + for (int i = 0; i < n; i++) { + val <<= 1; + val |= read1Bit(); + } + + return val; + } + + private void advance() throws IOException { + curByte = nextByte; + nextByte = is.read(); + nBit = 0; + } + + /* + * (non-Javadoc) + * + * @see ua.org.jplayer.javcodec.h264.RBSPInputStream#readByte() + */ + public int readByte() throws IOException { + if (nBit > 0) { + advance(); + } + + int res = curByte; + + advance(); + + return res; + } + + /* + * (non-Javadoc) + * + * @see ua.org.jplayer.javcodec.h264.RBSPInputStream#moreRBSPData() + */ + public boolean moreRBSPData() throws IOException { + if (nBit == 8) { + advance(); + } + int tail = 1 << (8 - nBit - 1); + int mask = ((tail << 1) - 1); + boolean hasTail = (curByte & mask) == tail; + + return !(curByte == -1 || (nextByte == -1 && hasTail)); + } + + public long getBitPosition() { + return (bitsRead * 8 + (nBit % 8)); + } + + /* + * (non-Javadoc) + * + * @see ua.org.jplayer.javcodec.h264.RBSPInputStream#readRemainingByte() + */ + public long readRemainingByte() throws IOException { + return readNBit(8 - nBit); + } + + /* + * (non-Javadoc) + * + * @see ua.org.jplayer.javcodec.h264.RBSPInputStream#next_bits(int) + */ + public int peakNextBits(int n) throws IOException { + if (n > 8) + throw new IllegalArgumentException("N should be less then 8"); + if (nBit == 8) { + advance(); + if (curByte == -1) { + return -1; + } + } + int[] bits = new int[16 - nBit]; + + int cnt = 0; + for (int i = nBit; i < 8; i++) { + bits[cnt++] = (curByte >> (7 - i)) & 0x1; + } + + for (int i = 0; i < 8; i++) { + bits[cnt++] = (nextByte >> (7 - i)) & 0x1; + } + + int result = 0; + for (int i = 0; i < n; i++) { + result <<= 1; + result |= bits[i]; + } + + return result; + } + + /* + * (non-Javadoc) + * + * @see ua.org.jplayer.javcodec.h264.RBSPInputStream#byte_aligned() + */ + public boolean isByteAligned() { + return (nBit % 8) == 0; + } + + /* + * (non-Javadoc) + * + * @see ua.org.jplayer.javcodec.h264.RBSPInputStream#close() + */ + public void close() throws IOException { + } + + public int getCurBit() { + return nBit; + } +}
\ No newline at end of file diff --git a/isoparser/src/main/java/com/googlecode/mp4parser/h264/read/CAVLCReader.java b/isoparser/src/main/java/com/googlecode/mp4parser/h264/read/CAVLCReader.java new file mode 100644 index 0000000..07c7f71 --- /dev/null +++ b/isoparser/src/main/java/com/googlecode/mp4parser/h264/read/CAVLCReader.java @@ -0,0 +1,185 @@ +/* +Copyright (c) 2011 Stanislav Vitvitskiy + +Permission is hereby granted, free of charge, to any person obtaining a copy of this +software and associated documentation files (the "Software"), to deal in the Software +without restriction, including without limitation the rights to use, copy, modify, +merge, publish, distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice shall be included in all copies or +substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, +INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR +PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE +FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE +OR OTHER DEALINGS IN THE SOFTWARE. +*/ +package com.googlecode.mp4parser.h264.read; + + +import com.googlecode.mp4parser.h264.BTree; + +import java.io.IOException; +import java.io.InputStream; + +import static com.googlecode.mp4parser.h264.Debug.println; + + +public class CAVLCReader extends BitstreamReader { + + public CAVLCReader(InputStream is) throws IOException { + super(is); + } + + public long readNBit(int n, String message) throws IOException { + long val = readNBit(n); + + trace(message, String.valueOf(val)); + + return val; + } + + /** + * Read unsigned exp-golomb code + * + * @return + * @throws java.io.IOException + * @throws java.io.IOException + */ + private int readUE() throws IOException { + int cnt = 0; + while (read1Bit() == 0) + cnt++; + + int res = 0; + if (cnt > 0) { + long val = readNBit(cnt); + + res = (int) ((1 << cnt) - 1 + val); + } + + return res; + } + + /* + * (non-Javadoc) + * + * @see + * ua.org.jplayer.javcodec.h264.H264BitInputStream#readUE(java.lang.String) + */ + public int readUE(String message) throws IOException { + int res = readUE(); + + trace(message, String.valueOf(res)); + + return res; + } + + public int readSE(String message) throws IOException { + int val = readUE(); + + int sign = ((val & 0x1) << 1) - 1; + val = ((val >> 1) + (val & 0x1)) * sign; + + trace(message, String.valueOf(val)); + + return val; + } + + public boolean readBool(String message) throws IOException { + + boolean res = read1Bit() == 0 ? false : true; + + trace(message, res ? "1" : "0"); + + return res; + } + + public int readU(int i, String string) throws IOException { + return (int) readNBit(i, string); + } + + public byte[] read(int payloadSize) throws IOException { + byte[] result = new byte[payloadSize]; + for (int i = 0; i < payloadSize; i++) { + result[i] = (byte) readByte(); + } + return result; + } + + public boolean readAE() { + // TODO: do it!! + throw new UnsupportedOperationException("Stan"); + } + + public int readTE(int max) throws IOException { + if (max > 1) + return readUE(); + return ~read1Bit() & 0x1; + } + + public int readAEI() { + // TODO: do it!! + throw new UnsupportedOperationException("Stan"); + } + + public int readME(String string) throws IOException { + return readUE(string); + } + + public Object readCE(BTree bt, String message) throws IOException { + while (true) { + int bit = read1Bit(); + bt = bt.down(bit); + if (bt == null) { + throw new RuntimeException("Illegal code"); + } + Object i = bt.getValue(); + if (i != null) { + trace(message, i.toString()); + return i; + } + } + } + + public int readZeroBitCount(String message) throws IOException { + int count = 0; + while (read1Bit() == 0) + count++; + + trace(message, String.valueOf(count)); + + return count; + } + + public void readTrailingBits() throws IOException { + read1Bit(); + readRemainingByte(); + } + + private void trace(String message, String val) { + StringBuilder traceBuilder = new StringBuilder(); + int spaces; + String pos = String.valueOf(bitsRead - debugBits.length()); + spaces = 8 - pos.length(); + + traceBuilder.append("@" + pos); + + for (int i = 0; i < spaces; i++) + traceBuilder.append(' '); + + traceBuilder.append(message); + spaces = 100 - traceBuilder.length() - debugBits.length(); + for (int i = 0; i < spaces; i++) + traceBuilder.append(' '); + traceBuilder.append(debugBits); + traceBuilder.append(" (" + val + ")"); + debugBits.clear(); + + println(traceBuilder.toString()); + } +}
\ No newline at end of file diff --git a/isoparser/src/main/java/com/googlecode/mp4parser/h264/write/.svn/all-wcprops b/isoparser/src/main/java/com/googlecode/mp4parser/h264/write/.svn/all-wcprops new file mode 100644 index 0000000..eb9d014 --- /dev/null +++ b/isoparser/src/main/java/com/googlecode/mp4parser/h264/write/.svn/all-wcprops @@ -0,0 +1,17 @@ +K 25 +svn:wc:ra_dav:version-url +V 83 +/svn/!svn/ver/236/trunk/isoparser/src/main/java/com/googlecode/mp4parser/h264/write +END +CAVLCWriter.java +K 25 +svn:wc:ra_dav:version-url +V 100 +/svn/!svn/ver/236/trunk/isoparser/src/main/java/com/googlecode/mp4parser/h264/write/CAVLCWriter.java +END +BitstreamWriter.java +K 25 +svn:wc:ra_dav:version-url +V 104 +/svn/!svn/ver/236/trunk/isoparser/src/main/java/com/googlecode/mp4parser/h264/write/BitstreamWriter.java +END diff --git a/isoparser/src/main/java/com/googlecode/mp4parser/h264/write/.svn/entries b/isoparser/src/main/java/com/googlecode/mp4parser/h264/write/.svn/entries new file mode 100644 index 0000000..17c897c --- /dev/null +++ b/isoparser/src/main/java/com/googlecode/mp4parser/h264/write/.svn/entries @@ -0,0 +1,96 @@ +10 + +dir +778 +http://mp4parser.googlecode.com/svn/trunk/isoparser/src/main/java/com/googlecode/mp4parser/h264/write +http://mp4parser.googlecode.com/svn + + + +2011-09-20T18:03:23.375910Z +236 +Sebastian.Annies@gmail.com + + + + + + + + + + + + + + +7decde4b-c250-0410-a0da-51896bc88be6 + +CAVLCWriter.java +file + + + + +2012-09-14T17:27:51.397232Z +466f7fb1a81ac3195414706a32abdee2 +2011-09-20T18:03:23.375910Z +236 +Sebastian.Annies@gmail.com + + + + + + + + + + + + + + + + + + + + + +3214 + +BitstreamWriter.java +file + + + + +2012-09-14T17:27:51.397232Z +816b2b532d6ccee0eda214f86cde8ebc +2011-09-20T18:03:23.375910Z +236 +Sebastian.Annies@gmail.com + + + + + + + + + + + + + + + + + + + + + +3192 + diff --git a/isoparser/src/main/java/com/googlecode/mp4parser/h264/write/.svn/text-base/BitstreamWriter.java.svn-base b/isoparser/src/main/java/com/googlecode/mp4parser/h264/write/.svn/text-base/BitstreamWriter.java.svn-base new file mode 100644 index 0000000..b382400 --- /dev/null +++ b/isoparser/src/main/java/com/googlecode/mp4parser/h264/write/.svn/text-base/BitstreamWriter.java.svn-base @@ -0,0 +1,108 @@ +/* +Copyright (c) 2011 Stanislav Vitvitskiy + +Permission is hereby granted, free of charge, to any person obtaining a copy of this +software and associated documentation files (the "Software"), to deal in the Software +without restriction, including without limitation the rights to use, copy, modify, +merge, publish, distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice shall be included in all copies or +substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, +INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR +PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE +FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE +OR OTHER DEALINGS IN THE SOFTWARE. +*/ +package com.googlecode.mp4parser.h264.write; + +import com.googlecode.mp4parser.h264.Debug; + +import java.io.IOException; +import java.io.OutputStream; + +/** + * A dummy implementation of H264 RBSP output stream + * + * @author Stanislav Vitvitskiy + */ +public class BitstreamWriter { + + private final OutputStream os; + private int[] curByte = new int[8]; + private int curBit; + + public BitstreamWriter(OutputStream out) { + this.os = out; + } + + /* + * (non-Javadoc) + * + * @see ua.org.jplayer.javcodec.h264.H264BitOutputStream#flush() + */ + public void flush() throws IOException { + for (int i = curBit; i < 8; i++) { + curByte[i] = 0; + } + curBit = 0; + writeCurByte(); + } + + private void writeCurByte() throws IOException { + int toWrite = (curByte[0] << 7) | (curByte[1] << 6) | (curByte[2] << 5) + | (curByte[3] << 4) | (curByte[4] << 3) | (curByte[5] << 2) + | (curByte[6] << 1) | curByte[7]; + os.write(toWrite); + } + + /* + * (non-Javadoc) + * + * @see ua.org.jplayer.javcodec.h264.H264BitOutputStream#write1Bit(int) + */ + public void write1Bit(int value) throws IOException { + Debug.print(value); + if (curBit == 8) { + curBit = 0; + writeCurByte(); + } + curByte[curBit++] = value; + } + + /* + * (non-Javadoc) + * + * @see ua.org.jplayer.javcodec.h264.H264BitOutputStream#writeNBit(long, + * int) + */ + public void writeNBit(long value, int n) throws IOException { + for (int i = 0; i < n; i++) { + write1Bit((int) (value >> (n - i - 1)) & 0x1); + } + } + + /* + * (non-Javadoc) + * + * @see + * ua.org.jplayer.javcodec.h264.H264BitOutputStream#writeRemainingZero() + */ + public void writeRemainingZero() throws IOException { + writeNBit(0, 8 - curBit); + } + + /* + * (non-Javadoc) + * + * @see ua.org.jplayer.javcodec.h264.H264BitOutputStream#writeByte(int) + */ + public void writeByte(int b) throws IOException { + os.write(b); + + } +}
\ No newline at end of file diff --git a/isoparser/src/main/java/com/googlecode/mp4parser/h264/write/.svn/text-base/CAVLCWriter.java.svn-base b/isoparser/src/main/java/com/googlecode/mp4parser/h264/write/.svn/text-base/CAVLCWriter.java.svn-base new file mode 100644 index 0000000..c4e0026 --- /dev/null +++ b/isoparser/src/main/java/com/googlecode/mp4parser/h264/write/.svn/text-base/CAVLCWriter.java.svn-base @@ -0,0 +1,100 @@ +/* +Copyright (c) 2011 Stanislav Vitvitskiy + +Permission is hereby granted, free of charge, to any person obtaining a copy of this +software and associated documentation files (the "Software"), to deal in the Software +without restriction, including without limitation the rights to use, copy, modify, +merge, publish, distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice shall be included in all copies or +substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, +INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR +PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE +FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE +OR OTHER DEALINGS IN THE SOFTWARE. +*/ +package com.googlecode.mp4parser.h264.write; + +import com.googlecode.mp4parser.h264.Debug; + +import java.io.IOException; +import java.io.OutputStream; + + +/** + * A class responsible for outputting exp-Golumb values into binary stream + * + * @author Stanislav Vitvitskiy + */ +public class CAVLCWriter extends BitstreamWriter { + + public CAVLCWriter(OutputStream out) { + super(out); + } + + public void writeU(int value, int n, String string) throws IOException { + Debug.print(string + "\t"); + writeNBit(value, n); + Debug.println("\t" + value); + } + + public void writeUE(int value) throws IOException { + int bits = 0; + int cumul = 0; + for (int i = 0; i < 15; i++) { + if (value < cumul + (1 << i)) { + bits = i; + break; + } + cumul += (1 << i); + } + writeNBit(0, bits); + write1Bit(1); + writeNBit(value - cumul, bits); + } + + public void writeUE(int value, String string) throws IOException { + Debug.print(string + "\t"); + writeUE(value); + Debug.println("\t" + value); + } + + public void writeSE(int value, String string) throws IOException { + Debug.print(string + "\t"); + writeUE((value << 1) * (value < 0 ? -1 : 1) + (value > 0 ? 1 : 0)); + Debug.println("\t" + value); + } + + public void writeBool(boolean value, String string) throws IOException { + Debug.print(string + "\t"); + write1Bit(value ? 1 : 0); + Debug.println("\t" + value); + } + + public void writeU(int i, int n) throws IOException { + writeNBit(i, n); + } + + public void writeNBit(long value, int n, String string) throws IOException { + Debug.print(string + "\t"); + for (int i = 0; i < n; i++) { + write1Bit((int) (value >> (n - i - 1)) & 0x1); + } + Debug.println("\t" + value); + } + + public void writeTrailingBits() throws IOException { + write1Bit(1); + writeRemainingZero(); + flush(); + } + + public void writeSliceTrailingBits() { + throw new IllegalStateException("todo"); + } +}
\ No newline at end of file diff --git a/isoparser/src/main/java/com/googlecode/mp4parser/h264/write/BitstreamWriter.java b/isoparser/src/main/java/com/googlecode/mp4parser/h264/write/BitstreamWriter.java new file mode 100644 index 0000000..b382400 --- /dev/null +++ b/isoparser/src/main/java/com/googlecode/mp4parser/h264/write/BitstreamWriter.java @@ -0,0 +1,108 @@ +/* +Copyright (c) 2011 Stanislav Vitvitskiy + +Permission is hereby granted, free of charge, to any person obtaining a copy of this +software and associated documentation files (the "Software"), to deal in the Software +without restriction, including without limitation the rights to use, copy, modify, +merge, publish, distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice shall be included in all copies or +substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, +INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR +PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE +FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE +OR OTHER DEALINGS IN THE SOFTWARE. +*/ +package com.googlecode.mp4parser.h264.write; + +import com.googlecode.mp4parser.h264.Debug; + +import java.io.IOException; +import java.io.OutputStream; + +/** + * A dummy implementation of H264 RBSP output stream + * + * @author Stanislav Vitvitskiy + */ +public class BitstreamWriter { + + private final OutputStream os; + private int[] curByte = new int[8]; + private int curBit; + + public BitstreamWriter(OutputStream out) { + this.os = out; + } + + /* + * (non-Javadoc) + * + * @see ua.org.jplayer.javcodec.h264.H264BitOutputStream#flush() + */ + public void flush() throws IOException { + for (int i = curBit; i < 8; i++) { + curByte[i] = 0; + } + curBit = 0; + writeCurByte(); + } + + private void writeCurByte() throws IOException { + int toWrite = (curByte[0] << 7) | (curByte[1] << 6) | (curByte[2] << 5) + | (curByte[3] << 4) | (curByte[4] << 3) | (curByte[5] << 2) + | (curByte[6] << 1) | curByte[7]; + os.write(toWrite); + } + + /* + * (non-Javadoc) + * + * @see ua.org.jplayer.javcodec.h264.H264BitOutputStream#write1Bit(int) + */ + public void write1Bit(int value) throws IOException { + Debug.print(value); + if (curBit == 8) { + curBit = 0; + writeCurByte(); + } + curByte[curBit++] = value; + } + + /* + * (non-Javadoc) + * + * @see ua.org.jplayer.javcodec.h264.H264BitOutputStream#writeNBit(long, + * int) + */ + public void writeNBit(long value, int n) throws IOException { + for (int i = 0; i < n; i++) { + write1Bit((int) (value >> (n - i - 1)) & 0x1); + } + } + + /* + * (non-Javadoc) + * + * @see + * ua.org.jplayer.javcodec.h264.H264BitOutputStream#writeRemainingZero() + */ + public void writeRemainingZero() throws IOException { + writeNBit(0, 8 - curBit); + } + + /* + * (non-Javadoc) + * + * @see ua.org.jplayer.javcodec.h264.H264BitOutputStream#writeByte(int) + */ + public void writeByte(int b) throws IOException { + os.write(b); + + } +}
\ No newline at end of file diff --git a/isoparser/src/main/java/com/googlecode/mp4parser/h264/write/CAVLCWriter.java b/isoparser/src/main/java/com/googlecode/mp4parser/h264/write/CAVLCWriter.java new file mode 100644 index 0000000..c4e0026 --- /dev/null +++ b/isoparser/src/main/java/com/googlecode/mp4parser/h264/write/CAVLCWriter.java @@ -0,0 +1,100 @@ +/* +Copyright (c) 2011 Stanislav Vitvitskiy + +Permission is hereby granted, free of charge, to any person obtaining a copy of this +software and associated documentation files (the "Software"), to deal in the Software +without restriction, including without limitation the rights to use, copy, modify, +merge, publish, distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice shall be included in all copies or +substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, +INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR +PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE +FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE +OR OTHER DEALINGS IN THE SOFTWARE. +*/ +package com.googlecode.mp4parser.h264.write; + +import com.googlecode.mp4parser.h264.Debug; + +import java.io.IOException; +import java.io.OutputStream; + + +/** + * A class responsible for outputting exp-Golumb values into binary stream + * + * @author Stanislav Vitvitskiy + */ +public class CAVLCWriter extends BitstreamWriter { + + public CAVLCWriter(OutputStream out) { + super(out); + } + + public void writeU(int value, int n, String string) throws IOException { + Debug.print(string + "\t"); + writeNBit(value, n); + Debug.println("\t" + value); + } + + public void writeUE(int value) throws IOException { + int bits = 0; + int cumul = 0; + for (int i = 0; i < 15; i++) { + if (value < cumul + (1 << i)) { + bits = i; + break; + } + cumul += (1 << i); + } + writeNBit(0, bits); + write1Bit(1); + writeNBit(value - cumul, bits); + } + + public void writeUE(int value, String string) throws IOException { + Debug.print(string + "\t"); + writeUE(value); + Debug.println("\t" + value); + } + + public void writeSE(int value, String string) throws IOException { + Debug.print(string + "\t"); + writeUE((value << 1) * (value < 0 ? -1 : 1) + (value > 0 ? 1 : 0)); + Debug.println("\t" + value); + } + + public void writeBool(boolean value, String string) throws IOException { + Debug.print(string + "\t"); + write1Bit(value ? 1 : 0); + Debug.println("\t" + value); + } + + public void writeU(int i, int n) throws IOException { + writeNBit(i, n); + } + + public void writeNBit(long value, int n, String string) throws IOException { + Debug.print(string + "\t"); + for (int i = 0; i < n; i++) { + write1Bit((int) (value >> (n - i - 1)) & 0x1); + } + Debug.println("\t" + value); + } + + public void writeTrailingBits() throws IOException { + write1Bit(1); + writeRemainingZero(); + flush(); + } + + public void writeSliceTrailingBits() { + throw new IllegalStateException("todo"); + } +}
\ No newline at end of file |