-1

I need to find the addresses where the width and height are stored, but the IUT version of the standard don't give a clear definition of the file format.

What I found so far... :

  • Both values are stored in "a QuickTime float". I couldn't find the format, but it seems it use two 16-bits integer: a signed one followed by an unsigned one.
  • Unlike many file format, there are no fixed position, so it is file specific. It depend on the TrackHeaderBox address.

What I desperatly need :

A clear canonical answer describing the places to find only those kind of information. I don't want answers only referring to third party libraries (unless they are written in proper JavaScript). Some pseudo C like structures can help.

Community
  • 1
  • 1
user2284570
  • 2,891
  • 3
  • 26
  • 74
  • From a question that was referred to in a comment on an answer to the question you referred to: [Fetching the dimensions of a H264Video stream](http://stackoverflow.com/questions/6394874/fetching-the-dimensions-of-a-h264video-stream/6477652#6477652) – GolezTrol Sep 28 '14 at 17:38

1 Answers1

1

There is no fixed position. You need to parse into the file. Please check this Java example.

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Arrays;
import java.util.List;


public class GetHeight {
    public static void main(String[] args) throws IOException {
        FileInputStream fis = new FileInputStream(new File(args[0]));

        GetHeight ps = new GetHeight();
        ps.find(fis);
    }

    byte[] lastTkhd;

    private void find(InputStream fis) throws IOException {

        while (fis.available() > 0) {
            byte[] header = new byte[8];
            fis.read(header);

            long size = readUint32(header, 0);
            String type = new String(header, 4, 4, "ISO-8859-1");
            if (containers.contains(type)) {
                find(fis);
            } else {
                if (type.equals("tkhd")) {
                    lastTkhd = new byte[(int) (size - 8)];
                    fis.read(lastTkhd);
                } else {
                    if (type.equals("hdlr")) {
                        byte[] hdlr = new byte[(int) (size - 8)];
                        fis.read(hdlr);
                        if (hdlr[8] == 0x76 && hdlr[9] == 0x69 && hdlr[10] == 0x64 && hdlr[11] == 0x65) {
                            System.out.println("Video Track Header identified");
                            System.out.println("width: " + readFixedPoint1616(lastTkhd, lastTkhd.length - 8));
                            System.out.println("height: " + readFixedPoint1616(lastTkhd, lastTkhd.length - 4));
                            System.exit(1);
                        }
                    } else {
                        fis.skip(size - 8);
                    }
                }
            }
        }
    }

    public static long readUint32(byte[] b, int s) {
        long result = 0;
        result |= ((b[s + 0] << 24) & 0xFF000000);
        result |= ((b[s + 1] << 16) & 0xFF0000);
        result |= ((b[s + 2] << 8) & 0xFF00);
        result |= ((b[s + 3]) & 0xFF);
        return result;
    }

    public static double readFixedPoint1616(byte[] b, int s) {
        return ((double) readUint32(b, s)) / 65536;
    }

    List<String> containers = Arrays.asList(
            "moov",
            "mdia",
            "trak"
    );
}
Sebastian Annies
  • 2,438
  • 1
  • 20
  • 38
  • Thanks, but do not confuse [Java and Javascript](http://stackoverflow.com/q/25838472/2284570) – user2284570 Sep 29 '14 at 09:10
  • 1
    I very well aware of the difference but as I'm a Java guy I've chosen a language not too far away and leave the translation to you. I got the impression that you are asking a bit too much here. Stackoverflow is not about someone else doing your job you are paid to do. – Sebastian Annies Sep 29 '14 at 12:05
  • Yes, I'm aware for StackOverflow,but this is something that can be formatted in few lines. The problem with JavaScript is there integers work similar as in python *(this like if you would always use `BigInteger`and with usual operators)*. There's no typed integers except if you do bit manipulation : then the integer is converted to a signed 32 bit one *(So it should be OK for most of the java program)*. There are also typed arrays which allow to use 16 and 8 bits integers as an array. ***But there is no way to get an equivalent of the `long`type : I can't see how to deal with that problem.*** – user2284570 Oct 02 '14 at 18:50
  • Just use a 32 signed integer. If it's negative throw an error. There are not many boxes that are larger. Alternative you could have a look at the integer and handle the special case of negative value: The negative value plus (2^32 + 1) is the actual uint32. You might then just skip to this position in multiple steps. – Sebastian Annies Oct 02 '14 at 22:05