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
Mutsuha Asada
September 28, 2022
Technology
0
37
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
230
❄️ NixCon2025に参加した
momeemt
0
260
🔨 小さなビルドシステムを作る
momeemt
4
1k
情報科学類で学べる専門科目38選
momeemt
0
830
❄️ tmux-nixの実装を通して学ぶNixOSモジュール
momeemt
1
610
Wasmで拡張できる軽量マークアップ言語 Brack
momeemt
0
390
❄️ NixOS/nixpkgsにSATySFiサポートを実装する
momeemt
2
560
Intel系FPGA上へのRISC-Vプロセッサの実装
momeemt
0
350
情報科学若手の会 2024 LT「WebAssemblyで拡張可能な軽量マークアップ言語の開発」
momeemt
0
51
Other Decks in Technology
See All in Technology
2025年のデザインシステムとAI 活用を振り返る
leveragestech
0
750
モノタロウ x クリエーションラインで実現する チームトポロジーにおける プラットフォームチーム・ ストリームアラインドチームの 効果的なコラボレーション
creationline
0
590
国井さんにPurview の話を聞く会
sophiakunii
1
350
純粋なイミュータブルモデルを設計してからイベントソーシングと組み合わせるDeciderの実践方法の紹介 /Introducing Decider Pattern with Event Sourcing
tomohisa
1
810
AI時代のアジャイルチームを目指して ー スクラムというコンフォートゾーンからの脱却 ー / Toward Agile Teams in the Age of AI
takaking22
11
5.5k
ECS_EKS以外の選択肢_ROSA入門_.pdf
masakiokuda
1
120
ソフトウェアエンジニアとAIエンジニアの役割分担についてのある事例
kworkdev
PRO
1
380
Scrum Guide Expansion Pack が示す現代プロダクト開発への補完的視点
sonjin
0
520
RALGO : AIを組織に組み込む方法 -アルゴリズム中心組織設計- #RSGT2026 / RALGO: How to Integrate AI into an Organization – Algorithm-Centric Organizational Design
kyonmm
PRO
3
910
[PR] はじめてのデジタルアイデンティティという本を書きました
ritou
0
780
AI with TiDD
shiraji
1
340
2025-12-27 Claude CodeでPRレビュー対応を効率化する@機械学習社会実装勉強会第54回
nakamasato
4
1.4k
Featured
See All Featured
Embracing the Ebb and Flow
colly
88
4.9k
Visualization
eitanlees
150
16k
Balancing Empowerment & Direction
lara
5
840
Conquering PDFs: document understanding beyond plain text
inesmontani
PRO
4
2.2k
Agile Leadership in an Agile Organization
kimpetersen
PRO
0
67
Leadership Guide Workshop - DevTernity 2021
reverentgeek
1
180
ラッコキーワード サービス紹介資料
rakko
0
1.9M
Breaking role norms: Why Content Design is so much more than writing copy - Taylor Woolridge
uxyall
0
130
Intergalactic Javascript Robots from Outer Space
tanoku
273
27k
Are puppies a ranking factor?
jonoalderson
0
2.6k
Why Our Code Smells
bkeepers
PRO
340
58k
Odyssey Design
rkendrick25
PRO
0
460
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さん、配信技術部のみなさま、 お世話になりました、ありがとうございました!