Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
103 changes: 96 additions & 7 deletions .github/workflows/build_windows.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ env:
RUSTFLAGS: -Ctarget-feature=+crt-static
VCPKG_DEFAULT_TRIPLET: x64-windows-static
VCPKG_DEFAULT_BINARY_CACHE: C:\vcpkg\.cache
VCPKG_COMMIT: fba75d09065fcc76a25dcf386b1d00d33f5175af
# VCPKG_COMMIT removed - will use latest

on:
workflow_dispatch:
Expand All @@ -30,34 +30,76 @@ jobs:
steps:
- name: Check out repository
uses: actions/checkout@v4

- name: Setup MSBuild.exe
uses: microsoft/[email protected]
with:
msbuild-architecture: x64

- name: Install gpac
run: choco install gpac --version 2.4.0

- name: Setup vcpkg
run: mkdir C:\vcpkg\.cache

- name: Get vcpkg commit hash
id: vcpkg-commit
run: |
$commit = (git ls-remote https://github.com/microsoft/vcpkg HEAD | Select-Object -First 1).Split()[0]
echo "hash=$commit" >> $env:GITHUB_OUTPUT
echo "Using vcpkg commit: $commit"

- name: Cache vcpkg
id: cache
uses: actions/cache@v4
with:
path: |
C:\vcpkg\.cache
key: vcpkg-${{ runner.os }}-${{ env.VCPKG_COMMIT }}
key: vcpkg-${{ runner.os }}-${{ steps.vcpkg-commit.outputs.hash }}

- name: Build vcpkg
run: |
git clone https://github.com/microsoft/vcpkg
cd vcpkg
git pull origin master
cd ..
./vcpkg/bootstrap-vcpkg.bat
- name: Install dependencies
run: ${{ github.workspace }}/vcpkg/vcpkg.exe install --x-install-root ${{ github.workspace }}/vcpkg/installed/

- name: Install dependencies with retry
run: |
$maxRetries = 3
$retryCount = 0
$success = $false

while (-not $success -and $retryCount -lt $maxRetries) {
try {
Write-Host "Attempt $($retryCount + 1) of $maxRetries"
& "${{ github.workspace }}/vcpkg/vcpkg.exe" install --x-install-root "${{ github.workspace }}/vcpkg/installed/"
$success = $true
Write-Host "Dependencies installed successfully"
}
catch {
$retryCount++
if ($retryCount -lt $maxRetries) {
Write-Host "Installation failed. Retrying in 10 seconds..."
Start-Sleep -Seconds 10
}
else {
Write-Host "Installation failed after $maxRetries attempts"
exit 1
}
}
}
working-directory: windows

- uses: actions-rs/toolchain@v1
with:
toolchain: stable
override: true

- name: Install Win 10 SDK
uses: ilammy/msvc-dev-cmd@v1

- name: build Release-Full
env:
LIBCLANG_PATH: "C:\\Program Files\\LLVM\\lib"
Expand All @@ -67,48 +109,93 @@ jobs:
VCPKG_ROOT: ${{ github.workspace }}/vcpkg
run: msbuild ccextractor.sln /p:Configuration=Release-Full /p:Platform=x64
working-directory: ./windows

- name: Display version information
run: ./ccextractorwinfull.exe --version
working-directory: ./windows/x64/Release-Full

- uses: actions/upload-artifact@v4
with:
name: CCExtractor Windows Release build
path: |
./windows/x64/Release-Full/ccextractorwinfull.exe
./windows/x64/Release-Full/*.dll

build_debug:
runs-on: windows-2022
steps:
- name: Check out repository
uses: actions/checkout@v4

- name: Setup MSBuild.exe
uses: microsoft/[email protected]
with:
msbuild-architecture: x64

- name: Install gpac
run: choco install gpac --version 2.4.0

- name: Setup vcpkg
run: mkdir C:\vcpkg\.cache

- name: Get vcpkg commit hash
id: vcpkg-commit
run: |
$commit = (git ls-remote https://github.com/microsoft/vcpkg HEAD | Select-Object -First 1).Split()[0]
echo "hash=$commit" >> $env:GITHUB_OUTPUT
echo "Using vcpkg commit: $commit"

- name: Cache vcpkg
id: cache
uses: actions/cache@v4
with:
path: |
C:\vcpkg\.cache
key: vcpkg-${{ runner.os }}-${{ env.VCPKG_COMMIT }}
key: vcpkg-${{ runner.os }}-${{ steps.vcpkg-commit.outputs.hash }}

- name: Build vcpkg
run: |
git clone https://github.com/microsoft/vcpkg
cd vcpkg
git pull origin master
cd ..
./vcpkg/bootstrap-vcpkg.bat
- name: Install dependencies
run: ${{ github.workspace }}/vcpkg/vcpkg.exe install --x-install-root ${{ github.workspace }}/vcpkg/installed/

- name: Install dependencies with retry
run: |
$maxRetries = 3
$retryCount = 0
$success = $false

while (-not $success -and $retryCount -lt $maxRetries) {
try {
Write-Host "Attempt $($retryCount + 1) of $maxRetries"
& "${{ github.workspace }}/vcpkg/vcpkg.exe" install --x-install-root "${{ github.workspace }}/vcpkg/installed/"
$success = $true
Write-Host "Dependencies installed successfully"
}
catch {
$retryCount++
if ($retryCount -lt $maxRetries) {
Write-Host "Installation failed. Retrying in 10 seconds..."
Start-Sleep -Seconds 10
}
else {
Write-Host "Installation failed after $maxRetries attempts"
exit 1
}
}
}
working-directory: windows

- uses: actions-rs/toolchain@v1
with:
toolchain: stable
override: true

- name: Install Win 10 SDK
uses: ilammy/msvc-dev-cmd@v1

- name: build Debug-Full
env:
LIBCLANG_PATH: "C:\\Program Files\\LLVM\\lib"
Expand All @@ -118,10 +205,12 @@ jobs:
VCPKG_ROOT: ${{ github.workspace }}/vcpkg
run: msbuild ccextractor.sln /p:Configuration=Debug-Full /p:Platform=x64
working-directory: ./windows

- name: Display version information
continue-on-error: true
run: ./ccextractorwinfull.exe --version
working-directory: ./windows/x64/Debug-Full

- uses: actions/upload-artifact@v4
with:
name: CCExtractor Windows Debug build
Expand Down
16 changes: 10 additions & 6 deletions src/lib_ccx/avc_functions.c
Original file line number Diff line number Diff line change
Expand Up @@ -95,15 +95,19 @@ void do_NAL(struct encoder_ctx *enc_ctx, struct lib_cc_decode *dec_ctx, unsigned
NAL_stop = NAL_length + NAL_start;
NAL_stop = remove_03emu(NAL_start + 1, NAL_stop); // Add +1 to NAL_stop for TS, without it for MP4. Still don't know why

dvprint("BEGIN NAL unit type: %d length %d ref_idc: %d - Buffered captions before: %d\n",
nal_unit_type, NAL_stop - NAL_start - 1, dec_ctx->avc_ctx->nal_ref_idc, !dec_ctx->avc_ctx->cc_buffer_saved);

if (NAL_stop == NULL) // remove_03emu failed.
{
mprint("\rNotice: NAL of type %u had to be skipped because remove_03emu failed.\n", nal_unit_type);
mprint("\rWarning: Invalid prevention bytes detected in NAL unit type %u (0x%02X). "
"This NAL unit contains an illegal byte sequence (0x000000, 0x000001, or 0x000002) or "
"improper prevention byte (0x03). "
Comment on lines +101 to +102
Copy link

Copilot AI Jul 15, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The error message contains technical inaccuracies. The sequences 0x000000, 0x000001, and 0x000002 are not inherently illegal in H.264 streams - 0x000001 is actually the standard start code prefix. The message should focus on the actual failure rather than speculating about specific byte patterns.

Suggested change
"This NAL unit contains an illegal byte sequence (0x000000, 0x000001, or 0x000002) or "
"improper prevention byte (0x03). "
"This NAL unit contains improper prevention bytes (0x03) or other anomalies. "

Copilot uses AI. Check for mistakes.
Copy link
Contributor Author

@steel-bucket steel-bucket Jul 15, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this suggestion is incorrect, The comment at Line 274 states that 0x000000, 0x000001 or 0x000002 shall not occur at any byte-aligned position

"This may indicate a corrupted AVC/H.264 stream. NAL unit skipped.\n",
Comment on lines +100 to +103
Copy link

Copilot AI Jul 15, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The error message incorrectly describes the failure condition. The remove_03emu function can fail for reasons other than invalid prevention bytes, such as general parsing errors or memory issues. Consider using a more generic message like 'Failed to process NAL unit type %u (0x%02X) due to emulation prevention byte removal failure.'

Suggested change
mprint("\rWarning: Invalid prevention bytes detected in NAL unit type %u (0x%02X). "
"This NAL unit contains an illegal byte sequence (0x000000, 0x000001, or 0x000002) or "
"improper prevention byte (0x03). "
"This may indicate a corrupted AVC/H.264 stream. NAL unit skipped.\n",
mprint("\rWarning: Failed to process NAL unit type %u (0x%02X) due to emulation prevention byte removal failure. "
"This may indicate a corrupted AVC/H.264 stream or an internal processing error. NAL unit skipped.\n",

Copilot uses AI. Check for mistakes.
nal_unit_type, nal_unit_type);
return;
}

dvprint("BEGIN NAL unit type: %d length %d ref_idc: %d - Buffered captions before: %d\n",
nal_unit_type, NAL_stop - NAL_start - 1, dec_ctx->avc_ctx->nal_ref_idc, !dec_ctx->avc_ctx->cc_buffer_saved);

Comment on lines 104 to +110
Copy link

Copilot AI Jul 15, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Moving the dvprint statement after the error check means debug information won't be printed for NAL units that fail emulation prevention byte removal. This could make debugging more difficult. Consider keeping the debug print before the error check or adding a separate debug message for failed NAL units.

Suggested change
return;
}
dvprint("BEGIN NAL unit type: %d length %d ref_idc: %d - Buffered captions before: %d\n",
nal_unit_type, NAL_stop - NAL_start - 1, dec_ctx->avc_ctx->nal_ref_idc, !dec_ctx->avc_ctx->cc_buffer_saved);
dvprint("Failed to process NAL unit type: %d - Emulation prevention byte removal failed.\n",
nal_unit_type);
return;
}

Copilot uses AI. Check for mistakes.
if (nal_unit_type == CCX_NAL_TYPE_ACCESS_UNIT_DELIMITER_9)
{
// Found Access Unit Delimiter
Expand All @@ -127,7 +131,7 @@ void do_NAL(struct encoder_ctx *enc_ctx, struct lib_cc_decode *dec_ctx, unsigned
else if (dec_ctx->avc_ctx->got_seq_para && nal_unit_type == CCX_NAL_TYPE_SEI)
{
// Found SEI (used for subtitles)
// set_fts(ctx->timing); // FIXME - check this!!!
set_fts(enc_ctx->timing);
sei_rbsp(dec_ctx->avc_ctx, NAL_start + 1, NAL_stop);
}
else if (dec_ctx->avc_ctx->got_seq_para && nal_unit_type == CCX_NAL_TYPE_PICTURE_PARAMETER_SET)
Expand Down Expand Up @@ -308,7 +312,7 @@ u32 avc_remove_emulation_bytes(const unsigned char *buffer_src, unsigned char *b
unsigned char *remove_03emu(unsigned char *from, unsigned char *to)
{
int num = to - from;
int newsize = EBSPtoRBSP(from, num, 0); // TODO: Do something if newsize == -1 (broken NAL)
int newsize = EBSPtoRBSP(from, num, 0);
if (newsize == -1)
return NULL;
return from + newsize;
Expand Down
Loading