blob: 38b6e1508b22171c30f4e93452df2644d5801248 [file] [log] [blame]
/*
* Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#include "../../source/BitstreamBuilder.h"
#include "../../source/BitstreamParser.h"
#include <assert.h>
#include <stdio.h>
#include <math.h>
#include <tchar.h>
#include <windows.h>
WebRtc_UWord32 BitRateBPS(WebRtc_UWord16 x )
{
return (x & 0x3fff) * WebRtc_UWord32(pow(10.0f,(2 + (x >> 14))));
}
WebRtc_UWord16 BitRateBPSInv(WebRtc_UWord32 x )
{
// 16383 0x3fff
// 1 638 300 exp 0
// 16 383 000 exp 1
// 163 830 000 exp 2
// 1 638 300 000 exp 3
const float exp = log10(float(x>>14)) - 2;
if(exp < 0.0)
{
return WebRtc_UWord16(x /100);
}else if(exp < 1.0)
{
return 0x4000 + WebRtc_UWord16(x /1000);
}else if(exp < 2.0)
{
return 0x8000 + WebRtc_UWord16(x /10000);
}else if(exp < 3.0)
{
return 0xC000 + WebRtc_UWord16(x /100000);
} else
{
assert(false);
return 0;
}
}
int _tmain(int argc, _TCHAR* argv[])
{
WebRtc_UWord8 dataBuffer[128];
BitstreamBuilder builder(dataBuffer, sizeof(dataBuffer));
// test 1 to 4 bits
builder.Add1Bit(1);
builder.Add1Bit(0);
builder.Add1Bit(1);
builder.Add2Bits(1);
builder.Add2Bits(2);
builder.Add2Bits(3);
builder.Add3Bits(1);
builder.Add3Bits(3);
builder.Add3Bits(7);
builder.Add4Bits(1);
builder.Add4Bits(5);
builder.Add4Bits(15);
assert(4 == builder.Length());
BitstreamParser parser(dataBuffer, sizeof(dataBuffer));
assert(1 == parser.Get1Bit());
assert(0 == parser.Get1Bit());
assert(1 == parser.Get1Bit());
assert(1 == parser.Get2Bits());
assert(2 == parser.Get2Bits());
assert(3 == parser.Get2Bits());
assert(1 == parser.Get3Bits());
assert(3 == parser.Get3Bits());
assert(7 == parser.Get3Bits());
assert(1 == parser.Get4Bits());
assert(5 == parser.Get4Bits());
assert(15 == parser.Get4Bits());
printf("Test of 1 to 4 bits done\n");
// test 5 to 7 bits
builder.Add5Bits(1);
builder.Add5Bits(15);
builder.Add5Bits(30);
builder.Add6Bits(1);
builder.Add6Bits(30);
builder.Add6Bits(60);
builder.Add7Bits(1);
builder.Add7Bits(60);
builder.Add7Bits(120);
assert(1 == parser.Get5Bits());
assert(15 == parser.Get5Bits());
assert(30 == parser.Get5Bits());
assert(1 == parser.Get6Bits());
assert(30 == parser.Get6Bits());
assert(60 == parser.Get6Bits());
assert(1 == parser.Get7Bits());
assert(60 == parser.Get7Bits());
assert(120 == parser.Get7Bits());
printf("Test of 5 to 7 bits done\n");
builder.Add8Bits(1);
builder.Add1Bit(1);
builder.Add8Bits(255);
builder.Add1Bit(0);
builder.Add8Bits(127);
builder.Add1Bit(1);
builder.Add8Bits(60);
builder.Add1Bit(0);
builder.Add8Bits(30);
builder.Add1Bit(1);
builder.Add8Bits(120);
builder.Add1Bit(0);
builder.Add8Bits(160);
builder.Add1Bit(1);
builder.Add8Bits(180);
assert(1 == parser.Get8Bits());
assert(1 == parser.Get1Bit());
assert(255 == parser.Get8Bits());
assert(0 == parser.Get1Bit());
assert(127 == parser.Get8Bits());
assert(1 == parser.Get1Bit());
assert(60 == parser.Get8Bits());
assert(0 == parser.Get1Bit());
assert(30 == parser.Get8Bits());
assert(1 == parser.Get1Bit());
assert(120 == parser.Get8Bits());
assert(0 == parser.Get1Bit());
assert(160 == parser.Get8Bits());
assert(1 == parser.Get1Bit());
assert(180 == parser.Get8Bits());
printf("Test of 8 bits done\n");
builder.Add16Bits(1);
builder.Add1Bit(1);
builder.Add16Bits(255);
builder.Add1Bit(0);
builder.Add16Bits(12756);
builder.Add1Bit(1);
builder.Add16Bits(60);
builder.Add1Bit(0);
builder.Add16Bits(30);
builder.Add1Bit(1);
builder.Add16Bits(30120);
builder.Add1Bit(0);
builder.Add16Bits(160);
builder.Add1Bit(1);
builder.Add16Bits(180);
assert(1 == parser.Get16Bits());
assert(1 == parser.Get1Bit());
assert(255 == parser.Get16Bits());
assert(0 == parser.Get1Bit());
assert(12756 == parser.Get16Bits());
assert(1 == parser.Get1Bit());
assert(60 == parser.Get16Bits());
assert(0 == parser.Get1Bit());
assert(30 == parser.Get16Bits());
assert(1 == parser.Get1Bit());
assert(30120 == parser.Get16Bits());
assert(0 == parser.Get1Bit());
assert(160 == parser.Get16Bits());
assert(1 == parser.Get1Bit());
assert(180 == parser.Get16Bits());
printf("Test of 16 bits done\n");
builder.Add24Bits(1);
builder.Add1Bit(1);
builder.Add24Bits(255);
builder.Add1Bit(0);
builder.Add24Bits(12756);
builder.Add1Bit(1);
builder.Add24Bits(60);
builder.Add1Bit(0);
builder.Add24Bits(303333);
builder.Add1Bit(1);
builder.Add24Bits(30120);
builder.Add1Bit(0);
builder.Add24Bits(160);
builder.Add1Bit(1);
builder.Add24Bits(8018018);
assert(1 == parser.Get24Bits());
assert(1 == parser.Get1Bit());
assert(255 == parser.Get24Bits());
assert(0 == parser.Get1Bit());
assert(12756 == parser.Get24Bits());
assert(1 == parser.Get1Bit());
assert(60 == parser.Get24Bits());
assert(0 == parser.Get1Bit());
assert(303333 == parser.Get24Bits());
assert(1 == parser.Get1Bit());
assert(30120 == parser.Get24Bits());
assert(0 == parser.Get1Bit());
assert(160 == parser.Get24Bits());
assert(1 == parser.Get1Bit());
assert(8018018 == parser.Get24Bits());
printf("Test of 24 bits done\n");
builder.Add32Bits(1);
builder.Add1Bit(1);
builder.Add32Bits(255);
builder.Add1Bit(0);
builder.Add32Bits(12756);
builder.Add1Bit(1);
builder.Add32Bits(60);
builder.Add1Bit(0);
builder.Add32Bits(303333);
builder.Add1Bit(1);
builder.Add32Bits(3012000012);
builder.Add1Bit(0);
builder.Add32Bits(1601601601);
builder.Add1Bit(1);
builder.Add32Bits(8018018);
assert(1 == parser.Get32Bits());
assert(1 == parser.Get1Bit());
assert(255 == parser.Get32Bits());
assert(0 == parser.Get1Bit());
assert(12756 == parser.Get32Bits());
assert(1 == parser.Get1Bit());
assert(60 == parser.Get32Bits());
assert(0 == parser.Get1Bit());
assert(303333 == parser.Get32Bits());
assert(1 == parser.Get1Bit());
assert(3012000012 == parser.Get32Bits());
assert(0 == parser.Get1Bit());
assert(1601601601 == parser.Get32Bits());
assert(1 == parser.Get1Bit());
assert(8018018 == parser.Get32Bits());
printf("Test of 32 bits done\n");
builder.AddUE(1);
builder.AddUE(4);
builder.AddUE(9809706);
builder.AddUE(2);
builder.AddUE(15);
builder.AddUE(16998);
assert( 106 == builder.Length());
assert(1 == parser.GetUE());
assert(4 == parser.GetUE());
assert(9809706 == parser.GetUE());
assert(2 == parser.GetUE());
assert(15 == parser.GetUE());
assert(16998 == parser.GetUE());
printf("Test UE bits done\n");
BitstreamBuilder builderScalabilityInfo(dataBuffer, sizeof(dataBuffer));
BitstreamParser parserScalabilityInfo(dataBuffer, sizeof(dataBuffer));
const WebRtc_UWord8 numberOfLayers = 4;
const WebRtc_UWord8 layerId[numberOfLayers] = {0,1,2,3};
const WebRtc_UWord8 priorityId[numberOfLayers] = {0,1,2,3};
const WebRtc_UWord8 discardableId[numberOfLayers] = {0,1,1,1};
const WebRtc_UWord8 dependencyId[numberOfLayers]= {0,1,1,1};
const WebRtc_UWord8 qualityId[numberOfLayers]= {0,0,0,1};
const WebRtc_UWord8 temporalId[numberOfLayers]= {0,0,1,1};
const WebRtc_UWord16 avgBitrate[numberOfLayers]= {BitRateBPSInv(100000),
BitRateBPSInv(200000),
BitRateBPSInv(400000),
BitRateBPSInv(800000)};
// todo which one is the sum?
const WebRtc_UWord16 maxBitrateLayer[numberOfLayers]= {BitRateBPSInv(150000),
BitRateBPSInv(300000),
BitRateBPSInv(500000),
BitRateBPSInv(900000)};
const WebRtc_UWord16 maxBitrateLayerRepresentation[numberOfLayers] = {BitRateBPSInv(150000),
BitRateBPSInv(450000),
BitRateBPSInv(950000),
BitRateBPSInv(1850000)};
assert( 16300 == BitRateBPS(BitRateBPSInv(16383)));
assert( 163800 == BitRateBPS(BitRateBPSInv(163830)));
assert( 1638300 == BitRateBPS(BitRateBPSInv(1638300)));
assert( 1638000 == BitRateBPS(BitRateBPSInv(1638400)));
assert( 18500 == BitRateBPS(BitRateBPSInv(18500)));
assert( 185000 == BitRateBPS(BitRateBPSInv(185000)));
assert( 1850000 == BitRateBPS(BitRateBPSInv(1850000)));
assert( 18500000 == BitRateBPS(BitRateBPSInv(18500000)));
assert( 185000000 == BitRateBPS(BitRateBPSInv(185000000)));
const WebRtc_UWord16 maxBitrareCalcWindow[numberOfLayers] = {200, 200,200,200};// in 1/100 of second
builderScalabilityInfo.Add1Bit(0); // temporal_id_nesting_flag
builderScalabilityInfo.Add1Bit(0); // priority_layer_info_present_flag
builderScalabilityInfo.Add1Bit(0); // priority_id_setting_flag
builderScalabilityInfo.AddUE(numberOfLayers-1);
for(int i = 0; i<= numberOfLayers-1; i++)
{
builderScalabilityInfo.AddUE(layerId[i]);
builderScalabilityInfo.Add6Bits(priorityId[i]);
builderScalabilityInfo.Add1Bit(discardableId[i]);
builderScalabilityInfo.Add3Bits(dependencyId[i]);
builderScalabilityInfo.Add4Bits(qualityId[i]);
builderScalabilityInfo.Add3Bits(temporalId[i]);
builderScalabilityInfo.Add1Bit(0);
builderScalabilityInfo.Add1Bit(0);
builderScalabilityInfo.Add1Bit(0);
builderScalabilityInfo.Add1Bit(0);
builderScalabilityInfo.Add1Bit(1); // bitrate_info_present_flag
builderScalabilityInfo.Add1Bit(0);
builderScalabilityInfo.Add1Bit(0);
builderScalabilityInfo.Add1Bit(0);
builderScalabilityInfo.Add1Bit(0);
builderScalabilityInfo.Add1Bit(0);
builderScalabilityInfo.Add1Bit(0);
builderScalabilityInfo.Add1Bit(0);
builderScalabilityInfo.Add1Bit(0);
builderScalabilityInfo.Add16Bits(avgBitrate[i]);
builderScalabilityInfo.Add16Bits(maxBitrateLayer[i]);
builderScalabilityInfo.Add16Bits(maxBitrateLayerRepresentation[i]);
builderScalabilityInfo.Add16Bits(maxBitrareCalcWindow[i]);
builderScalabilityInfo.AddUE(0); // layer_dependency_info_src_layer_id_delta
builderScalabilityInfo.AddUE(0); // parameter_sets_info_src_layer_id_delta
}
printf("Test builderScalabilityInfo done\n");
// Scalability Info parser
parserScalabilityInfo.Get1Bit(); // not used in futher parsing
const WebRtc_UWord8 priority_layer_info_present = parserScalabilityInfo.Get1Bit();
const WebRtc_UWord8 priority_id_setting_flag = parserScalabilityInfo.Get1Bit();
WebRtc_UWord32 numberOfLayersMinusOne = parserScalabilityInfo.GetUE();
for(WebRtc_UWord32 j = 0; j<= numberOfLayersMinusOne; j++)
{
parserScalabilityInfo.GetUE();
parserScalabilityInfo.Get6Bits();
parserScalabilityInfo.Get1Bit();
parserScalabilityInfo.Get3Bits();
parserScalabilityInfo.Get4Bits();
parserScalabilityInfo.Get3Bits();
const WebRtc_UWord8 sub_pic_layer_flag = parserScalabilityInfo.Get1Bit();
const WebRtc_UWord8 sub_region_layer_flag = parserScalabilityInfo.Get1Bit();
const WebRtc_UWord8 iroi_division_info_present_flag = parserScalabilityInfo.Get1Bit();
const WebRtc_UWord8 profile_level_info_present_flag = parserScalabilityInfo.Get1Bit();
const WebRtc_UWord8 bitrate_info_present_flag = parserScalabilityInfo.Get1Bit();
const WebRtc_UWord8 frm_rate_info_present_flag = parserScalabilityInfo.Get1Bit();
const WebRtc_UWord8 frm_size_info_present_flag = parserScalabilityInfo.Get1Bit();
const WebRtc_UWord8 layer_dependency_info_present_flag = parserScalabilityInfo.Get1Bit();
const WebRtc_UWord8 parameter_sets_info_present_flag = parserScalabilityInfo.Get1Bit();
const WebRtc_UWord8 bitstream_restriction_info_present_flag = parserScalabilityInfo.Get1Bit();
const WebRtc_UWord8 exact_inter_layer_pred_flag = parserScalabilityInfo.Get1Bit(); // not used in futher parsing
if(sub_pic_layer_flag || iroi_division_info_present_flag)
{
parserScalabilityInfo.Get1Bit();
}
const WebRtc_UWord8 layer_conversion_flag = parserScalabilityInfo.Get1Bit();
const WebRtc_UWord8 layer_output_flag = parserScalabilityInfo.Get1Bit(); // not used in futher parsing
if(profile_level_info_present_flag)
{
parserScalabilityInfo.Get24Bits();
}
if(bitrate_info_present_flag)
{
// this is what we want
assert(avgBitrate[j] == parserScalabilityInfo.Get16Bits());
assert(maxBitrateLayer[j] == parserScalabilityInfo.Get16Bits());
assert(maxBitrateLayerRepresentation[j] == parserScalabilityInfo.Get16Bits());
assert(maxBitrareCalcWindow[j] == parserScalabilityInfo.Get16Bits());
}else
{
assert(false);
}
if(frm_rate_info_present_flag)
{
parserScalabilityInfo.Get2Bits();
parserScalabilityInfo.Get16Bits();
}
if(frm_size_info_present_flag || iroi_division_info_present_flag)
{
parserScalabilityInfo.GetUE();
parserScalabilityInfo.GetUE();
}
if(sub_region_layer_flag)
{
parserScalabilityInfo.GetUE();
if(parserScalabilityInfo.Get1Bit())
{
parserScalabilityInfo.Get16Bits();
parserScalabilityInfo.Get16Bits();
parserScalabilityInfo.Get16Bits();
parserScalabilityInfo.Get16Bits();
}
}
if(sub_pic_layer_flag)
{
parserScalabilityInfo.GetUE();
}
if(iroi_division_info_present_flag)
{
if(parserScalabilityInfo.Get1Bit())
{
parserScalabilityInfo.GetUE();
parserScalabilityInfo.GetUE();
}else
{
const WebRtc_UWord32 numRoisMinusOne = parserScalabilityInfo.GetUE();
for(WebRtc_UWord32 k = 0; k <= numRoisMinusOne; k++)
{
parserScalabilityInfo.GetUE();
parserScalabilityInfo.GetUE();
parserScalabilityInfo.GetUE();
}
}
}
if(layer_dependency_info_present_flag)
{
const WebRtc_UWord32 numDirectlyDependentLayers = parserScalabilityInfo.GetUE();
for(WebRtc_UWord32 k = 0; k < numDirectlyDependentLayers; k++)
{
parserScalabilityInfo.GetUE();
}
} else
{
parserScalabilityInfo.GetUE();
}
if(parameter_sets_info_present_flag)
{
const WebRtc_UWord32 numSeqParameterSetMinusOne = parserScalabilityInfo.GetUE();
for(WebRtc_UWord32 k = 0; k <= numSeqParameterSetMinusOne; k++)
{
parserScalabilityInfo.GetUE();
}
const WebRtc_UWord32 numSubsetSeqParameterSetMinusOne = parserScalabilityInfo.GetUE();
for(WebRtc_UWord32 l = 0; l <= numSubsetSeqParameterSetMinusOne; l++)
{
parserScalabilityInfo.GetUE();
}
const WebRtc_UWord32 numPicParameterSetMinusOne = parserScalabilityInfo.GetUE();
for(WebRtc_UWord32 m = 0; m <= numPicParameterSetMinusOne; m++)
{
parserScalabilityInfo.GetUE();
}
}else
{
parserScalabilityInfo.GetUE();
}
if(bitstream_restriction_info_present_flag)
{
parserScalabilityInfo.Get1Bit();
parserScalabilityInfo.GetUE();
parserScalabilityInfo.GetUE();
parserScalabilityInfo.GetUE();
parserScalabilityInfo.GetUE();
parserScalabilityInfo.GetUE();
parserScalabilityInfo.GetUE();
}
if(layer_conversion_flag)
{
parserScalabilityInfo.GetUE();
for(WebRtc_UWord32 k = 0; k <2;k++)
{
if(parserScalabilityInfo.Get1Bit())
{
parserScalabilityInfo.Get24Bits();
parserScalabilityInfo.Get16Bits();
parserScalabilityInfo.Get16Bits();
}
}
}
}
if(priority_layer_info_present)
{
const WebRtc_UWord32 prNumDidMinusOne = parserScalabilityInfo.GetUE();
for(WebRtc_UWord32 k = 0; k <= prNumDidMinusOne;k++)
{
parserScalabilityInfo.Get3Bits();
const WebRtc_UWord32 prNumMinusOne = parserScalabilityInfo.GetUE();
for(WebRtc_UWord32 l = 0; l <= prNumMinusOne; l++)
{
parserScalabilityInfo.GetUE();
parserScalabilityInfo.Get24Bits();
parserScalabilityInfo.Get16Bits();
parserScalabilityInfo.Get16Bits();
}
}
}
if(priority_id_setting_flag)
{
WebRtc_UWord8 priorityIdSettingUri;
WebRtc_UWord32 priorityIdSettingUriIdx = 0;
do
{
priorityIdSettingUri = parserScalabilityInfo.Get8Bits();
} while (priorityIdSettingUri != 0);
}
printf("Test parserScalabilityInfo done\n");
printf("\nAPI test of parser for ScalabilityInfo done\n");
::Sleep(5000);
}