/* * 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 #include #include #include #include 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); }