Stream Video From Android Part 4 – Parse Boxes and SPS or PPS

Alright, your have the taste of blood in your mouth and you like it. Lets dive deeper and actually try parsing some data.

->source code here <-

In our android app we have saved the file and now we are passing it to our sdp maker. Ironically I do not actually use session description protocol. I just didn’t know it was not needed so I named this class incorrectly.

Our sdpmaker class uses a randomaccessfile to parse through the data by reading each byte and looking for box headers. Here is the start of the method where you can get the idea of how the whole class works.


public static byte[][] retreiveSPSPPS(File file) throws IOException, FileNotFoundException
{
    byte[] sps = new byte[0];                                 //we will find the bytes and read into these arrays then convert to the string values
    byte[] pps = new byte[0];
    byte[] prfix = new byte[6];
    byte[][] spspps;
    String[] spsppsString = new String[2];


    RandomAccessFile randomAccessFile;              //file type to allow searching file byte by byte
    long fileLength = 0;
    long position = 0;
    long moovPos = 0;

    byte[] holder = new byte[8];

                                                        //get the file we saved our little video too

       randomAccessFile = new RandomAccessFile(file, "r");
        fileLength = randomAccessFile.length();

                                                            // here we find the moov box within the mp4 file
    while(position < fileLength) {
        //read our current position and then advance to next position
        randomAccessFile.read(holder, 0, 8);
        position += 8;

        if (checkForBox(holder)) {
            String name = new String(holder, 4, 4);

            if (name.equals("moov")) {
                moovPos = position;
                Log.d(TAG, "retreiveSPSPPS: found moov box = " + name);
                break;
            }
        }

    }

Check out this picture again. Notice how the boxes are nested?  My code above isn’t optimized for any use case. But as you can see I start by finding the moov box and then search my way through each nested box to find the data i need.

Here you can see where I am extracting my sps. Read through the full code for all the details.

if (read[0] == 'g') {

                                        //ascii 'g' = hex 67  &lt;- we found the sps
    int length = bLength &amp; 0xff;        //blength is the length of the sps


    remaining = new byte[length];

    randomAccessFile.read(remaining, 0, length-1); //minus 1 because we already read the g

                                            //scoot everything down and add our g at the begining
    for (int i = length-1; i &gt; 0 ; i--) {

        remaining[i] = remaining[i-1];

    }

    remaining[0] = read[0];
    sps = remaining;

    String s = bytesToHex(remaining);
    Log.d(TAG, "retreiveSPSPPS: found sps: " + s + " length used: " + String.valueOf(length));

 

Once this is done we need to save this data in our app. As long as we don’t change the media recorder settings when we stream this sps and pps data will allow a decoder to decode it correctly.

On a side note I also saved a prefix byte[] but this turned out to be unnecessary. Stick with the sps and pps.

 

Leave a Reply

Your email address will not be published. Required fields are marked *