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
5
PIXIV SUMMER BOOT CAMP 2022 成果発表「GIFから12倍速くする」
Mutsuha Asada
September 28, 2022
Tweet
Share
More Decks by Mutsuha Asada
See All by Mutsuha Asada
情報科学若手の会 2024 LT「WebAssemblyで拡張可能な軽量マークアップ言語の開発」
momeemt
0
13
Nixでつくるdotfiles
momeemt
0
9
情報特別演習I 最終発表「理工学の紙書籍を用いた学習の効率を向上させるインタフェース」
momeemt
0
15
SATySFi Conf 2023「SATySFiを使って学類新歓冊子を発行した」
momeemt
0
9
主専攻実験(深層学習を用いたCG・画像処理)最終成果報告
momeemt
0
12
情報科学類新歓2023 履修の組み方
momeemt
0
13
情報科学特別演習 最終発表「動画編集ソフトウェアフレームワーク: mock up」
momeemt
0
12
技育キャンプ ハッカソン vol.9「ギリギリ飯」
momeemt
0
9
SWEST22「Nimです、こんばんは」
momeemt
0
4
Other Decks in Technology
See All in Technology
第3回Snowflake女子会_LT登壇資料(合成データ)_Taro_CCCMK
tarotaro0129
0
200
Amazon SageMaker Unified Studio(Preview)、Lakehouse と Amazon S3 Tables
ishikawa_satoru
0
160
統計データで2024年の クラウド・インフラ動向を眺める
ysknsid25
2
850
OpenAIの蒸留機能(Model Distillation)を使用して運用中のLLMのコストを削減する取り組み
pharma_x_tech
4
560
株式会社ログラス − エンジニア向け会社説明資料 / Loglass Comapany Deck for Engineer
loglass2019
3
32k
社内イベント管理システムを1週間でAKSからACAに移行した話し
shingo_kawahara
0
190
継続的にアウトカムを生み出し ビジネスにつなげる、 戦略と運営に対するタイミーのQUEST(探求)
zigorou
0
590
2024年にチャレンジしたことを振り返るぞ
mitchan
0
140
ブラックフライデーで購入したPixel9で、Gemini Nanoを動かしてみた
marchin1989
1
540
NilAway による静的解析で「10 億ドル」を節約する #kyotogo / Kyoto Go 56th
ytaka23
3
380
ガバメントクラウドのセキュリティ対策事例について
fujisawaryohei
0
560
私なりのAIのご紹介 [2024年版]
qt_luigi
1
120
Featured
See All Featured
Testing 201, or: Great Expectations
jmmastey
40
7.1k
Intergalactic Javascript Robots from Outer Space
tanoku
270
27k
What's in a price? How to price your products and services
michaelherold
243
12k
GraphQLの誤解/rethinking-graphql
sonatard
67
10k
The Language of Interfaces
destraynor
154
24k
Scaling GitHub
holman
458
140k
How GitHub (no longer) Works
holman
311
140k
A designer walks into a library…
pauljervisheath
204
24k
No one is an island. Learnings from fostering a developers community.
thoeni
19
3k
Designing for humans not robots
tammielis
250
25k
Music & Morning Musume
bryan
46
6.2k
Gamification - CAS2011
davidbonilla
80
5.1k
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さん、配信技術部のみなさま、 お世話になりました、ありがとうございました!