티스토리 툴바



2009/05/19 05:26

Sample Code of The SVC NAL Header Parser

//This Code is a part of full source code and a modified from SJ Park's code by ES Ryu.
//H.264 SVC NAL Header is explained at "http://tools.ietf.org/html/draft-ietf-avt-rtp-svc-18" (RTP Payload Format for SVC Video draft-ietf-avt-rtp-svc-18.txt).


int extract_layers(FILE *infile) //I modified SJ Park(Korea University)'s code -by ES RYU-
{
    int temp, forb, nri, type;
    int reserved_one_bit, idr_flag, priority_id, no_inter_layer_pre_flag;
    int dependency_id, quality_id, temporal_id, use_ref_base_pic_flag;
    int discardable_flag, output_flag, reserved_three_2bits;
    int status;
    unsigned long int offset, nal_size, index;

    char *str, *typeText;

    nal_size = 4;
    status = 0;
    offset = 0;
    index = 0;
    str = "";
 
    while((temp = fgetc(infile)) != -1)
    {
        offset++;
        switch(status)
        {
            case 0:
            case 1:
            case 2:
                {
                    if (temp == 0x00) // NAL Header first 3 byte = "0x00 00 00"
                    {
                        status++;
                    }
                    else
                    {
                        status = 0;
                    }
                }
                break;

            case 3:
                {
                    if (temp == 0x01) // NAL Header 4th byte = '0x01'
                    {
                        if (offset != 4)
                        {
                            nal_size = offset - nal_size; //NAL Size
                            printf("Size = %ld \n\n", nal_size);
                            nal_size = offset;
                        }
                        status++;
                    }
                    else
                    {
                        status = 0;
                    }
                    break;
                }
            case 4: // 1st byte of NAL Header [F(1) NRI(2) Type(5)]
                {
                    forb = (temp & 0x80) >> 7;
                    nri = (temp & 0x60) >> 5;
                    type = temp & 0x1F;


                    switch (type)
                    {
                        case 1:
                            typeText = "CS non-IDR ";
                            break;
                        case 5:
                            typeText = "CS IDR     ";
                            break;
                        case 6:
                            typeText = "SEI        ";
                            break;
                        case 7 :
                            typeText = "SPS        ";
                            break;
                        case 8:
                            typeText = "PPS        ";
                            break;
                        case 14 :
                            typeText = "PREFIX RBSP";
                            break;
                        case 15:
                            typeText = "SUBSET RBSP";
                            break;
                        case 20 :
                            typeText = "CS S Ext   ";
                            break;
                        default:
                            typeText = "TYPE       ";
                            break;
                    }
                   
                    printf("No=%d, Offset=%d, F=%d, NRI=%d, Type=%s, ", index, offset - 5, forb, nri, typeText);
                    index++;

                    if (type == 20 || type == 14)
                    {
                        status++; // To Next byte
                    }
                    else
                    {
                        status = 0;
                    }
                    break;
                }
            case 5: //2nd byte of NAL Header [R(1) I(1) PRID(6)]
                {
                    reserved_one_bit = (temp & 0x80) >> 7;
                    idr_flag = (temp & 0x40) >> 6;
                    priority_id = (temp & 0x3F);

                    printf("R=%d, I=%d, PRID=%d, ", reserved_one_bit, idr_flag, priority_id);
                    status++;  //To next byte
                   
                    break;
                }
            case 6 : //3rd byte of NAL Header [N(1) DID(3) QID(4)]
                {
                    no_inter_layer_pre_flag = (temp & 0x80) >> 7;
                    dependency_id = (temp & 0x70) >> 4;
                    quality_id = (temp & 0x0F);

                    printf("N=%d, DID=%d, QID=%d ", no_inter_layer_pre_flag, dependency_id, quality_id);

                    status++; //To next byte
                    break;
                }
            case 7: //4th byte of NAL Header [TID(3) U(1) D(1) O(1) RR(2)]
                {
                    temporal_id = (temp & 0xE0) >> 5;
                    use_ref_base_pic_flag = (temp & 0x10) >> 4;
                    discardable_flag = (temp & 0x08) >> 3;
                    output_flag = (temp & 0x04) >> 2;
                    reserved_three_2bits = (temp & 0x03);
                 
                    printf("TID=%d, U=%d, D=%d, O=%d, RR=%d ", temporal_id, use_ref_base_pic_flag, discardable_flag, output_flag, reserved_three_2bits);

                    status = 0;  //to the 1st byte of header again
                    break;
                }
        } // end of switch
    } //end of while
    return 0;
}
저작자 표시 비영리 동일 조건 변경 허락
Trackback 0 Comment 0