Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
PIXIV SUMMER BOOT CAMP 2022 成果発表「GIFから12倍速くする」
Search
Sponsored
·
Your Podcast. Everywhere. Effortlessly.
Share. Educate. Inspire. Entertain. You do you. We'll handle the rest.
→
Mutsuha Asada
September 28, 2022
Technology
0
38
PIXIV SUMMER BOOT CAMP 2022 成果発表「GIFから12倍速くする」
Mutsuha Asada
September 28, 2022
Tweet
Share
More Decks by Mutsuha Asada
See All by Mutsuha Asada
Reproducible Containers (ASPLOS'20)
momeemt
0
310
❄️ NixCon2025に参加した
momeemt
0
340
🔨 小さなビルドシステムを作る
momeemt
4
1.1k
情報科学類で学べる専門科目38選
momeemt
0
900
❄️ tmux-nixの実装を通して学ぶNixOSモジュール
momeemt
1
730
Wasmで拡張できる軽量マークアップ言語 Brack
momeemt
0
470
❄️ NixOS/nixpkgsにSATySFiサポートを実装する
momeemt
2
650
Intel系FPGA上へのRISC-Vプロセッサの実装
momeemt
0
420
情報科学若手の会 2024 LT「WebAssemblyで拡張可能な軽量マークアップ言語の開発」
momeemt
0
52
Other Decks in Technology
See All in Technology
Bill One急成長の舞台裏 開発組織が直面した失敗と教訓
sansantech
PRO
2
410
コスト削減から「セキュリティと利便性」を担うプラットフォームへ
sansantech
PRO
3
1.6k
今こそ学びたいKubernetesネットワーク ~CNIが繋ぐNWとプラットフォームの「フラッと」な対話
logica0419
5
550
AIが実装する時代、人間は仕様と検証を設計する
gotalab555
1
650
Webhook best practices for rock solid and resilient deployments
glaforge
2
310
Amazon Bedrock Knowledge Basesチャンキング解説!
aoinoguchi
0
170
OpenShiftでllm-dを動かそう!
jpishikawa
0
140
GitHub Copilot CLI を使いやすくしよう
tsubakimoto_s
0
110
フルカイテン株式会社 エンジニア向け採用資料
fullkaiten
0
10k
Tebiki Engineering Team Deck
tebiki
0
24k
広告の効果検証を題材にした因果推論の精度検証について
zozotech
PRO
0
210
Why Organizations Fail: ノーベル経済学賞「国家はなぜ衰退するのか」から考えるアジャイル組織論
kawaguti
PRO
1
220
Featured
See All Featured
Efficient Content Optimization with Google Search Console & Apps Script
katarinadahlin
PRO
1
330
How Fast Is Fast Enough? [PerfNow 2025]
tammyeverts
3
460
Context Engineering - Making Every Token Count
addyosmani
9
670
Making the Leap to Tech Lead
cromwellryan
135
9.7k
Why Your Marketing Sucks and What You Can Do About It - Sophie Logan
marketingsoph
0
77
Understanding Cognitive Biases in Performance Measurement
bluesmoon
32
2.8k
Java REST API Framework Comparison - PWX 2021
mraible
34
9.2k
技術選定の審美眼(2025年版) / Understanding the Spiral of Technologies 2025 edition
twada
PRO
117
110k
Bioeconomy Workshop: Dr. Julius Ecuru, Opportunities for a Bioeconomy in West Africa
akademiya2063
PRO
1
57
Impact Scores and Hybrid Strategies: The future of link building
tamaranovitovic
0
200
Amusing Abliteration
ianozsvald
0
110
DevOps and Value Stream Thinking: Enabling flow, efficiency and business value
helenjbeal
1
110
Transcript
GIFから12倍速くする ImageFluxコース PIXIV SUMMER BOOT CAMP 2022 筑波大学 momeemt /
浅田睦葉 2022.9.28
2 自己紹介 • 筑波大学 情報学群 情報科学類 1年次 • Nim /
FFmpeg • 趣味: インディーズバンドとお笑い ◦ 35.7とダウ90000が好きです • Twitter: @momeemt momeemt ImageFluxコース
3 nontanさん usaさん terryさん hayaさん 配信技術部 メンター サブメンター
4 H.264エンコーダを利用して GIFアニメーションをmp4に変換する
5 • GIFとは複数枚の画像をコマ送りにしてアニメーションにできる 画像ファイルフォーマットの こと • Webブラウザでも標準的にサポート • ImageFluxもサポートしている GIF?
▲こういうの
6 • H.264が行うフレーム間予測というメチャクチャ賢い圧縮ができない ◦ → ファイルサイズが大きくなるので配信コストが高い • エンコードが遅い ◦ どうして...
GIFの問題点 地球も泣いている
• H.264とは動画圧縮規格の1つ • 「.mp4」「.mov」「.m4v」などおなじみ(?)の拡張子を持つ動画は H.264コーデックによっ てエンコード(圧縮)されている • 軽い!速い! 7 H.264?
8 • FFmpegは映像や音声を処理できる伝統のライブラリ • 膨大なコーデックやファイル形式、メディアをサポートしている • コマンドラインツールとしては有名だが libavcodec等のAPIを直接叩くことも ◦ 今回はこっち
FFmpeg
9 • nasm・yasm・libx264・FFmpegをインストール インストールバトル
10 • ビルド時間がえらいことに(15分半) 長すぎ
11 • H.264コーデックを手に入れる • エンコードに必要な設定を行う • 書き出し先である映像ストリームを準備する • フレームをエンコードしてパケットに格納して書き出す H.264エンコーダを呼び出す
12 • cgoはCとGoを相互運用する仕組み ◦ FFmpegの各種APIはCで記述されているのでこれを使って呼び出す ◦ GoのFFmpegラッパーではうまくいかなかったので途中で使うのをやめた cgo
13 あとは根気 • これはもうC言語
14 • VLCやブラウザで視聴可能なmp4ファイルを出力できた • QuickTimeではブラックスクリーンになり見れない ◦ 気難しい できた mp4になった地球 困る
15 • ImageFlux上でGIFをmp4に変換する • URLで f=mp4 というパラメータを与えるとmp4が返ってくるようにしたい ImageFluxでmp4変換をサポートする
16 • これまでは書き出すために avio_open 関数を呼んでいた ◦ URLを受け取って書き出し先を確立する • しかし、ImageFluxではHTTPのレスポンスとして書き出す必要があるので、 io.Writer
に書 き出さなければならない • そこでカスタムな AVIOContext を作成して io.Writer を繋ぎ合わせる I/Oを繋ぎ合わせる
AVIOContext *allocIOContext(void *bridge) { int bufferSize = 4096; uint8_t *buffer
= (uint8_t *)av_malloc(bufferSize); return avio_alloc_context( buffer, bufferSize, 1, bridge, 0, golibmp4BridgeWriterWrite, golibmp4BridgeSeek ); } void freeIOContextBuffer(AVIOContext *ctx) { av_free(ctx->buffer); } I/Oを繋ぎ合わせる C側から関数ポインタを渡す 17
• AVIOContextは書き込み関数だけでなくシーク関数を呼んでいる 18 I/Oを繋ぎ合わせる f544a9e55d239e42d74c9a16971e4b234da64441cd7bd 9e17c199b60b09fbe3741fda6110ee2fd16514d88f280b 62c1989204ba2db16d36d650419aeb04e4b5bc762b81 87f91c5d7845… 基本的には最初から順番に書き込んでいくが...
• AVIOContextは書き込み関数だけでなくシーク関数を呼んでいる 19 I/Oを繋ぎ合わせる f544a9e55d239e42d74c9a16971e4b234da64441cd7bd 9e17c199b60b09fbe3741cd50…fda6110ee2fd16514d8 8f280b62c1989204ba2db16d36d650419aeb04e4b5bc7 62b8187f91c5d7845 ファイルの途中に巻き戻って書き出すこともある
• ImageFluxは io.Writer を受け取る関数が処理の基本単位になっている ◦ io.Writer はシークできることが保証されていないのでシークできない • エンコードする時にシーク可能なバッファに書き込んで、まとめて書き出す ◦
メンターのnontanさんが seekbuf を実装してくださった 実装しておきました 20 I/Oを繋ぎ合わせる ありがとうございます🙏
21 動いた ~/c!/f=mp4/testdata/images/rotating_earth.gif
22 • 利用しやすいOpenH264に差し替える • libopenh264をビルドしてインストール(pkg-configファイルの生成) • libopenh264が生成した共有ライブラリを削除して Ciscoがビルドして頒布している共有ラ イブラリに差し替える •
OpenH264を有効にしてFFmpegをビルド OpenH264への差し替え
23 • GIFよりどれくらい速くなったのか • GIFエンコードとmp4エンコードのベンチマークを書いて計測する 計測! 1回の実行に561ミリ秒 GIFエンコード
• GIFよりどれくらい速くなったのか • GIFエンコードとmp4エンコードのベンチマークを書いて計測する 24 もう速い mp4エンコード 1回の実行に69ミリ秒 6.3倍
25 お得 ファイルサイズも半分少しになっている
26 • しかしメモリ確保を43倍やっているのでもう少し減らしたい 富豪すぎた mp4エンコード 1回の実行に176万回もメモリを確保している
27 • NRGBAをYUV420Pに変換する時にメモリアロケーション回数が跳ね上がっていた エンコード最適化
28 • color.NRGBA 型が color.Color 型にBoxingされる際にメモリアロケーションがされまくっ ていた ◦ → image.NRGBA
型にアサーションすることでアロケーションを回避 エンコード最適化
• 元のGIFエンコードよりも 12.2倍 高速になった • また、メモリ確保回数はGIFエンコードと比べて 0.013% になった 29 結果
1回の実行に46ミリ秒 爆速
もっと! 30 ※ 最終日はずっとチューニングしていた
• 色空間の変換で毎フレーム確保されていたバッファを使い回す • 元のGIFエンコードよりも 14.8倍 高速になった 31 NRGBA32→YUV420P変換 1回の実行に38ミリ秒
• 色空間の変換で23ms、フレームの書き込みで15msかかっている • どちらかを改善したい 32 速度的なボトルネック 変換部分のありなしで 2桁も変わる
• 自前の色空間変換を捨てて libswscale を使ってみる ◦ SWS_FAST_BILINEAR フラグで変換するとかなり速かった(約 17ms) • 元のGIFエンコードよりも
19.1倍 高速になった 33 libswscaleを使う 1回の実行に29ミリ秒
• なったが、かなり変換時間にはブレがある ◦ 自前の場合は安定して37ms〜42msかかっていた ◦ swscaleでは27〜32msかかることは多いが、たまに60msになったりする 34 libswscaleを使う 1回の実行に29ミリ秒
35 感想 • 複数の環境で問題なく動作すること、いずれ本番環境に乗せることを見据えて品質を保 つことなどを強く意識させられた 8日間でした • FFmpegを延々と触っていられて楽しかったです ◦ 実装のためにドキュメントを普段よりじっくりと読めたので解像度がなんとなく上がった
気がします • シェルが書けないとこんなに辛いんだなと思いました ◦ 8日間で一番苦労したのはシェルスクリプトでした
36 8日間ありがとうございました!!! 最後に メンターのnontanさん、人事のkamikoさん、配信技術部のみなさま、 お世話になりました、ありがとうございました!