mirror of
https://github.com/heygen-com/hyperframes.git
synced 2026-11-15 13:58:20 +00:00
feat!: remove Plan v1 distributed transport (#6970)
* feat!: remove Plan v1 distributed transport BREAKING CHANGE: Cloud adapters accept only Plan v2; producer v1 exports are removed. * ci: authorize Plan v1 cleanup deletions * docs: avoid citing generated smoke result file * fix(gcp): reject unsupported plan protocols in workflow * ci: preserve gcp package size reduction * fix: reject stale Plan v1 SDK options * chore: remove retired Plan parity scripts
This commit is contained in:
@@ -1,239 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
# Canonical decoded-output comparison shared by the real-AWS smoke test and
|
||||
# its local unit test. This file defines functions only; sourcing it has no
|
||||
# side effects.
|
||||
|
||||
hf_sha256() {
|
||||
sha256sum "$1" | awk '{print $1}'
|
||||
}
|
||||
|
||||
hf_canonical_video_framemd5() {
|
||||
local input="$1" output="$2" raw
|
||||
raw=$(mktemp)
|
||||
if ! ffmpeg -nostdin -v error -y -i "$input" \
|
||||
-map 0:v:0 -an -vf format=rgba -fps_mode passthrough \
|
||||
-f framemd5 "$raw"; then
|
||||
rm -f "$raw"
|
||||
return 1
|
||||
fi
|
||||
# Ignore container timestamp/header differences here: normalized ffprobe
|
||||
# metadata and duration are gated separately. This file pins decoded pixel
|
||||
# bytes, frame order, frame count, and per-frame byte size.
|
||||
awk -F',' '
|
||||
!/^#/ && NF >= 6 {
|
||||
size=$5; hash=$6
|
||||
gsub(/[[:space:]]/, "", size)
|
||||
gsub(/[[:space:]]/, "", hash)
|
||||
print size "," hash
|
||||
}
|
||||
' "$raw" > "$output"
|
||||
rm -f "$raw"
|
||||
[ -s "$output" ]
|
||||
}
|
||||
|
||||
hf_normalized_ffprobe_metadata() {
|
||||
local input="$1" output="$2"
|
||||
ffprobe -v error \
|
||||
-show_entries \
|
||||
stream=index,codec_type,codec_name,profile,pix_fmt,width,height,sample_aspect_ratio,display_aspect_ratio,r_frame_rate,avg_frame_rate,time_base,color_range,color_space,color_transfer,color_primaries,chroma_location,field_order,sample_fmt,sample_rate,channels,channel_layout \
|
||||
-of json "$input" |
|
||||
jq -S '{
|
||||
streams: ((.streams // [])
|
||||
| sort_by(.codec_type, .index)
|
||||
| map(del(.index)))
|
||||
}' > "$output"
|
||||
}
|
||||
|
||||
hf_duration_seconds() {
|
||||
ffprobe -v error -show_entries format=duration -of default=nw=1:nk=1 "$1"
|
||||
}
|
||||
|
||||
hf_has_audio() {
|
||||
[ -n "$(ffprobe -v error -select_streams a:0 -show_entries stream=index -of csv=p=0 "$1" 2>/dev/null | head -1)" ]
|
||||
}
|
||||
|
||||
hf_decode_pcm() {
|
||||
ffmpeg -nostdin -v error -i "$1" -map 0:a:0 -vn \
|
||||
-ac 2 -ar 48000 -c:a pcm_s16le -f s16le "$2"
|
||||
}
|
||||
|
||||
# Chunks run in Distributed Map child executions; the Map's exit output carries every result.
|
||||
hf_extract_chunk_hashes() {
|
||||
local history="$1" output="$2"
|
||||
jq '[
|
||||
.events[] |
|
||||
select(.type == "MapStateExited") |
|
||||
.stateExitedEventDetails |
|
||||
select(.name == "RenderChunks" or .name == "RenderChunksV2") |
|
||||
(.output | fromjson | .Chunks // [])[] |
|
||||
{ChunkIndex, Sha256, FramesEncoded}
|
||||
] | sort_by(.ChunkIndex)' "$history" > "$output"
|
||||
}
|
||||
|
||||
# Compare two rendered outputs. Writes durable evidence at <prefix>.* and a
|
||||
# machine-readable <prefix>.json. Returns 0 only for semantic equivalence.
|
||||
hf_compare_render_semantics() {
|
||||
local v1="$1" v2="$2" prefix="$3"
|
||||
local v1_history="${4:-}" v2_history="${5:-}"
|
||||
local tolerance="${SEMANTIC_DURATION_TOLERANCE_SECONDS:-0.001}"
|
||||
local work
|
||||
work=$(mktemp -d)
|
||||
|
||||
local v1_frames="${prefix}.v1.framemd5"
|
||||
local v2_frames="${prefix}.v2.framemd5"
|
||||
local v1_meta="${prefix}.v1.ffprobe.json"
|
||||
local v2_meta="${prefix}.v2.ffprobe.json"
|
||||
local v1_duration v2_duration duration_delta
|
||||
local v1_encoded_sha v2_encoded_sha encoded_equal
|
||||
local video_equal metadata_equal duration_equal
|
||||
local audio_state audio_equal v1_audio_sha="" v2_audio_sha=""
|
||||
local v1_audio_bytes=0 v2_audio_bytes=0
|
||||
local encoded_gated=false
|
||||
local chunks_checked=false chunks_equal=true v1_chunk_count=0 v2_chunk_count=0
|
||||
if [ "${REQUIRE_ENCODED_SHA_EQUAL:-false}" = true ]; then encoded_gated=true; fi
|
||||
|
||||
if ! hf_canonical_video_framemd5 "$v1" "$v1_frames" ||
|
||||
! hf_canonical_video_framemd5 "$v2" "$v2_frames" ||
|
||||
! hf_normalized_ffprobe_metadata "$v1" "$v1_meta" ||
|
||||
! hf_normalized_ffprobe_metadata "$v2" "$v2_meta"; then
|
||||
rm -rf "$work"
|
||||
return 2
|
||||
fi
|
||||
|
||||
if cmp -s "$v1_frames" "$v2_frames"; then video_equal=true; else video_equal=false; fi
|
||||
if cmp -s "$v1_meta" "$v2_meta"; then metadata_equal=true; else metadata_equal=false; fi
|
||||
|
||||
if ! v1_duration=$(hf_duration_seconds "$v1") ||
|
||||
! v2_duration=$(hf_duration_seconds "$v2"); then
|
||||
rm -rf "$work"
|
||||
return 2
|
||||
fi
|
||||
duration_delta=$(awk -v a="$v1_duration" -v b="$v2_duration" \
|
||||
'BEGIN { d=a-b; if (d<0) d=-d; printf("%.9f", d) }')
|
||||
if awk -v d="$duration_delta" -v t="$tolerance" 'BEGIN { exit !(d <= t) }'; then
|
||||
duration_equal=true
|
||||
else
|
||||
duration_equal=false
|
||||
fi
|
||||
|
||||
local v1_has_audio=false v2_has_audio=false
|
||||
if hf_has_audio "$v1"; then v1_has_audio=true; fi
|
||||
if hf_has_audio "$v2"; then v2_has_audio=true; fi
|
||||
if [ "$v1_has_audio" = false ] && [ "$v2_has_audio" = false ]; then
|
||||
audio_state="no-audio-on-either"
|
||||
audio_equal=true
|
||||
elif [ "$v1_has_audio" != "$v2_has_audio" ]; then
|
||||
audio_state="audio-stream-mismatch"
|
||||
audio_equal=false
|
||||
else
|
||||
audio_state="decoded-pcm"
|
||||
if ! hf_decode_pcm "$v1" "$work/v1.pcm" ||
|
||||
! hf_decode_pcm "$v2" "$work/v2.pcm"; then
|
||||
rm -rf "$work"
|
||||
return 2
|
||||
fi
|
||||
v1_audio_sha=$(hf_sha256 "$work/v1.pcm")
|
||||
v2_audio_sha=$(hf_sha256 "$work/v2.pcm")
|
||||
v1_audio_bytes=$(wc -c < "$work/v1.pcm" | tr -d '[:space:]')
|
||||
v2_audio_bytes=$(wc -c < "$work/v2.pcm" | tr -d '[:space:]')
|
||||
if [ "$v1_audio_sha" = "$v2_audio_sha" ] && [ "$v1_audio_bytes" = "$v2_audio_bytes" ]; then
|
||||
audio_equal=true
|
||||
else
|
||||
audio_equal=false
|
||||
fi
|
||||
fi
|
||||
|
||||
v1_encoded_sha=$(hf_sha256 "$v1")
|
||||
v2_encoded_sha=$(hf_sha256 "$v2")
|
||||
if [ "$v1_encoded_sha" = "$v2_encoded_sha" ]; then encoded_equal=true; else encoded_equal=false; fi
|
||||
|
||||
local semantic_equal=false
|
||||
if [ "$video_equal" = true ] &&
|
||||
[ "$metadata_equal" = true ] &&
|
||||
[ "$duration_equal" = true ] &&
|
||||
[ "$audio_equal" = true ]; then
|
||||
semantic_equal=true
|
||||
fi
|
||||
if [ "$encoded_gated" = true ] && [ "$encoded_equal" != true ]; then
|
||||
semantic_equal=false
|
||||
fi
|
||||
|
||||
if [ -n "$v1_history" ] || [ -n "$v2_history" ]; then
|
||||
chunks_checked=true
|
||||
if [ -z "$v1_history" ] || [ -z "$v2_history" ] ||
|
||||
! hf_extract_chunk_hashes "$v1_history" "${prefix}.v1.chunk-hashes.json" ||
|
||||
! hf_extract_chunk_hashes "$v2_history" "${prefix}.v2.chunk-hashes.json"; then
|
||||
rm -rf "$work"
|
||||
return 2
|
||||
fi
|
||||
v1_chunk_count=$(jq 'length' "${prefix}.v1.chunk-hashes.json")
|
||||
v2_chunk_count=$(jq 'length' "${prefix}.v2.chunk-hashes.json")
|
||||
if [ "$v1_chunk_count" -eq 0 ] ||
|
||||
[ "$v2_chunk_count" -eq 0 ] ||
|
||||
! cmp -s "${prefix}.v1.chunk-hashes.json" "${prefix}.v2.chunk-hashes.json"; then
|
||||
chunks_equal=false
|
||||
semantic_equal=false
|
||||
fi
|
||||
fi
|
||||
|
||||
jq -n \
|
||||
--arg v1 "$v1" --arg v2 "$v2" \
|
||||
--argjson semanticEqual "$semantic_equal" \
|
||||
--argjson videoEqual "$video_equal" \
|
||||
--argjson v1VideoFrameCount "$(wc -l < "$v1_frames" | tr -d '[:space:]')" \
|
||||
--argjson v2VideoFrameCount "$(wc -l < "$v2_frames" | tr -d '[:space:]')" \
|
||||
--argjson metadataEqual "$metadata_equal" \
|
||||
--arg v1Duration "$v1_duration" --arg v2Duration "$v2_duration" \
|
||||
--arg durationDelta "$duration_delta" --arg durationTolerance "$tolerance" \
|
||||
--arg audioState "$audio_state" --argjson audioEqual "$audio_equal" \
|
||||
--arg v1AudioSha256 "$v1_audio_sha" --arg v2AudioSha256 "$v2_audio_sha" \
|
||||
--argjson v1AudioBytes "$v1_audio_bytes" --argjson v2AudioBytes "$v2_audio_bytes" \
|
||||
--arg v1EncodedSha256 "$v1_encoded_sha" --arg v2EncodedSha256 "$v2_encoded_sha" \
|
||||
--argjson encodedShaEqual "$encoded_equal" \
|
||||
--argjson encodedShaGated "$encoded_gated" \
|
||||
--argjson chunksChecked "$chunks_checked" \
|
||||
--argjson chunksEqual "$chunks_equal" \
|
||||
--argjson v1ChunkCount "$v1_chunk_count" \
|
||||
--argjson v2ChunkCount "$v2_chunk_count" \
|
||||
'{
|
||||
v1: $v1,
|
||||
v2: $v2,
|
||||
semanticEqual: $semanticEqual,
|
||||
video: {
|
||||
equal: $videoEqual,
|
||||
v1FrameCount: $v1VideoFrameCount,
|
||||
v2FrameCount: $v2VideoFrameCount
|
||||
},
|
||||
metadata: {equal: $metadataEqual},
|
||||
chunks: {
|
||||
checked: $chunksChecked,
|
||||
equal: $chunksEqual,
|
||||
v1Count: $v1ChunkCount,
|
||||
v2Count: $v2ChunkCount
|
||||
},
|
||||
duration: {
|
||||
v1Seconds: ($v1Duration | tonumber),
|
||||
v2Seconds: ($v2Duration | tonumber),
|
||||
deltaSeconds: ($durationDelta | tonumber),
|
||||
toleranceSeconds: ($durationTolerance | tonumber),
|
||||
equal: (($durationDelta | tonumber) <= ($durationTolerance | tonumber))
|
||||
},
|
||||
audio: {
|
||||
state: $audioState,
|
||||
equal: $audioEqual,
|
||||
v1Sha256: $v1AudioSha256,
|
||||
v2Sha256: $v2AudioSha256,
|
||||
v1Bytes: $v1AudioBytes,
|
||||
v2Bytes: $v2AudioBytes
|
||||
},
|
||||
encoded: {
|
||||
equal: $encodedShaEqual,
|
||||
gated: $encodedShaGated,
|
||||
v1Sha256: $v1EncodedSha256,
|
||||
v2Sha256: $v2EncodedSha256
|
||||
}
|
||||
}' > "${prefix}.json"
|
||||
|
||||
rm -rf "$work"
|
||||
[ "$semantic_equal" = true ]
|
||||
}
|
||||
@@ -1,118 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
# shellcheck source=./_semantic-compare.sh
|
||||
source "$SCRIPT_DIR/_semantic-compare.sh"
|
||||
# shellcheck source=./_smoke-config.sh
|
||||
source "$SCRIPT_DIR/_smoke-config.sh"
|
||||
|
||||
for cmd in ffmpeg ffprobe jq sha256sum cmp; do
|
||||
command -v "$cmd" >/dev/null 2>&1 || {
|
||||
echo "missing test dependency: $cmd" >&2
|
||||
exit 1
|
||||
}
|
||||
done
|
||||
|
||||
WORK=$(mktemp -d)
|
||||
trap 'rm -rf "$WORK"' EXIT
|
||||
|
||||
printf '{"minPsnr":25}\n' > "$WORK/meta.json"
|
||||
[ "$(hf_resolve_psnr_threshold "" "$WORK/meta.json")" = "25" ]
|
||||
[ "$(hf_resolve_psnr_threshold "37.5" "$WORK/meta.json")" = "37.5" ]
|
||||
|
||||
ffmpeg -nostdin -v error -y \
|
||||
-f lavfi -i "color=c=red:s=64x64:r=24:d=0.5" \
|
||||
-f lavfi -i "sine=frequency=440:sample_rate=48000:duration=0.5" \
|
||||
-shortest -c:v mpeg4 -q:v 3 -c:a aac "$WORK/original.mp4"
|
||||
|
||||
# Rewrapping changes encoded bytes while preserving decoded semantics.
|
||||
ffmpeg -nostdin -v error -y -i "$WORK/original.mp4" \
|
||||
-map 0 -c copy -metadata comment="different container bytes" "$WORK/rewrapped.mp4"
|
||||
hf_compare_render_semantics "$WORK/original.mp4" "$WORK/rewrapped.mp4" "$WORK/equal"
|
||||
jq -e '
|
||||
.semanticEqual == true and
|
||||
.video.equal == true and
|
||||
.audio.equal == true and
|
||||
.metadata.equal == true and
|
||||
.duration.equal == true and
|
||||
.encoded.equal == false
|
||||
' "$WORK/equal.json" >/dev/null
|
||||
|
||||
# Map exit output as Step Functions records it: the whole state, chunk results under Chunks.
|
||||
map_exit() {
|
||||
jq -nc --arg name "$1" --argjson chunks "$2" \
|
||||
'{type: "MapStateExited", stateExitedEventDetails: {name: $name, output: ({Plan: {ChunkCount: 2}, Chunks: $chunks} | tojson)}}'
|
||||
}
|
||||
CHUNKS='[{"ChunkIndex":1,"Sha256":"bbb","FramesEncoded":12,"DurationMs":9},{"ChunkIndex":0,"Sha256":"aaa","FramesEncoded":12,"DurationMs":8}]'
|
||||
jq -n --argjson exit "$(map_exit RenderChunks "$CHUNKS")" \
|
||||
'{events: [{type: "TaskSucceeded", taskSucceededEventDetails: {output: "{}"}}, $exit]}' \
|
||||
> "$WORK/v1-history.json"
|
||||
jq -n --argjson exit "$(map_exit RenderChunksV2 "$CHUNKS")" '{events: [$exit]}' \
|
||||
> "$WORK/v2-history.json"
|
||||
hf_compare_render_semantics \
|
||||
"$WORK/original.mp4" "$WORK/rewrapped.mp4" "$WORK/chunks-equal" \
|
||||
"$WORK/v1-history.json" "$WORK/v2-history.json"
|
||||
jq -e '.semanticEqual == true and .chunks == {checked:true,equal:true,v1Count:2,v2Count:2}' \
|
||||
"$WORK/chunks-equal.json" >/dev/null
|
||||
|
||||
jq -n --argjson exit "$(map_exit RenderChunksV2 "$(jq -c '.[1].Sha256 = "different"' <<<"$CHUNKS")")" \
|
||||
'{events: [$exit]}' > "$WORK/v2-history-mismatch.json"
|
||||
if hf_compare_render_semantics \
|
||||
"$WORK/original.mp4" "$WORK/rewrapped.mp4" "$WORK/chunks-mismatch" \
|
||||
"$WORK/v1-history.json" "$WORK/v2-history-mismatch.json"; then
|
||||
echo "expected chunk-hash mismatch" >&2
|
||||
exit 1
|
||||
fi
|
||||
jq -e '.semanticEqual == false and .chunks.equal == false' \
|
||||
"$WORK/chunks-mismatch.json" >/dev/null
|
||||
|
||||
if REQUIRE_ENCODED_SHA_EQUAL=true \
|
||||
hf_compare_render_semantics "$WORK/original.mp4" "$WORK/rewrapped.mp4" "$WORK/encoded-gated"; then
|
||||
echo "expected encoded-SHA gate to reject rewrapped output" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
ffmpeg -nostdin -v error -y \
|
||||
-f lavfi -i "color=c=blue:s=64x64:r=24:d=0.5" \
|
||||
-f lavfi -i "sine=frequency=440:sample_rate=48000:duration=0.5" \
|
||||
-shortest -c:v mpeg4 -q:v 3 -c:a aac "$WORK/video-mismatch.mp4"
|
||||
if hf_compare_render_semantics \
|
||||
"$WORK/original.mp4" "$WORK/video-mismatch.mp4" "$WORK/video-mismatch"; then
|
||||
echo "expected decoded-video mismatch" >&2
|
||||
exit 1
|
||||
fi
|
||||
jq -e '.semanticEqual == false and .video.equal == false' \
|
||||
"$WORK/video-mismatch.json" >/dev/null
|
||||
|
||||
ffmpeg -nostdin -v error -y \
|
||||
-f lavfi -i "color=c=red:s=64x64:r=24:d=0.5" \
|
||||
-f lavfi -i "sine=frequency=880:sample_rate=48000:duration=0.5" \
|
||||
-shortest -c:v mpeg4 -q:v 3 -c:a aac "$WORK/audio-mismatch.mp4"
|
||||
if hf_compare_render_semantics \
|
||||
"$WORK/original.mp4" "$WORK/audio-mismatch.mp4" "$WORK/audio-mismatch"; then
|
||||
echo "expected decoded-audio mismatch" >&2
|
||||
exit 1
|
||||
fi
|
||||
jq -e '.semanticEqual == false and .video.equal == true and .audio.equal == false' \
|
||||
"$WORK/audio-mismatch.json" >/dev/null
|
||||
|
||||
ffmpeg -nostdin -v error -y \
|
||||
-f lavfi -i "color=c=red:s=64x64:r=24:d=0.5" \
|
||||
-an -c:v mpeg4 -q:v 3 "$WORK/silent.mp4"
|
||||
ffmpeg -nostdin -v error -y -i "$WORK/silent.mp4" \
|
||||
-map 0 -c copy -metadata comment="silent rewrap" "$WORK/silent-rewrapped.mp4"
|
||||
hf_compare_render_semantics \
|
||||
"$WORK/silent.mp4" "$WORK/silent-rewrapped.mp4" "$WORK/silent-equal"
|
||||
jq -e '.semanticEqual == true and .audio.state == "no-audio-on-either"' \
|
||||
"$WORK/silent-equal.json" >/dev/null
|
||||
|
||||
if hf_compare_render_semantics \
|
||||
"$WORK/original.mp4" "$WORK/silent.mp4" "$WORK/audio-stream-mismatch"; then
|
||||
echo "expected audio-stream presence mismatch" >&2
|
||||
exit 1
|
||||
fi
|
||||
jq -e '.semanticEqual == false and .audio.state == "audio-stream-mismatch"' \
|
||||
"$WORK/audio-stream-mismatch.json" >/dev/null
|
||||
|
||||
echo "semantic compare shell tests passed"
|
||||
@@ -31,7 +31,6 @@
|
||||
# --region <region> (default: $AWS_REGION or us-east-1)
|
||||
# --profile <name> (default: $AWS_PROFILE, otherwise the AWS
|
||||
# default profile resolution chain)
|
||||
# --plan-protocol <v1|v2|both> (default: v2)
|
||||
# --keep-stack (skip `sam delete` at the end)
|
||||
# --skip-build (skip the ZIP rebuild; use the existing one)
|
||||
#
|
||||
@@ -54,8 +53,6 @@ set -euo pipefail
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
REPO_ROOT="$(cd "$SCRIPT_DIR/../../.." && pwd)"
|
||||
SAM_DIR="$SCRIPT_DIR/.."
|
||||
# shellcheck source=./_semantic-compare.sh
|
||||
source "$SCRIPT_DIR/_semantic-compare.sh"
|
||||
# shellcheck source=./_s3-purge.sh
|
||||
source "$SCRIPT_DIR/_s3-purge.sh"
|
||||
# shellcheck source=./_smoke-config.sh
|
||||
@@ -82,7 +79,6 @@ SMOKE_RUN_ID="${HYPERFRAMES_SMOKE_RUN_ID:-$(hf_new_smoke_run_id)}"
|
||||
STACK_NAME="${STACK_NAME:-hyperframes-lambda-smoke-${SMOKE_RUN_ID}}"
|
||||
AWS_REGION="${AWS_REGION:-us-east-1}"
|
||||
AWS_PROFILE="${AWS_PROFILE:-}"
|
||||
PLAN_PROTOCOL="${PLAN_PROTOCOL:-v2}"
|
||||
KEEP_STACK="false"
|
||||
SKIP_BUILD="false"
|
||||
REQUIRE_ENCODED_SHA_EQUAL="${REQUIRE_ENCODED_SHA_EQUAL:-false}"
|
||||
@@ -110,7 +106,6 @@ Flags:
|
||||
--stack-name <name> SAM stack name (default: hyperframes-lambda-smoke-<unique-run-id>)
|
||||
--region <region> AWS region (default: $AWS_REGION or us-east-1)
|
||||
--profile <name> AWS profile (default: $AWS_PROFILE)
|
||||
--plan-protocol <v1|v2|both> plan transport(s) to compare (default: v2)
|
||||
--reserved-concurrency <N> Lambda Map MaxConcurrency cap (default: 16)
|
||||
--keep-stack skip `sam delete` at the end (manual teardown later)
|
||||
--require-encoded-sha-equal also gate byte-identical encoded MP4 output
|
||||
@@ -138,7 +133,6 @@ while [ $# -gt 0 ]; do
|
||||
--stack-name) STACK_NAME="$2"; shift 2 ;;
|
||||
--region) AWS_REGION="$2"; shift 2 ;;
|
||||
--profile) AWS_PROFILE="$2"; shift 2 ;;
|
||||
--plan-protocol) PLAN_PROTOCOL="$2"; shift 2 ;;
|
||||
--keep-stack) KEEP_STACK="true"; shift ;;
|
||||
--require-encoded-sha-equal) REQUIRE_ENCODED_SHA_EQUAL="true"; shift ;;
|
||||
--skip-build) SKIP_BUILD="true"; shift ;;
|
||||
@@ -148,10 +142,6 @@ while [ $# -gt 0 ]; do
|
||||
esac
|
||||
done
|
||||
|
||||
if [ "$PLAN_PROTOCOL" != "v1" ] && [ "$PLAN_PROTOCOL" != "v2" ] && [ "$PLAN_PROTOCOL" != "both" ]; then
|
||||
echo "ERROR: --plan-protocol must be v1, v2, or both." >&2
|
||||
exit 1
|
||||
fi
|
||||
PROJECT_NAME=$(hf_derive_project_name "$STACK_NAME")
|
||||
|
||||
# Export AWS_REGION + AWS_PROFILE so `aws` and `sam` inherit them via the
|
||||
@@ -519,12 +509,7 @@ RESULTS_JSON="$ARTIFACT_DIR/results.json"
|
||||
echo "[]" > "$RESULTS_JSON"
|
||||
|
||||
IFS=',' read -ra COUNTS <<< "$CHUNK_COUNTS"
|
||||
if [ "$PLAN_PROTOCOL" = "both" ]; then
|
||||
PROTOCOLS=(v1 v2)
|
||||
else
|
||||
PROTOCOLS=("$PLAN_PROTOCOL")
|
||||
fi
|
||||
for PROTOCOL in "${PROTOCOLS[@]}"; do
|
||||
PROTOCOL="v2"
|
||||
for N in "${COUNTS[@]}"; do
|
||||
EXEC_NAME="smoke-$PROTOCOL-N$N-$(date +%s)"
|
||||
OUTPUT_KEY="renders/$EXEC_NAME/output.mp4"
|
||||
@@ -623,41 +608,6 @@ for N in "${COUNTS[@]}"; do
|
||||
'. += [{planProtocol: $protocol, chunkCount: $n, wallClockMs: $wall, psnrAvgDb: ($psnr|tonumber), output: "renders/\($protocol)-N\($n)-output.mp4", history: "renders/\($protocol)-N\($n)-history.json"}]' \
|
||||
"$RESULTS_JSON" > "$RESULTS_JSON.tmp" && mv "$RESULTS_JSON.tmp" "$RESULTS_JSON"
|
||||
done
|
||||
done
|
||||
|
||||
# ── 6. Direct v1 ↔ v2 semantic equivalence ────────────────────────────────
|
||||
SEMANTIC_FAILED=0
|
||||
SEMANTIC_RESULTS_JSON="$ARTIFACT_DIR/semantic-comparisons.json"
|
||||
echo "[]" > "$SEMANTIC_RESULTS_JSON"
|
||||
if [ "$PLAN_PROTOCOL" = "both" ]; then
|
||||
for N in "${COUNTS[@]}"; do
|
||||
V1_OUTPUT="$ARTIFACT_DIR/renders/v1-N$N-output.mp4"
|
||||
V2_OUTPUT="$ARTIFACT_DIR/renders/v2-N$N-output.mp4"
|
||||
V1_HISTORY="$ARTIFACT_DIR/renders/v1-N$N-history.json"
|
||||
V2_HISTORY="$ARTIFACT_DIR/renders/v2-N$N-history.json"
|
||||
SEMANTIC_PREFIX="$ARTIFACT_DIR/renders/v1-v2-N$N"
|
||||
COMPARE_STATUS=0
|
||||
if hf_compare_render_semantics \
|
||||
"$V1_OUTPUT" "$V2_OUTPUT" "$SEMANTIC_PREFIX" "$V1_HISTORY" "$V2_HISTORY"; then
|
||||
echo "PASS: v1/v2 semantic equivalence at N=$N"
|
||||
else
|
||||
COMPARE_STATUS=$?
|
||||
if [ ! -f "${SEMANTIC_PREFIX}.json" ]; then
|
||||
jq -n --argjson status "$COMPARE_STATUS" \
|
||||
'{semanticEqual: false, comparisonError: true, comparisonExitCode: $status}' \
|
||||
> "${SEMANTIC_PREFIX}.json"
|
||||
fi
|
||||
echo "FAIL: v1/v2 semantic comparison at N=$N exited $COMPARE_STATUS (see ${SEMANTIC_PREFIX}.json)" >&2
|
||||
SEMANTIC_FAILED=$((SEMANTIC_FAILED + 1))
|
||||
fi
|
||||
jq --argjson n "$N" --slurpfile comparison "${SEMANTIC_PREFIX}.json" \
|
||||
'. += [($comparison[0] + {chunkCount: $n})]' \
|
||||
"$SEMANTIC_RESULTS_JSON" > "$SEMANTIC_RESULTS_JSON.tmp" &&
|
||||
mv "$SEMANTIC_RESULTS_JSON.tmp" "$SEMANTIC_RESULTS_JSON"
|
||||
jq -r '" chunks=\(.chunks.equal // "error") decoded-video=\(.video.equal // "error") audio=\(.audio.equal // "error") metadata=\(.metadata.equal // "error") duration=\(.duration.equal // "error") encoded-sha=\(.encoded.equal // "error") (informational unless gated)"' \
|
||||
"${SEMANTIC_PREFIX}.json"
|
||||
done
|
||||
fi
|
||||
|
||||
# ── 7. Gate on baseline PSNR threshold ────────────────────────────────────
|
||||
FAILED=0
|
||||
@@ -680,10 +630,6 @@ jq -r '.[] | [.planProtocol, .chunkCount, .wallClockMs, .psnrAvgDb] | @tsv' "$RE
|
||||
echo
|
||||
echo "Artifacts: $ARTIFACT_DIR"
|
||||
|
||||
if [ "$SEMANTIC_FAILED" -gt 0 ]; then
|
||||
echo "FAILED ($SEMANTIC_FAILED v1/v2 semantic mismatches)" >&2
|
||||
cleanup_and_exit 6
|
||||
fi
|
||||
if [ "$FAILED" -gt 0 ]; then
|
||||
echo "FAILED ($FAILED renders below PSNR threshold)" >&2
|
||||
cleanup_and_exit 5
|
||||
|
||||
Reference in New Issue
Block a user