Upgrade libopenapv to v0.1.11.3 am: e512872da8
Original change: https://android-review.googlesource.com/c/platform/external/libopenapv/+/3528750
Change-Id: I55d916594230070fe55b6f8e0d4572ba50fe05e1
Signed-off-by: Automerger Merge Worker <[email protected]>
diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml
index f7a0947..0d0e37e 100644
--- a/.github/workflows/build.yml
+++ b/.github/workflows/build.yml
@@ -65,7 +65,7 @@
- name: Build ARM
run: |
- cmake -DCMAKE_BUILD_TYPE=Release -S ${{github.workspace}} -B ${{github.workspace}}/build-arm -DCMAKE_C_COMPILER=aarch64-linux-gnu-gcc -DARM=TRUE -DCMAKE_SYSTEM_PROCESSOR=aarch64
+ cmake -S ${{github.workspace}} -B ${{github.workspace}}/build-arm -DCMAKE_TOOLCHAIN_FILE=${{github.workspace}}/arm64_toolchain.cmake -DCMAKE_BUILD_TYPE=Release
cmake --build ${{github.workspace}}/build-arm
test-linux:
diff --git a/.github/workflows/release_packages.yml b/.github/workflows/release_packages.yml
index 861497b..cb92d2f 100644
--- a/.github/workflows/release_packages.yml
+++ b/.github/workflows/release_packages.yml
@@ -57,7 +57,7 @@
- name: Build ARM
run: |
- cmake -DCMAKE_BUILD_TYPE=Release -S ${{github.workspace}} -B ${{github.workspace}}/build-arm -DCMAKE_C_COMPILER=aarch64-linux-gnu-gcc -DARM=TRUE -DCMAKE_SYSTEM_PROCESSOR=aarch64
+ cmake -S ${{github.workspace}} -B ${{github.workspace}}/build-arm -DCMAKE_TOOLCHAIN_FILE=${{github.workspace}}/arm64_toolchain.cmake -DCMAKE_BUILD_TYPE=Release
cmake --build ${{github.workspace}}/build-arm
cd ${{github.workspace}}/build-arm
cpack -C Release
@@ -67,8 +67,8 @@
with:
name: openapv-arm-${{github.event.release.tag_name}}
path: |
- ${{ github.workspace }}/build/*.deb
- ${{ github.workspace }}/build/*.md5
+ ${{ github.workspace }}/build-arm/*.deb
+ ${{ github.workspace }}/build-arm/*.md5
retention-days: 7
- name: Upload ARM assets to GitHub Release
@@ -76,7 +76,7 @@
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
- file: "build/*.deb; build/*.md5"
+ file: "build-arm/*.deb; build-arm/*.md5"
update_latest_release: true
draft: false
overwrite: true
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 92b1846..b86694e 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -198,10 +198,10 @@
set(CPACK_RESOURCE_FILE_README "${CMAKE_CURRENT_SOURCE_DIR}/README.md")
set(CPACK_PACKAGE_NAME "OpenAPV")
-set(CPACK_PACKAGE_VENDOR "OpenAPV")
-set(CPACK_PACKAGE_CONTACT "https://github.com/openapv")
-set(CPACK_PACKAGE_HOMEPAGE_URL "https://github.com/openapv/oapv/releases")
-set(CMAKE_PROJECT_HOMEPAGE_URL "https://github.com/openapv/oapv")
+set(CPACK_PACKAGE_VENDOR "AcademySoftwareFoundation")
+set(CPACK_PACKAGE_CONTACT "https://github.com/AcademySoftwareFoundation")
+set(CPACK_PACKAGE_HOMEPAGE_URL "https://github.com/AcademySoftwareFoundation/openapv/releases")
+set(CMAKE_PROJECT_HOMEPAGE_URL "https://github.com/AcademySoftwareFoundation/openapv")
set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "Open Advanced Professional Video Codec")
set(CPACK_PACKAGE_VERSION "${PROJECT_VERSION}")
set(CPACK_PACKAGE_VERSION_MAJOR "${PROJECT_VERSION_MAJOR}")
@@ -209,7 +209,9 @@
set(CPACK_PACKAGE_VERSION_PATCH "${PROJECT_VERSION_PATCH}")
set(CPACK_PACKAGE_CHECKSUM MD5)
-set(CPACK_DEBIAN_PACKAGE_MAINTAINER "OpenAPV")
+set(CPACK_DEBIAN_PACKAGE_MAINTAINER "AcademySoftwareFoundation")
+set(CPACK_DEBIAN_PACKAGE_SECTION "video")
+set(CPACK_DEBIAN_FILE_NAME "DEB-DEFAULT")
include(CPack)
diff --git a/METADATA b/METADATA
index c985b01..a0d5c2e 100644
--- a/METADATA
+++ b/METADATA
@@ -8,14 +8,14 @@
license_type: NOTICE
last_upgrade_date {
year: 2025
- month: 2
- day: 18
+ month: 3
+ day: 5
}
homepage: "https://github.com/openapv/openapv"
identifier {
type: "Git"
value: "https://github.com/openapv/openapv.git"
- version: "v0.1.11"
+ version: "v0.1.11.3"
primary_source: true
}
}
diff --git a/README.md b/README.md
index 8486a71..eb753b3 100644
--- a/README.md
+++ b/README.md
@@ -49,21 +49,21 @@
- mingw-w64
- mingw-w64-tools
-- Build Instructions PC
+- Build Instructions PC (Linux)
```
cmake -DCMAKE_BUILD_TYPE=Release -S . -B build
cmake --build build
```
-- Build Instructions ARM
+- Build Instructions ARM (Crosscompile)
```
- cmake -DCMAKE_BUILD_TYPE=Release -S . -B build-arm -DCMAKE_C_COMPILER=aarch64-linux-gnu-gcc -DARM=TRUE -DCMAKE_SYSTEM_PROCESSOR=aarch64
+ cmake -S . -B build-arm -DCMAKE_TOOLCHAIN_FILE=aarch64_toolchain.cmake -DCMAKE_BUILD_TYPE=Release
cmake --build build-arm
```
- Build Instructions Windows (Crosscompile)
```
- cmake -S . -B build-windows -DCMAKE_TOOLCHAIN_FILE=windows_x86_64_toolchain.cmake
+ cmake -S . -B build-windows -DCMAKE_TOOLCHAIN_FILE=windows_x86_64_toolchain.cmake -DCMAKE_BUILD_TYPE=Release
cmake --build build-windows
```
@@ -97,6 +97,18 @@
oapv_app_dec -i encoded.apv -o output.y4m
+## Utility
+
+### Graphical APV bitstream parser
+
+Pattern file of APV bitstream for [ImHex](https://github.com/WerWolv/ImHex) is provided [here](/util/apv.hexpat).
+1. Install [ImHex](https://github.com/WerWolv/ImHex) application
+2. Download [APV pattern file](/util/apv.hexpat)
+2. Open APV bitstream (\*.apv file) with ImHex
+3. Import the APV pattern file on Pattern editor view of ImHex and apply
+
+
+
## Testing
In build directory run ``ctest``
diff --git a/app/oapv_app_enc.c b/app/oapv_app_enc.c
index d3e2c8e..58fa94c 100644
--- a/app/oapv_app_enc.c
+++ b/app/oapv_app_enc.c
@@ -499,9 +499,9 @@
param->csp = vars->input_csp;
/* update level idc */
- double tmp_level = 0;
- sscanf(vars->level, "%lf", &tmp_level);
- param->level_idc = tmp_level * 30;
+ float tmp_level = 0;
+ sscanf(vars->level, "%f", &tmp_level);
+ param->level_idc = (int)((tmp_level * 30.0) + 0.5);
/* update band idc */
param->band_idc = vars->band;
diff --git a/arm64_toolchain.cmake b/arm64_toolchain.cmake
new file mode 100644
index 0000000..9e07152
--- /dev/null
+++ b/arm64_toolchain.cmake
@@ -0,0 +1,13 @@
+set(CMAKE_SYSTEM_NAME Linux)
+set(CMAKE_SYSTEM_PROCESSOR aarch64)
+
+set(CMAKE_C_COMPILER aarch64-linux-gnu-gcc)
+set(CMAKE_CXX_COMPILER aarch64-linux-gnu-g++)
+
+set(ARM=TRUE)
+
+set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
+set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
+set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
+
+set(CPACK_DEBIAN_PACKAGE_ARCHITECTURE arm64)
diff --git a/readme/empty.txt b/readme/empty.txt
deleted file mode 100644
index 588fe22..0000000
--- a/readme/empty.txt
+++ /dev/null
@@ -1 +0,0 @@
-This is empy file
diff --git a/readme/img/apv_parser_on_imhex.png b/readme/img/apv_parser_on_imhex.png
new file mode 100644
index 0000000..3ad7a2e
--- /dev/null
+++ b/readme/img/apv_parser_on_imhex.png
Binary files differ
diff --git a/src/avx/oapv_tq_avx.c b/src/avx/oapv_tq_avx.c
index 2f7b299..22c8d4e 100644
--- a/src/avx/oapv_tq_avx.c
+++ b/src/avx/oapv_tq_avx.c
@@ -519,6 +519,8 @@
shift = QUANT_SHIFT + tr_shift + (qp / 6);
offset = (s64)deadzone_offset << (shift - 9);
__m256i offset_vector = _mm256_set1_epi64x(offset);
+ __m256i reg_minval_int16 = _mm256_set1_epi32(-32768);
+ __m256i reg_maxval_int16 = _mm256_set1_epi32(32767);
int pixels = (1 << (log2_w + log2_h));
int i;
@@ -533,7 +535,7 @@
0, 1, 4, 5, 8, 9, 12, 13,
-128, -128, -128, -128, -128, -128, -128, -128,
-128, -128, -128, -128, -128, -128, -128, -128);
-
+
for (i = 0; i < pixels; i += 8)
{
// Load first row
@@ -541,8 +543,8 @@
__m128i coef_row = _mm_lddqu_si128((__m128i*)(coef + i));
// Extract sign
- __m256i coef_row_cast = _mm256_castsi128_si256(coef_row);
- __m256i sign_mask = _mm256_srai_epi16(coef_row_cast, 15);
+ __m128i sign_mask = _mm_srai_epi16(coef_row, 15);
+ __m256i sign_mask_ext = _mm256_cvtepi16_epi32(sign_mask);
// Convert to 32 bits and take abs()
__m256i coef_row_ext = _mm256_cvtepi16_epi32(coef_row);
@@ -557,25 +559,23 @@
// First level of combination
lev2_low = _mm256_slli_epi64(lev2_low, 32);
__m256i combined = _mm256_or_si256(lev2_low, lev2_high);
+ __m256i levx = _mm256_permutevar8x32_epi32(combined, shuffle0);
+
+ // Apply sign and clipping
+ levx = _mm256_sub_epi32(_mm256_xor_si256(levx, sign_mask_ext), sign_mask_ext);
+ levx = _mm256_max_epi32(levx, reg_minval_int16);
+ levx = _mm256_min_epi32(levx, reg_maxval_int16);
// Second level of combination
- __m256i levx = _mm256_permutevar8x32_epi32(combined, shuffle0);
- __m128i levx_low = _mm256_castsi256_si128(levx);
- __m256i levx_low_ext = _mm256_castsi128_si256(levx_low);
- levx_low_ext = _mm256_shuffle_epi8(levx_low_ext, shuffle1);
+ __m256i levx_low_sh = _mm256_shuffle_epi8(levx, shuffle1);
__m128i levx_high = _mm256_extracti128_si256(levx, 1);
__m256i levx_high_ext = _mm256_castsi128_si256(levx_high);
- levx_high_ext = _mm256_shuffle_epi8(levx_high_ext, shuffle2);
- levx = _mm256_or_si256(levx_high_ext, levx_low_ext);
+ __m256i levx_high_sh = _mm256_shuffle_epi8(levx_high_ext, shuffle2);
+ levx = _mm256_or_si256(levx_high_sh, levx_low_sh);
- // Apply sign
- levx = _mm256_sub_epi16(_mm256_xor_si256(levx, sign_mask), sign_mask);
-
- // Clip and store in coef
+ // store in coef
__m128i lev4 = _mm256_castsi256_si128(levx);
- __m128i lev5 = _mm_max_epi16(lev4, _mm_set1_epi16(-32768));
- __m128i lev6 = _mm_min_epi16(lev5, _mm_set1_epi16(32767));
- _mm_storeu_si128((__m128i*)(coef + i), lev6);
+ _mm_storeu_si128((__m128i*)(coef + i), lev4);
}
return OAPV_OK;
}
diff --git a/src/oapv.c b/src/oapv.c
index 164d334..8fe2fa8 100644
--- a/src/oapv.c
+++ b/src/oapv.c
@@ -1467,7 +1467,7 @@
param->tile_h_mb = 16;
param->profile_idc = OAPV_PROFILE_422_10;
- param->level_idc = (int)(4.1 * 30);
+ param->level_idc = (int)((4.1 * 30.0) + 0.5);
param->band_idc = 2;
param->use_q_matrix = 0;
@@ -1959,10 +1959,10 @@
oapv_bsr_init(&ctx->bs, (u8 *)bitb->addr + cur_read_size, remain, NULL);
bs = &ctx->bs;
- ret = oapvd_vlc_pbu_size(bs, &pbu_size); // 4byte
+ ret = oapvd_vlc_pbu_size(bs, &pbu_size); // read pbu_size (4 byte)
oapv_assert_g(OAPV_SUCCEEDED(ret), ERR);
- oapv_assert_gv((pbu_size + 4) <= bs->size, ret, OAPV_ERR_MALFORMED_BITSTREAM, ERR);
-
+ remain -= 4; // size of pbu_size syntax
+ oapv_assert_gv(pbu_size <= remain, ret, OAPV_ERR_MALFORMED_BITSTREAM, ERR);
ret = oapvd_vlc_pbu_header(bs, &pbuh);
oapv_assert_g(OAPV_SUCCEEDED(ret), ERR);
@@ -2065,20 +2065,22 @@
DUMP_SET(0);
+ /* 'au' address contains series of PBU */
do {
oapv_bs_t bs;
- u32 pbu_size = 0;
+ u32 pbu_size = 0;
u32 remain = au_size - cur_read_size;
oapv_assert_rv((remain >= 8), OAPV_ERR_MALFORMED_BITSTREAM);
oapv_bsr_init(&bs, (u8 *)au + cur_read_size, remain, NULL);
- ret = oapvd_vlc_pbu_size(&bs, &pbu_size); // 4 byte
+ ret = oapvd_vlc_pbu_size(&bs, &pbu_size); // read pbu_size (4 byte)
oapv_assert_rv(OAPV_SUCCEEDED(ret), ret);
- oapv_assert_rv((pbu_size + 4) <= bs.size, OAPV_ERR_MALFORMED_BITSTREAM);
+ remain -= 4; // size of pbu_size syntax
+ oapv_assert_rv(pbu_size <= remain, OAPV_ERR_MALFORMED_BITSTREAM);
/* pbu header */
oapv_pbuh_t pbuh;
- ret = oapvd_vlc_pbu_header(&bs, &pbuh); // 4 byte
+ ret = oapvd_vlc_pbu_header(&bs, &pbuh); // read pbu_header() (4 byte)
oapv_assert_rv(OAPV_SUCCEEDED(ret), OAPV_ERR_MALFORMED_BITSTREAM);
if(pbuh.pbu_type == OAPV_PBU_TYPE_AU_INFO) {
// parse access_unit_info in PBU
@@ -2109,7 +2111,7 @@
frm_count++;
}
aui->num_frms = frm_count;
- cur_read_size += pbu_size + 4;
+ cur_read_size += pbu_size + 4; /* 4byte is for pbu_size syntax itself */
} while(cur_read_size < au_size);
DUMP_SET(1);
return OAPV_OK;
diff --git a/src/oapv_tq.c b/src/oapv_tq.c
index 8745b91..af0bad5 100644
--- a/src/oapv_tq.c
+++ b/src/oapv_tq.c
@@ -97,6 +97,11 @@
static int oapv_quant(s16 *coef, u8 qp, int q_matrix[OAPV_BLK_D], int log2_w, int log2_h, int bit_depth, int deadzone_offset)
{
+ // coef is the output of the transform, the bit range is 16
+ // q_matrix has the value of q_scale * 16 / q_matrix, the bit range is 19
+ // (precision of q_scale is 15, and the range of q_mtrix is 1~255)
+ // lev is the product of abs(coef) and q_matrix, the bit range is 35
+
s64 lev;
s32 offset;
int sign;
diff --git a/test/README.md b/test/README.md
index 2af8348..a404bfc 100644
--- a/test/README.md
+++ b/test/README.md
@@ -5,18 +5,18 @@
| No. | Bitstream Name | Description | Profile | Level | Band | Frame Rate | Resolution | # of Frame | MD5 sum of bitstream |
|-----|----------------|--------------------------------------------------------------|---------------------|-------|------|------------|------------|------------|----------------------------------|
-| 1 | tile_A | one-tile per one-picture | 422-10 | 4.1 | 2 | 60 fps | 3840x2160 | 3 | b6e1cef839381b2c90cb9ffcdf537d77 |
-| 2 | tile_B | Tile size = min size tile (256x128) | 422-10 | 4.1 | 2 | 60 fps | 3840x2160 | 3 | 9a0cb5126d705b03a2e7bcdcbacf6fbf |
+| 1 | tile_A | one-tile per one-picture | 422-10 | 4.1 | 2 | 60 fps | 3840x2160 | 3 | 74c5c0ca1bd2cfb28c6e2e0673e965f9 |
+| 2 | tile_B | Tile size = min size tile (256x128) | 422-10 | 4.1 | 2 | 60 fps | 3840x2160 | 3 | 666ec80235a1e8f59db044d77a89a495 |
| 3 | tile_C | # of Tiles: max num tile (20x20) | 422-10 | 5 | 0 | 30 fps | 7680x4320 | 3 | 75363d036965a9dccc90a9ce8d0ae652 |
-| 4 | tile_D | tile dummy data test | 422-10 | 4.1 | 2 | 60 fps | 3840x2160 | 3 | 0394e3ac275e2bc595c07c5290dc9466 |
-| 5 | tile_E | tile_size_present_in_fh_flag=on | 422-10 | 4.1 | 2 | 60 fps | 3840x2160 | 3 | fdf72572b6551bc6a9eed7f80ca0ec0f |
+| 4 | tile_D | tile dummy data test | 422-10 | 4.1 | 2 | 60 fps | 3840x2160 | 3 | dd492519c90409a9ca5710746f45c125 |
+| 5 | tile_E | tile_size_present_in_fh_flag=on | 422-10 | 4.1 | 2 | 60 fps | 3840x2160 | 3 | 134c4aa46cec9ab0299824682a89eecd |
| 6 | qp_A | QP matrix enabled | 422-10 | 4.1 | 2 | 60 fps | 3840x2160 | 3 | 5ca6d4ea0f65add261b44ed3532a0a73 |
-| 7 | qp_B | Tile QP variation in a frame | 422-10 | 4.1 | 2 | 60 fps | 3840x2160 | 3 | 1b24d4f97c18545b7881002cc642839b |
+| 7 | qp_B | Tile QP variation in a frame | 422-10 | 4.1 | 2 | 60 fps | 3840x2160 | 3 | 85bfa477911447d994c17dea9703a9c7 |
| 8 | qp_C | Set all the QPs in a frame equal to min. QP (=0) | 422-10 | 6 | 2 | 60 fps | 3840x2160 | 3 | 8c2928ec05eb06d42d6a8bda0ceb7e8d |
-| 9 | qp_D | Set all the QPs in a frame equal to max. QP (=51) | 422-10 | 4.1 | 2 | 60 fps | 3840x2160 | 3 | e5acd3d3a0aa7bd6a45a49af35980512 |
-| 10 | qp_E | Set different QP betwee luma and chroma | 422-10 | 4.1 | 2 | 60 fps | 3840x2160 | 3 | e58ea5df35750c0d19cffefde12e78c4 |
-| 11 | syn_A | Exercise a synthetic image with QP = 0 and QP = 51 | 422-10 | 4.1 | 2 | 60 fps | 1920x1080 | 2 | e1593a670c62d69718986ff84d1150f3 |
-| 12 | syn_B | Exercise a synthetic image with Tile QP variation in Frame | 422-10 | 4.1 | 2 | 60 fps | 1920x1080 | 2 | 9f188e39824829aa05db584034ab1fd0 |
+| 9 | qp_D | Set all the QPs in a frame equal to max. QP (=51) | 422-10 | 4.1 | 2 | 60 fps | 3840x2160 | 3 | 9c98e376fb59100f5a5585482fb33746 |
+| 10 | qp_E | Set different QP betwee luma and chroma | 422-10 | 4.1 | 2 | 60 fps | 3840x2160 | 3 | 6d1a1bc982d412758f353c8d041979d1 |
+| 11 | syn_A | Exercise a synthetic image with QP = 0 and QP = 51 | 422-10 | 4.1 | 2 | 60 fps | 1920x1080 | 2 | db9f8f7ce57871481e5b257b79149b1e |
+| 12 | syn_B | Exercise a synthetic image with Tile QP variation in Frame | 422-10 | 4.1 | 2 | 60 fps | 1920x1080 | 2 | 5f6c57f0bfe7ceb2f97a56a3bec7fb7a |
## Test sequence
"sequence" folder has the uncompressed video sequence for encoder testing.
diff --git a/test/bitstream/qp_B.apv b/test/bitstream/qp_B.apv
index fd3d776..f685630 100644
--- a/test/bitstream/qp_B.apv
+++ b/test/bitstream/qp_B.apv
Binary files differ
diff --git a/test/bitstream/qp_D.apv b/test/bitstream/qp_D.apv
index 6469e60..d094042 100644
--- a/test/bitstream/qp_D.apv
+++ b/test/bitstream/qp_D.apv
Binary files differ
diff --git a/test/bitstream/qp_E.apv b/test/bitstream/qp_E.apv
index 24d8091..62bde8c 100644
--- a/test/bitstream/qp_E.apv
+++ b/test/bitstream/qp_E.apv
Binary files differ
diff --git a/test/bitstream/syn_A.apv b/test/bitstream/syn_A.apv
index b220d05..1d325d1 100644
--- a/test/bitstream/syn_A.apv
+++ b/test/bitstream/syn_A.apv
Binary files differ
diff --git a/test/bitstream/syn_B.apv b/test/bitstream/syn_B.apv
index fb0565c..641a108 100644
--- a/test/bitstream/syn_B.apv
+++ b/test/bitstream/syn_B.apv
Binary files differ
diff --git a/test/bitstream/tile_A.apv b/test/bitstream/tile_A.apv
index 074701f..1f8d213 100644
--- a/test/bitstream/tile_A.apv
+++ b/test/bitstream/tile_A.apv
Binary files differ
diff --git a/test/bitstream/tile_B.apv b/test/bitstream/tile_B.apv
index 9930bf7..f796778 100644
--- a/test/bitstream/tile_B.apv
+++ b/test/bitstream/tile_B.apv
Binary files differ
diff --git a/test/bitstream/tile_D.apv b/test/bitstream/tile_D.apv
index cf0d33e..7d61d5c 100644
--- a/test/bitstream/tile_D.apv
+++ b/test/bitstream/tile_D.apv
Binary files differ
diff --git a/test/bitstream/tile_E.apv b/test/bitstream/tile_E.apv
index 029262b..66b1c3d 100644
--- a/test/bitstream/tile_E.apv
+++ b/test/bitstream/tile_E.apv
Binary files differ
diff --git a/util/apv.hexpat b/util/apv.hexpat
new file mode 100644
index 0000000..dd4ae2c
--- /dev/null
+++ b/util/apv.hexpat
@@ -0,0 +1,224 @@
+#pragma pattern for Advanced Professional Video (*.apv)
+
+import std.io;
+import std.mem;
+#pragma endian big
+
+/* PBU types */
+enum PbuType : u8 {
+ FRM_PRI = 1,
+ FRM_NONPRI = 2,
+ FRM_PREVIEW = 25,
+ FRM_DEPTH = 26,
+ FRM_ALPHA = 27,
+ AUI = 65,
+ METADATA = 66,
+ FILLER = 67
+};
+
+fn get_0xff_ext_var(auto addr) {
+ u32 read = 1;
+ u32 var = 0;
+ u8 ext = std::mem::read_unsigned(addr, 1);
+
+ while (ext == 0xFF) {
+ var += 0xFF;
+ ext = std::mem::read_unsigned(addr + read, 1);
+ read += 1;
+ }
+ var += ext;
+ return var;
+};
+
+fn get_0xff_ext_var_bytes(auto addr) {
+ u32 read = 1;
+ u8 ext = std::mem::read_unsigned(addr, 1);
+
+ while (ext == 0xFF) {
+ ext = std::mem::read_unsigned(addr + read, 1);
+ read += 1;
+ }
+ return read;
+};
+
+struct PbuBase {
+
+ u32 read = 0;
+ str ptype_str = "";
+
+ /*
+ syntax code | type
+ --------------------------------------------------------------|-----
+ pbu_header(){ |
+ pbu_type | u(8)
+ group_id | u(16)
+ reserved_zero_8bits | u(8)
+ }
+ */
+
+ u32 pbu_size; // originally, this syntax is part of AuccessUnit
+ u8 pbu_type;
+ u16 group_id;
+ u8 reserved_zero_8bits;
+ read += 4;
+};
+
+/*
+syntax code | type
+--------------------------------------------------------------|-----
+frame_info(){ |
+ profile_idc | u(8)
+ level_idc | u(8)
+ band_idc | u(3)
+ reserved_zero_5bits | u(5)
+ frame_width | u(24)
+ frame_height | u(24)
+ chroma_format_idc | u(4)
+ bit_depth_minus8 | u(4)
+ capture_time_distance | u(8)
+ reserved_zero_8bits | u(8)
+}
+*/
+
+bitfield FrmInfo {
+ profile_idc : 8;
+ level_idc : 8;
+ band_idc : 3;
+ reserved_zero_5bits: 5;
+ frame_width: 24;
+ frame_height: 24;
+ chroma_format_idc: 4;
+ bit_depth_minus8: 4;
+ capture_time_distance: 8;
+ reserved_zero_8bits: 8;
+};
+
+struct PbuFrm:PbuBase {
+
+ if(pbu_type == PbuType::FRM_PRI) ptype_str = "Frm(Pri)";
+ else if(pbu_type == PbuType::FRM_NONPRI) ptype_str = "Frm(Nonpri)";
+ else if(pbu_type == PbuType::FRM_PREVIEW) ptype_str = "Frm(Preview)";
+ else if(pbu_type == PbuType::FRM_DEPTH) ptype_str = "Frm(Depth)";
+ else if(pbu_type == PbuType::FRM_ALPHA) ptype_str = "Frm(Alpha)";
+ else ptype_str = "Frm(Unknown)";
+
+ FrmInfo finfo [[name("frame_info()")]];
+ read += 12; // byte size of frame_info()
+
+ u8 frameData[pbu_size - read] [[sealed]];
+};
+
+u32 metadata_payload_count = 0;
+
+struct MetadataPayload {
+ str ptype_str = "";
+ u32 read = 0;
+
+ u32 payloadType = get_0xff_ext_var($) [[export]];
+ read += get_0xff_ext_var_bytes($);
+ $ += get_0xff_ext_var_bytes($); // update current reading point
+
+ u32 payloadSize = get_0xff_ext_var($) [[export]];
+ read += get_0xff_ext_var_bytes($);
+ $ += get_0xff_ext_var_bytes($); // update current reading point
+
+ u64 endOffset = $ + payloadSize;
+
+
+ if (payloadType == 4) ptype_str = "itu_t_t35";
+ else if (payloadType == 5) ptype_str = "mdcv";
+ else if (payloadType == 6) ptype_str = "cll";
+ else if (payloadType == 10) ptype_str = "filler";
+ else if (payloadType == 170) ptype_str = "user_defined";
+ else ptype_str = "undefined";
+
+ std::print(" metadata payload[{:d}] type = {:d}({}), size = {:d}", metadata_payload_count, payloadType, ptype_str, payloadSize);
+
+ u8 payloadData[while($ < endOffset)] [[sealed]];
+
+ metadata_payload_count += 1;
+
+
+} [[name(std::format("MetadataPayload[{}]:{}", (metadata_payload_count - 1), ptype_str))]];
+
+struct PbuMetadata:PbuBase {
+ u64 endOffset = 0;
+ ptype_str = "Metadata";
+ metadata_payload_count = 0; // reset number of metadata payload
+
+ u32 metadata_size; // syntax
+
+ endOffset = $ + metadata_size;
+
+ MetadataPayload pay[while($ < endOffset)] [[inline]];
+};
+
+
+struct PbuAui:PbuBase {
+ ptype_str = "aui";
+ u8 data[pbu_size - read] [[sealed]];
+};
+
+struct PbuFiller:PbuBase {
+ ptype_str = "filler";
+ u8 data[pbu_size - read] [[sealed]];
+};
+
+struct PbuUnknown:PbuBase {
+ std::warning(std::format("Unknown PBU type ({})!!!", pbu_type));
+ ptype_str = "unknown";
+ u8 data[pbu_size - read] [[sealed]];
+};
+
+u32 pbu_count = 0;
+
+struct PBU {
+ u32 pbu_size = std::mem::read_unsigned($, 4, std::mem::Endian::Big);
+ u8 pbu_type = std::mem::read_unsigned($ + 4, 1, std::mem::Endian::Big);
+
+ match (pbu_type) {
+ (PbuType::FRM_PRI) : PbuFrm Pbu [[inline]];
+ (PbuType::FRM_NONPRI) : PbuFrm Pbu [[inline]];
+ (PbuType::FRM_PREVIEW): PbuFrm Pbu [[inline]];
+ (PbuType::FRM_DEPTH): PbuFrm Pbu [[inline]];
+ (PbuType::FRM_ALPHA): PbuFrm Pbu [[inline]];
+ (PbuType::AUI): PbuAui Pbu [[inline]];
+ (PbuType::METADATA): PbuMetadata Pbu [[inline]];
+ (PbuType::FILLER): PbuFiller Pbu [[inline]];
+ (_) : PbuUnknown Pbu [[inline]];
+ }
+
+ std::print(" PBU[{:d}] size = {:d}, {}", pbu_count, pbu_size, Pbu.ptype_str);
+
+ pbu_count += 1;
+
+} [[name(std::format("PBU[{}]:{}", (pbu_count - 1), Pbu.ptype_str))]];
+
+
+u32 au_count = 0;
+
+struct AccessUnit {
+ u64 au_end = 0;
+
+ u32 au_size; // originally this syntax is part of RawBitstream
+
+ std::print("AU[{:d}] size = {:d}", au_count, au_size);
+
+ au_end = $ + au_size;
+
+ pbu_count = 0; // reset number of PBU
+ PBU pbu[while($ < au_end)] [[inline]];
+};
+
+u32 raw_count = 0;
+
+struct RawBitstream {
+ AccessUnit AU [[name(std::format("AU[{}]", raw_count))]];
+ raw_count += 1;
+} [[name(std::format("Raw[{}]", (raw_count - 1)))]];
+
+struct ApvBitstream {
+ RawBitstream Raw [[inline]];
+}[[inline]];
+
+ApvBitstream APV[while(!std::mem::eof())] @ 0x0 [[inline]];
\ No newline at end of file
diff --git a/version.txt b/version.txt
index 5e12916..db4afdf 100644
--- a/version.txt
+++ b/version.txt
@@ -1 +1 @@
-v0.1.10.1
+v0.1.11.1