MediaConvert の Video Passthrough で映像フレームは保持されるのか、FFmpeg で比較してみた
はじめに
テクニカルサポートの 片方 です。
AWS Elemental MediaConvert には、入力動画の映像エッセンスを再エンコードせず、対応する出力コンテナへ再パッケージ化できる Video Passthrough があります。
Video Passthrough を使用すると、H.264 / AVC または H.265 / HEVC の入力映像を、再エンコードせずに MP4、HLS、DASH、MPEG-TS などの対応コンテナへ出力できます。
「再エンコードしない」と聞くと、入力ファイルと出力ファイルがバイト単位で同一になるように思えます。しかし、MP4 ファイルには映像以外にもコンテナメタデータ、タイムスタンプ、ストリーム情報、データの格納順序などが含まれます。
そのため、本記事では Video Passthrough 出力を入力動画と比較し、以下の観点で映像フレームが保持されるかを確認します。
- 映像ストリームのメタデータ
- 映像パケットのペイロードハッシュ
- デコード後フレームの比較
また、比較手順が差分を検出できることを確認するため、同じ入力動画を H.264 / AVC で再エンコードした出力も対照群として作成します。
比較対象は映像ストリームのみです。音声、字幕、コンテナメタデータ、およびファイル全体のバイト列は、映像フレームの保持とは別の観点として扱います。
本記事では、Windows 上の WSL 2 と Visual Studio Code を使用して検証しました。
先に結論から
H.264 / MP4 の入力動画を MediaConvert の Video Passthrough で MP4 に出力し、入力動画と比較しました。
| 比較方法 | Video Passthrough 出力 | H.264 再エンコード出力 |
|---|---|---|
| 映像ストリームのメタデータ | 主要項目が入力動画と一致 | 主要項目が入力動画と一致 |
| 映像パケットのペイロードハッシュ | 1,064 件中 1,053 件が一致、11 件が不一致 | 1,064 件すべてが不一致 |
| デコード後フレームの比較 | framemd5 のフレームレコードが完全一致 |
framemd5 のフレームレコードが不一致 |
| ファイル全体の SHA-256 | 入力動画と不一致 | 入力動画と不一致 |
Video Passthrough 出力では、ファイル全体の SHA-256 は入力動画と一致せず、映像パケットのペイロードハッシュにも一部差分がありました。
一方、FFmpeg の framemd5 で比較したフレームレコードは、入力動画と Video Passthrough 出力で完全に一致しました。
今回の H.264 / MP4 入力および MP4 出力の条件では、ファイル全体のハッシュや圧縮済み映像パケットのハッシュだけで、映像フレームが保持されたかを判断することは適切ではありませんでした。映像フレームの保持を確認するには、デコード後フレームを比較する方法が有効でした。
検証環境について
検証環境は以下のとおりです。
| 項目 | 内容 |
|---|---|
| AWS リージョン | ap-northeast-1 |
| AWS サービス | AWS Elemental MediaConvert、Amazon S3 |
| ローカル環境 | Windows 上の WSL 2 |
| Linux ディストリビューション | Ubuntu 22.04.5 LTS |
| エディタ | Visual Studio Code |
| AWS CLI | 2.35.21 |
| FFmpeg | 4.4.2-0ubuntu0.22.04.1 |
| FFprobe | 4.4.2-0ubuntu0.22.04.1 |
| 入力コンテナ | MP4 |
| 入力映像コーデック | H.264 / AVC |
| 入力解像度 | 2560 × 1440 |
| 入力フレームレート | 30000 / 1001 fps(約 29.97 fps) |
| 入力動画の長さ | 35.501667 秒 |
| 比較対象 | 映像ストリームのみ |
ローカルでは入力動画を input/source.mp4 として管理します。Amazon S3 には、Pixabay からダウンロードした元ファイル名を維持して 359930.mp4 としてアップロードしました。
Video Passthrough の出力コンテナには MP4 を使用します。出力フレームレートは ソースに従う(Follow source)とします。
やってみた
ローカルの検証環境を準備する
映像パケットおよびデコード後フレームを比較するため、WSL 2 上の Ubuntu に FFmpeg をインストールします。
WSL が未導入の場合は、管理者として PowerShell を起動し、以下を実行します。
wsl --install
コマンドの実行後に再起動を求められた場合は、Windows を再起動します。再起動後、Ubuntu の初回起動時に Linux ユーザー名とパスワードを設定します。
Ubuntu を起動したら、パッケージ一覧を更新して FFmpeg をインストールします。
sudo apt update
sudo apt install -y ffmpeg
本記事では、Amazon S3 に入力動画をアップロードし、MediaConvert の出力動画をダウンロードするために AWS CLI を使用します。AWS CLI が未導入の場合は、AWS 公式ドキュメントを参照してインストールしてください。
AWS CLI、FFmpeg、および FFprobe が実行できることを確認します。
今回の検証では、FFprobe を使用して映像ストリームと映像パケットの情報を取得します。また、FFmpeg の framemd5 を使用して、デコード後フレームのハッシュを出力します。
続いて、検証用の作業ディレクトリを作成します。
mkdir -p ~/work/mediaconvert-passthrough-test/{input,output,hashes,metadata}
cd ~/work/mediaconvert-passthrough-test
| ディレクトリ | 用途 |
|---|---|
| input | 入力動画を配置します。 |
| output | MediaConvert の出力動画を保存します。 |
| hashes | 各種ハッシュを保存します。 |
| metadata | FFprobe の出力を保存します。 |
作業ディレクトリの構成は、tree コマンドで確認できます。
tree コマンドが見つからない場合は、以下のコマンドでインストールします。
sudo apt install -y tree
tree
実行結果は以下のとおりです。
.
├── hashes
├── input
├── metadata
└── output
4 directories, 0 files

入力動画を確認する
入力動画には、利用条件を確認した Pixabay のフリー素材を使用します。比較条件を単純にするため、H.264 / AVC でエンコードされた MP4 動画を選択しました。
ダウンロードした動画を input/source.mp4 として配置します。
cp "<ダウンロードした動画のパス>" input/source.mp4
ファイルが配置されたことを確認します。
ls -lh input/source.mp4
続いて、FFprobe で入力動画の映像ストリーム情報を確認します。
ffprobe \
-v error \
-select_streams v:0 \
-show_entries stream=codec_name,codec_long_name,profile,width,height,pix_fmt,r_frame_rate,avg_frame_rate,nb_frames,duration \
-of default=noprint_wrappers=1 \
input/source.mp4
検証時の実行結果は以下のとおりです。
codec_name=h264
codec_long_name=H.264 / AVC / MPEG-4 AVC / MPEG-4 part 10
profile=High
width=2560
height=1440
pix_fmt=yuv420p
r_frame_rate=30000/1001
avg_frame_rate=30000/1001
duration=35.501667
nb_frames=1064
入力動画の仕様を以下にまとめます。
| 項目 | 値 |
|---|---|
| 映像コーデック | H.264 / AVC |
| プロファイル | High |
| 解像度 | 2560 × 1440 |
| ピクセルフォーマット | yuv420p |
| フレームレート | 30000 / 1001 fps(約 29.97 fps) |
| 映像の長さ | 35.501667 秒 |
| FFprobe が取得した映像フレーム数 | 1,064 |
codec_name=h264 を確認できたため、この動画を Video Passthrough の入力として使用します。
入力ファイルを識別するため、ファイル全体の SHA-256 を保存します。
sha256sum input/source.mp4 | tee hashes/source.file.sha256.txt
| ハッシュ | 対象 | 用途 |
|---|---|---|
| ファイル全体の SHA-256 | MP4 コンテナを含むファイル全体 | 入力ファイルの識別 |
| 映像パケットのペイロードハッシュ | 圧縮済み映像パケットのデータ部 | 圧縮済み映像データの比較 |
| デコード後フレームのハッシュ | デコード後の映像フレーム | 映像フレームの比較 |
| 入力動画に使用したフリー素材は以下のとおりです。 |
使用したフリー素材は以下のとおりです。
| 項目 | 内容 |
|---|---|
| 素材配布元 | Pixabay |
| 素材名 | 牧草地、夏、咲く、雰囲気 |
| 素材ページ | Pixabay の素材ページ |
| ライセンス | Pixabay Content License |
| ライセンス確認日 | 2026 年 8 月 30 日 |
Amazon S3 バケットと IAM ロールを準備する
MediaConvert の入力動画と出力動画の保存先として Amazon S3 を使用します。今回は、MediaConvert のジョブを作成するリージョンと同じリージョンに検証用 S3 バケットを用意しました。
s3://<検証用バケット名>/
├── input/
│ └── source.mp4
└── output/
├── passthrough/
└── reencoded/
入力動画を Amazon S3 へアップロードする
ローカルの input/source.mp4 を、S3 では 359930.mp4 としてアップロードします。
aws s3 cp \
input/source.mp4 \
s3://<検証用バケット名>/input/359930.mp4
アップロード後、オブジェクトを確認します。
aws s3 ls s3://<検証用バケット名>/input/
以降の MediaConvert ジョブでは、以下の S3 URI を入力動画として指定します。
s3://<検証用バケット名>/input/359930.mp4

MediaConvert のサービスロールを作成する
MediaConvert が S3 上の入力動画を読み取り、出力動画を書き込めるように IAM サービスロールを作成します。
MediaConvert コンソールで [ジョブを作成] を選択し、[ジョブの設定] の [AWS の統合] を開きます。[サービスアクセス] の [サービスロールの制御] で、[新しいサービスロールを作成し、アクセス許可を設定] を選択します。
| 項目 | 設定 |
|---|---|
| サービスロールの制御 | 新しいサービスロールを作成し、アクセス許可を設定 |
| 新しいロール名 | <例: MediaConvertPassthroughTestRole> |
| S3 の入力場所 | s3://<検証用バケット名>/input/ |
| S3 の出力場所 | s3://<検証用バケット名>/output/ |
| API Gateway エンドポイントの呼び出し | 許可しない |
S3 の入力場所には、入力動画を配置した input/ を指定します。S3 の出力場所には、MediaConvert の出力動画を配置する output/ を指定します。
作成後は IAM コンソールでサービスロールの権限ポリシーを確認し、検証に不要な S3 バケットへのアクセスが許可されていないことを確認します。

MediaConvert で Video Passthrough 出力を作成する
入力動画を Video Passthrough で MP4 ファイルへ再パッケージ化します。
入力動画を指定する
[入力 1] の [入力ファイル URL] に以下を指定します。
s3://<検証用バケット名>/input/359930.mp4
今回は、1 本の入力動画だけを使用します。

File グループを追加する
[出力グループ] の [追加] から [File グループ] を選択します。送信先には以下を指定します。
s3://<検証用バケット名>/output/passthrough/
出力先には passthrough/ プレフィックスを指定し、後続で作成する再エンコード出力と分けます。

Video Passthrough を設定する

出力設定で以下を指定します。
| 項目 | 設定値 |
|---|---|
| コンテナ | MPEG-4 コンテナ |
| 名前修飾子 | _passthrough |
| ビデオコーデック | パススルー |
| フレームレート | ソースに従う(Follow source) |
パススルー を選択すると、映像のビットレート、解像度、プロファイルなど、再エンコード時に使用する映像設定は指定できません。

声出力を削除する
本記事では映像ストリームのみを比較するため、[オーディオ 1] を選択して [オーディオの削除] を実行します。

ジョブを作成する
サービスロールが選択されていることを確認し、[作成] を選択します。
| 項目 | 設定値 |
|---|---|
| 入力ファイル | s3://<検証用バケット名>/input/359930.mp4 |
| 出力グループ | File グループ |
| 出力先 | s3://<検証用バケット名>/output/passthrough/ |
| 出力コンテナ | MPEG-4 コンテナ |
| ビデオコーデック | パススルー |
| フレームレート | ソースに従う(Follow source) |
| 音声出力 | なし |

ジョブを作成すると、MediaConvert のジョブ一覧へ遷移します。ジョブのステータスが COMPLETE になるまで待ちます。

出力先 URI にベース名を指定せず、名前修飾子に _passthrough を指定したため、出力ファイル名は以下となりました。
359930_passthrough.mp4
以降の検証では、この出力ファイルをローカル環境へダウンロードし、passthrough.mp4 として扱います。

対照群として H.264 再エンコード出力を作成する
比較手順が再エンコードによる差分を検出できることを確認するため、同じ入力動画を H.264 / AVC で再エンコードします。
入力ファイルには、Video Passthrough と同じ S3 URI を指定します。
s3://<検証用バケット名>/input/359930.mp4

File グループを追加する
File グループを追加し、以下を指定します。
| 項目 | 設定値 |
|---|---|
| カスタムグループ名 | H.264 Re-encode MP4 |
| 送信先 | s3://<検証用バケット名>/output/reencoded/ |
| S3 ストレージクラス | スタンダード |
| サーバー側の暗号化 | オフ |
| アクセスコントロール | オフ |
| フレームごとのメトリクス | オフ |
出力先には reencoded/ プレフィックスを指定します。Video Passthrough 出力の output/passthrough/ と分けることで、出力ファイルを取り違えないようにします。

H.264 / AVC を設定する
出力設定で以下を指定します。
| 項目 | 設定値 |
|---|---|
| 名前修飾子 | _reencoded |
| 拡張子 | 空欄 |
| コンテナ | MPEG-4 コンテナ |
| ビデオコーデック | MPEG-4 AVC (H.264) |
| レート制御モード | CBR |
| ビットレート | 1,000,000 bps |
| フレームレート | ソースに従う(Follow source) |
| 音声出力 | なし |
1,000,000 bps は 2560 × 1440 の映像を画質評価するには低い値です。本記事では画質を評価するのではなく、再エンコードによる差分を明確に確認するため、意図的に低い値を指定しました。

ジョブを作成する
設定内容を確認したら、画面下部の [作成] を選択します。作成前に、前節で作成した MediaConvert 用サービスロールが選択されていることを確認します。
今回のジョブ設定の要点は以下のとおりです。
| 項目 | 設定値 |
|---|---|
| 入力ファイル | s3://<検証用バケット名>/input/359930.mp4 |
| 出力グループ | File グループ |
| 出力先 | s3://<検証用バケット名>/output/reencoded/ |
| 出力コンテナ | MPEG-4 コンテナ |
| ビデオコーデック | MPEG-4 AVC (H.264) |
| レート制御モード | CBR |
| ビットレート | 1,000,000 bps |
| フレームレート | ソースに従う(Follow source) |
| 音声出力 | なし |
ジョブを作成後、ステータスが COMPLETE になったことを確認します。
ジョブが完了すると、Amazon S3 の output/reencoded/ プレフィックスに MP4 ファイルが出力されます。
出力先 URI にベース名を指定せず、名前修飾子に _reencoded を指定したため、今回の出力ファイル名は以下となりました。
359930_reencoded.mp4
以降の検証では、この出力ファイルをローカル環境へダウンロードし、reencoded.mp4 として扱います。

確認してみた
出力動画をローカル環境へダウンロードする
MediaConvert の出力動画を、ハッシュ比較に使用する WSL 環境へダウンロードします。
まず、S3 に出力されたファイル名を確認します。
aws s3 ls s3://<検証用バケット名>/output/passthrough/
aws s3 ls s3://<検証用バケット名>/output/reencoded/
今回の出力ファイルは以下のとおりでした。
359930_passthrough.mp4
359930_reencoded.mp4
ローカルでは、以降のコマンドを簡潔にするため、passthrough.mp4 と reencoded.mp4 として保存します。
aws s3 cp \
s3://<検証用バケット名>/output/passthrough/359930_passthrough.mp4 \
output/passthrough.mp4
aws s3 cp \
s3://<検証用バケット名>/output/reencoded/359930_reencoded.mp4 \
output/reencoded.mp4
ダウンロード後、比較対象の 3 ファイルがそろっていることを確認します。
ls -lh \
input/source.mp4 \
output/passthrough.mp4 \
output/reencoded.mp4
比較対象は以下の 3 ファイルです。
| 役割 | ローカルファイル |
|---|---|
| 入力動画 | input/source.mp4 |
| Video Passthrough 出力 | output/passthrough.mp4 |
| H.264 再エンコード出力 | output/reencoded.mp4 |
映像ストリームのメタデータを比較する
FFprobe で映像ストリームのメタデータを比較します。-count_frames を指定し、実際に読み取ったフレーム数である nb_read_frames を確認します。以下のコマンドを実行します。
for file in \
input/source.mp4 \
output/passthrough.mp4 \
output/reencoded.mp4
do
echo "===== $file ====="
ffprobe \
-v error \
-count_frames \
-select_streams v:0 \
-show_entries stream=codec_name,profile,width,height,pix_fmt,r_frame_rate,avg_frame_rate,nb_read_frames,duration,bit_rate \
-of default=noprint_wrappers=1 \
"$file"
echo
done
検証時では実行結果は以下のとおりです。
===== input/source.mp4 =====
codec_name=h264
profile=High
width=2560
height=1440
pix_fmt=yuv420p
r_frame_rate=30000/1001
avg_frame_rate=30000/1001
duration=35.501667
bit_rate=11760880
nb_read_frames=1064
===== output/passthrough.mp4 =====
codec_name=h264
profile=High
width=2560
height=1440
pix_fmt=yuv420p
r_frame_rate=30000/1001
avg_frame_rate=30000/1001
duration=35.502133
bit_rate=11760827
nb_read_frames=1064
===== output/reencoded.mp4 =====
codec_name=h264
profile=High
width=2560
height=1440
pix_fmt=yuv420p
r_frame_rate=30000/1001
avg_frame_rate=30000/1001
duration=35.502133
bit_rate=1012745
nb_read_frames=1064
結果を比較すると、以下のとおりでした。
| 項目 | 入力動画 | Video Passthrough 出力 | H.264 再エンコード出力 |
|---|---|---|---|
| 映像コーデック | H.264 / AVC | H.264 / AVC | H.264 / AVC |
| プロファイル | High | High | High |
| 解像度 | 2560 × 1440 | 2560 × 1440 | 2560 × 1440 |
| ピクセルフォーマット | yuv420p | yuv420p | yuv420p |
| フレームレート | 30000 / 1001 fps | 30000 / 1001 fps | 30000 / 1001 fps |
| 読み取ったフレーム数 | 1,064 | 1,064 | 1,064 |
| 映像ストリームの長さ | 35.501667 秒 | 35.502133 秒 | 35.502133 秒 |
| ビットレート | 11,760,880 bps | 11,760,827 bps | 1,012,745 bps |
Video Passthrough 出力では、主要なメタデータが入力動画と一致しました。一方、H.264 再エンコード出力もコーデック、解像度、フレームレート、およびフレーム数が入力動画と一致しています。
そのため、メタデータだけでは再エンコードの有無を判断できません。ミリ秒 です。メタデータ上の時間表現には差があるものの、映像フレーム数はすべて 1,064 でした。

映像エッセンスが保持されたかは、このメタデータ比較だけでは判断できません。次に、映像パケットのペイロードハッシュおよびデコード後フレームのハッシュを比較します。
映像パケットのペイロードハッシュを比較する
続いて、圧縮済みの映像パケットに含まれるペイロードデータを比較します。
MP4 ファイル全体には、映像以外にもコンテナメタデータ、タイムスタンプ、ストリーム情報などが含まれます。そこで、ファイル全体ではなく、映像ストリームの各パケットに含まれるデータ部の SHA-256 を比較します。
FFprobe の -show_data_hash sha256 を使用して、映像パケットごとの SHA-256 を出力します。-select_streams v:0 を指定することで、先頭の映像ストリームだけを比較対象とします。
for file in \
input/source.mp4 \
output/passthrough.mp4 \
output/reencoded.mp4
do
base_name=$(basename "$file" .mp4)
ffprobe \
-v error \
-select_streams v:0 \
-show_packets \
-show_entries packet=data_hash \
-show_data_hash sha256 \
-of default=noprint_wrappers=1:nokey=1 \
"$file" \
> "hashes/${base_name}.packet.payload.sha256.txt"
done
各ファイルで取得した映像パケットペイロードハッシュの件数を確認します。
wc -l hashes/*.packet.payload.sha256.txt
実行結果は以下のとおりです。
1064 hashes/passthrough.packet.payload.sha256.txt
1064 hashes/reencoded.packet.payload.sha256.txt
1064 hashes/source.packet.payload.sha256.txt
3192 total
今回のファイルでは、3 つの比較対象すべてから 1,064 件の映像パケットペイロードハッシュを取得できました。
入力動画と Video Passthrough 出力を比較する
入力動画と Video Passthrough 出力で、映像パケットのペイロードハッシュが完全に一致するかを確認します。
if cmp -s \
hashes/source.packet.payload.sha256.txt \
hashes/passthrough.packet.payload.sha256.txt
then
echo "PASS: input and passthrough packet payload hashes are identical"
else
echo "FAIL: input and passthrough packet payload hashes differ"
fi
実行結果は以下のとおりです。
FAIL: input and passthrough packet payload hashes differ
入力動画と Video Passthrough 出力では、映像パケットのペイロードハッシュ列は完全一致しませんでした。
続いて、同じ位置にあるパケット同士を比較し、一致・不一致の件数を確認します。
paste \
hashes/source.packet.payload.sha256.txt \
hashes/passthrough.packet.payload.sha256.txt \
| awk -F '\t' '
$1 == $2 { same++ }
$1 != $2 { different++ }
END {
print "same=" same ", different=" different
}'
実行結果は以下のとおりです。
same=1053, different=11
全 1,064 件のうち、1,053 件は一致し、11 件は不一致でした。
差分の一部を確認します。
diff -u \
hashes/source.packet.payload.sha256.txt \
hashes/passthrough.packet.payload.sha256.txt \
| head -n 30
今回の結果では、88、178、268 行目などで差分を確認できました。ただし、この結果だけでは差分の具体的な要因までは判断できません。
入力動画と H.264 再エンコード出力を比較する
次に、入力動画と H.264 再エンコード出力の映像パケットペイロードハッシュを比較します。
paste \
hashes/source.packet.payload.sha256.txt \
hashes/reencoded.packet.payload.sha256.txt \
| awk -F '\t' '
$1 == $2 { same++ }
$1 != $2 { different++ }
END {
print "same=" same ", different=" different
}'
実行結果は以下のとおりです。
same=, different=1064
入力動画と H.264 再エンコード出力では、全 1,064 件の映像パケットペイロードハッシュが不一致でした。
再エンコードでは圧縮済み映像データが新たに生成されるため、Video Passthrough 出力と比較して差分が大きくなる結果となりました。
今回の結果をまとめます。
| 比較 | 一致 | 不一致 |
|---|---|---|
| 入力動画 vs Video Passthrough 出力 | 1,053 | 11 |
| 入力動画 vs H.264 再エンコード出力 | 0 | 1,064 |
Video Passthrough 出力では、映像パケットペイロードハッシュが完全一致にはなりませんでした。一方、H.264 再エンコード出力では、すべてのパケットで差分を検出できました。
次に、映像をデコードした後のフレームが一致するかを確認します。
デコード後フレームのハッシュを比較する
映像パケットのペイロードハッシュでは、入力動画と Video Passthrough 出力に 11 件の差分がありました。
そこで、圧縮済み映像パケットではなく、映像をデコードした後のフレームが一致するかを確認します。
FFmpeg の framemd5 を使用して、映像ストリームをデコードした後の各フレームの MD5 を出力します。
for file in \
input/source.mp4 \
output/passthrough.mp4 \
output/reencoded.mp4
do
base_name=$(basename "$file" .mp4)
ffmpeg \
-v error \
-i "$file" \
-map 0:v:0 \
-an \
-f framemd5 \
"hashes/${base_name}.frame.md5"
done
framemd5 の出力にはコメント行が含まれます。比較対象をフレームのハッシュ情報だけに限定するため、コメント行を除外します。
grep -v '^#' hashes/source.frame.md5 > hashes/source.frame.data.md5
grep -v '^#' hashes/passthrough.frame.md5 > hashes/passthrough.frame.data.md5
grep -v '^#' hashes/reencoded.frame.md5 > hashes/reencoded.frame.data.md5
入力動画と Video Passthrough 出力を比較する
入力動画と Video Passthrough 出力のデコード後フレームハッシュを比較します。
if cmp -s \
hashes/source.frame.data.md5 \
hashes/passthrough.frame.data.md5
then
echo "PASS: input and passthrough decoded frame hashes are identical"
else
echo "FAIL: input and passthrough decoded frame hashes differ"
fi
実行結果は以下のとおりです。
PASS: input and passthrough decoded frame hashes are identical
入力動画と Video Passthrough 出力では、framemd5 のフレームレコードが完全に一致しました。
前節では、映像パケットペイロードハッシュに 11 件の差分がありました。一方、デコード後フレームを対象とした比較では、入力動画と Video Passthrough 出力に差分はありませんでした。
この結果から、今回の H.264 / MP4 入力および MP4 出力の条件では、Video Passthrough 出力における映像パケットペイロードの一部差分は、FFmpeg でデコードした映像フレームに影響しないことを確認できました。
入力動画と H.264 再エンコード出力を比較する
次に、入力動画と H.264 再エンコード出力の framemd5 出力を比較します。
if cmp -s \
hashes/source.frame.data.md5 \
hashes/reencoded.frame.data.md5
then
echo "UNEXPECTED: input and re-encoded decoded frame hashes are identical"
else
echo "EXPECTED: input and re-encoded decoded frame hashes differ"
fi
実行結果は以下のとおりです。
EXPECTED: input and re-encoded decoded frame hashes differ
入力動画と H.264 再エンコード出力では、framemd5 のフレームレコードは一致しませんでした。
今回の結果をまとめます。
| 比較 | 映像パケットペイロードハッシュ | デコード後フレーム |
|---|---|---|
| 入力動画 vs Video Passthrough 出力 | 11 件が不一致 | framemd5 のフレームレコードが完全一致 |
| 入力動画 vs H.264 再エンコード出力 | 全 1,064 件が不一致 | framemd5 のフレームレコードが不一致 |
Video Passthrough 出力では、圧縮済み映像パケットのペイロード比較だけでは一部差分が検出されました。一方、デコード後フレームを比較すると、入力動画と完全に一致しました。
そのため、今回の検証条件では、Video Passthrough 出力によりデコード後の映像フレームが保持されたと判断します。
検証結果
[USER@HOST:]~/work/mediaconvert-passthrough-test$ wc -l hashes/*.packet.payload.sha256.txt
1064 hashes/passthrough.packet.payload.sha256.txt
1064 hashes/reencoded.packet.payload.sha256.txt
1064 hashes/source.packet.payload.sha256.txt
3192 total
[USER@HOST:]~/work/mediaconvert-passthrough-test$ if cmp -s \
hashes/source.packet.payload.sha256.txt \
hashes/passthrough.packet.payload.sha256.txt
then
echo "PASS: input and passthrough packet payload hashes are identical"
else
echo "FAIL: input and passthrough packet payload hashes differ"
fi
FAIL: input and passthrough packet payload hashes differ
[USER@HOST:]~/work/mediaconvert-passthrough-test$ diff -u \
hashes/source.packet.payload.sha256.txt \
hashes/passthrough.packet.payload.sha256.txt \
| head -n 30
--- hashes/source.packet.payload.sha256.txt 2026-08-30 15:19:14.403151678 +0900
+++ hashes/passthrough.packet.payload.sha256.txt 2026-08-30 15:19:14.696893010 +0900
@@ -88,7 +88,7 @@
SHA256:a99c136301372af3d16ea8aa071cbc3faa3bfa3b6c124e42c0cd58384a5521d3
SHA256:32ada1d9b599abc8d8aa5c42e5bd35a2bc07670f3b61b6619c78f67dd9e2a0e4
SHA256:30ceb218559752a76129d30581b02d070c76e8296a29bfec868dd4c0093d5214
-SHA256:054025dfbb6acceb0c66bf1f996e4689e22574bd47ce865aede0e42801ca3daf
+SHA256:be60936aafee40a3c0a3e4d58181616cdf4ffcdc7ad4c62a04d573ea400cab23
SHA256:06cb8acc7a8600a8a1402dfafcf1f0723cc523e2713fee6265106f092851cc88
SHA256:32dc278f685e892551ce2290a3537cf1280cce35b747713d519b89a1851ff130
SHA256:8eeaaaf4eb8a482366563832f0932d485c56f00170d1d38000502c2d2efd56f4
@@ -178,7 +178,7 @@
SHA256:47335c5a72e6dc93cf3ae2aa34dedc7df567c0a6da1c9f423bdbda71cf86bb75
SHA256:ff619a82278f874b17d43bb2c170c30ee915d3eeb0ed7b0e32c0a087be67d418
SHA256:0962d17402a91873b9dd86d6799411194f03a6bf04c15567f750023393c64471
-SHA256:a5db38e2058f3ca0d9ca80d0207c2466deabe489bf4634d2ae510a4de360a6bb
+SHA256:87c0a49764bd2a7791959b3be095738a681d1786035ac03c035ffcdb9ee2ed6a
SHA256:ad7f3c1715ef1c00855ab5592773c275899deb68b84b8de4872461c37770995e
SHA256:22fae26055baef8da4253b069c206a907536c3da368f1f9af40bebd3244896ca
SHA256:b477131e1ef96a243f83a9b9c981b20e6fe4c4a90e45c10a1f04ec410ccb853d
@@ -268,7 +268,7 @@
SHA256:4e8dc41b61dfb70e008ce16f241fbbe4b834902df9753b5bf6ab5a7214313596
SHA256:06ab3563171fa03b66d1ae309a70f418e8a6df701ae1483e2a8998bfd3a3c503
SHA256:7d33de36bab9a4e87b41c82f5b7104e4a3a6a5cd2ffa32d1af8b35c74ae3eb7a
-SHA256:4449c7c1dfc0858d043416c322603c84fa46e08ad0b1df9dd6d864c0ac459104
+SHA256:f3b53f3b84bb18348f7f4fe4b4773c7729fec55f1b25bcf36a31710affba3406
SHA256:f019024986f8063e1bda74811fe6fc6eaff87e983d959d0a58518e95ab55ea50
SHA256:ba3ac42d5b10014cf951ebd02706522505a41a8134d5b01ee17cbd81c0d496e6
SHA256:8245fa1c4489f1099e024cd94e1c09aa5d50ea7307f098c3b8c2362f97177883
@@ -358,7 +358,7 @@
[USER@HOST:]~/work/mediaconvert-passthrough-test$ paste \
hashes/source.packet.payload.sha256.txt \
hashes/passthrough.packet.payload.sha256.txt \
| awk -F '\t' '$1 == $2 { same++ } $1 != $2 { different++ } END { print "same=" same ", different=" different }'
same=1053, different=11
[USER@HOST:]~/work/mediaconvert-passthrough-test$ paste \
hashes/source.packet.payload.sha256.txt \
hashes/reencoded.packet.payload.sha256.txt \
| awk -F '\t' '$1 == $2 { same++ } $1 != $2 { different++ } END { print "same=" same ", different=" different }'
same=, different=1064
[USER@HOST:]~/work/mediaconvert-passthrough-test$ for file in \
input/source.mp4 \
output/passthrough.mp4 \
output/reencoded.mp4
do
base_name=$(basename "$file" .mp4)
ffmpeg \
-v error \
-i "$file" \
-map 0:v:0 \
-an \
-f framemd5 \
"hashes/${base_name}.frame.md5"
done
[USER@HOST:]~/work/mediaconvert-passthrough-test$ wc -l hashes/*.frame.md5
1074 hashes/passthrough.frame.md5
1074 hashes/reencoded.frame.md5
1074 hashes/source.frame.md5
3222 total
[USER@HOST:]~/work/mediaconvert-passthrough-test$ grep -v '^#' hashes/source.frame.md5 > hashes/source.frame.data.md5
grep -v '^#' hashes/passthrough.frame.md5 > hashes/passthrough.frame.data.md5
grep -v '^#' hashes/reencoded.frame.md5 > hashes/reencoded.frame.data.md5
[USER@HOST:]~/work/mediaconvert-passthrough-test$ if cmp -s \
hashes/source.frame.data.md5 \
hashes/passthrough.frame.data.md5
then
echo "PASS: input and passthrough decoded frame hashes are identical"
else
echo "FAIL: input and passthrough decoded frame hashes differ"
fi
PASS: input and passthrough decoded frame hashes are identical
[USER@HOST:]~/work/mediaconvert-passthrough-test$ if cmp -s \
hashes/source.frame.data.md5 \
hashes/reencoded.frame.data.md5
then
echo "UNEXPECTED: input and re-encoded decoded frame hashes are identical"
else
echo "EXPECTED: input and re-encoded decoded frame hashes differ"
fi
EXPECTED: input and re-encoded decoded frame hashes differ
[USER@HOST:]~/work/mediaconvert-passthrough-test$
ファイル全体の SHA-256 を比較する
最後に、入力動画、Video Passthrough 出力、および H.264 再エンコード出力のファイル全体に対する SHA-256 を比較します。
ここで確認する SHA-256 は、映像ストリームだけではなく、MP4 コンテナに含まれるすべてのバイト列を対象とします。そのため、映像フレームが一致する Video Passthrough 出力でも、入力動画とファイル全体の SHA-256 は一致しない可能性があります。
以下のコマンドを実行します。
sha256sum \
input/source.mp4 \
output/passthrough.mp4 \
output/reencoded.mp4
実行結果は以下のとおりです。
8f3a286c4eda74cd4d1024815de94646ea6a65b7dd2476d275e147ebbc123182 input/source.mp4
b64a4324abcddc853fa50ca9926617922db1a32fc45d303e84aa41e4a6734295 output/passthrough.mp4
417f0f343a29ca687f44b417ede57107a337a134a959d8f2fda55c16863e5fcf output/reencoded.mp4
入力動画、Video Passthrough 出力、および H.264 再エンコード出力では、ファイル全体の SHA-256 はすべて異なりました。
ファイル全体の SHA-256 は、映像ストリームだけでなく、MP4 コンテナに含まれるすべてのバイト列を比較します。比較対象には、コンテナメタデータ、タイムスタンプ、インデックス情報、およびデータの格納順序なども含まれます。
そのため、Video Passthrough 出力のファイル全体の SHA-256 が入力動画と一致しないことだけでは、映像が再エンコードされた、またはデコード後の映像フレームが変化したとは判断できません。
今回の検証結果を整理します。
| 比較方法 | Video Passthrough 出力 | H.264 再エンコード出力 |
|---|---|---|
| 映像ストリームのメタデータ | 主要項目が入力動画と一致 | コーデック、解像度、フレームレート、フレーム数は入力動画と一致 |
| 映像パケットのペイロードハッシュ | 1,064 件中 11 件が不一致 | 1,064 件すべてが不一致 |
| デコード後フレームの比較 | framemd5 のフレームレコードが完全一致 | framemd5 のフレームレコードが不一致 |
| ファイル全体の SHA-256 | 入力動画と不一致 | 入力動画と不一致 |
Video Passthrough 出力では、ファイル全体の SHA-256 と映像パケットのペイロードハッシュでは入力動画との差分を検出しました。
一方、デコード後フレームを比較すると、framemd5 のフレームレコードは入力動画と完全に一致しました。
したがって、今回の H.264 / MP4 入力および MP4 出力の検証条件では、ファイル全体の SHA-256 だけで Video Passthrough による映像フレームの保持を判定することは適切ではありません。
映像フレームが保持されているかを確認する目的では、デコード後フレームを比較する方法が、今回の検証ではより直接的な確認方法になりました。

まとめ
MediaConvert の Video Passthrough を使用し、H.264 / MP4 入力を MP4 へ再パッケージ化して比較しました。
今回の検証では、Video Passthrough 出力のファイル全体の SHA-256 は入力動画と一致せず、映像パケットのペイロードハッシュにも 11 件の差分がありました。
一方、framemd5 のフレームレコードは入力動画と完全に一致しました。今回の条件では、パケットペイロードの一部差分は、FFmpeg でデコードした映像フレームに影響しないことを確認できました。
この結果から、以下を確認できました。
- ファイル全体の SHA-256 だけでは、映像が再エンコードされたかを判断できない
- コーデック、解像度、フレームレート、およびフレーム数が一致していても、再エンコードされていない根拠にはならない
- Video Passthrough 出力でも、映像パケットのペイロードハッシュが完全一致しない場合がある
- 映像フレームの保持を確認するには、デコード後フレームを比較する方法が有効である
本記事の検証は、1 本の H.264 / MP4 入力を MP4 へ出力した場合に限定しています。入力コーデック、コンテナ、GOP 構造、付加情報、出力形式などが異なる場合、結果も変わる可能性があります。
今後は、以下の条件でも比較してみたいと思います。
- H.265 / HEVC 入力での Video Passthrough
- HLS、DASH、CMAF への再パッケージ化
- 音声ストリームを含めた比較
- 複数入力動画を連結した場合の比較
- 不一致となった 11 件を H.264 の NAL ユニット単位で調査する検証
検証完了後は、不要な MediaConvert 出力オブジェクトを Amazon S3 バケットから削除しました。
本ブログが誰かの参考になれば幸いです。
参考資料
- Video passthrough - MediaConvert
- Video passthrough codec support and job settings requirements - MediaConvert
- Tutorial: Configuring job settings - MediaConvert
- Setting up IAM permissions - MediaConvert
- Creating the IAM role within MediaConvert - MediaConvert
- ffprobe Documentation
- FFmpeg Formats Documentation - framemd5
- Pixabay Content License
クラスメソッドオペレーションズ株式会社について
クラスメソッドグループのオペレーション企業です。
運用・保守開発・サポート・情シス・バックオフィスの専門チームが、IT・AIをフル活用した「しくみ」を通じて、お客様の業務代行から課題解決や高付加価値サービスまでを提供するエキスパート集団です。
当社は様々な職種でメンバーを募集しています。
「オペレーション・エクセレンス」と「らしく働く、らしく生きる」を共に実現するカルチャー・しくみ・働き方にご興味がある方は、クラスメソッドオペレーションズ株式会社 コーポレートサイト をぜひご覧ください。※2026年1月 アノテーション㈱から社名変更しました








