RandomThoughts

RandomThoughts

動画配信

Contents:
  1. Fragmented MPEG-4とAVAssetWriter
  2. AV Foundation
  3. Audioのキャプチャ
  4. エンコードとデコードのsample bufferの直接アクセス
    1. 扱う4つのユースケース
    2. 良く出てくる登場人物
    3. H.264のストリームのデコード(1つ目のケース)
    4. VTDecompressSessionによるデコードした画像へのアクセス
    5. VTCompressionSessionでネットワークに圧縮フレームを直接送る
    6. Elementary Streamへの変換
  5. メモ

Macより。iOS関連で動画のエンコードや配信周りがどうなっているかを調べる。WikiNameとしてはOS関係なく動画配信全般にしておく。

YouTubeAPITwitchで配信するようなケースで、iOS側はどうなっているかを調べるメモ。

HTTP Live Streaming - Apple Developer Documentation あたりから見るのか?

Fragmented MPEG-4とAVAssetWriter

Author fragmented MPEG-4 content with AVAssetWriter - WWDC20 - Videos - Apple Developer

この一つ手前のエンコーダーのあたりを知りたいのだが、とりあえずの取っ掛かりとして。 このサンプルコードからたどって見つけた。 Writing Fragmented MPEG-4 Files for HTTP Live Streaming - Apple Developer Documentation

この動画はやりたい事とは違いそうだが、情報量が多いのでなかなか良い。

Working with Media in AV Foundation (WWDC11)がみたい動画っぽいが見つからないな。

ただAV Foundation周りを調べると良さそうか。

AV Foundation

AVFoundation Overview - Apple Developer

Apple iOS Development: Understanding AV Foundation - YouTube

Playbackの解説と、Editingの解説が詳しい。Editingは役に立ちそう。AVComposition、AVAudioMixなどの解説や時間などがどう表されるかなどの解説。

最後に言及されてたサンプルコード

  • RosyWriter
  • AVReaderWriter for OSX

Audioのキャプチャ

オーディオというよりはステレオの話だが、サンプルコードは参考になりそう。

Capturing stereo audio from built-in microphones - Apple Developer Documentation

WWDCのこの動画が同じ内容か? Record stereo audio with AVAudioSession - WWDC20 - Videos - Apple Developer

なんかAVAudioRecoderはファイルに書く奴っぽいので、サンプルバッファが取れるのは無いのか? とググっていたらその辺の比較をしているブログを見つけた。 Recording Audio on iOS with Examples - Dolby.io

エンコードとデコードのsample bufferの直接アクセス

AVAssetWriterのdelegateの返すsegmentedDataがなんなのか全然分からなくて調べていた所見つけた動画。とても良いのでサブセクションを作る。 AV Foundationでは無くその下のVideo Toolboxを使うらしい。

Direct Access to Video Encoding and Decoding - WWDC14 - Videos - Apple Developer

参照されてる動画で気になったの

  • WWDC 2013 Moving to AVKit and AVFoundation

扱う4つのユースケース

ユースケースとして以下を挙げている

  1. Displaying an H.264 stream in a layer in your application
  2. Decoding an H.264 stream and accessing the decoded buffers
  3. Compressing a sequence of images into a movie file (27:50あたりから)
  4. Compressing a sequence of images into an H.264 stream for the network

良く出てくる登場人物

6分あたり。

  • CVPixelBuffer … 非圧縮の画像バッファ
  • CVPixelBufferPool … CVPixelBufferのバッファプール
  • pixelBufferAttributes … 幅、高さ、32RGBAなど
  • CMTime
  • CMVideoFormatDescription … width/height, フォーマットタイプとしてkCMPixelFormat_32RGBA、kCMVideoCodecType_H264など
  • CMBlockBuffer … 圧縮されたビデオフレームのデータなど
  • CMSampleBuffer … 圧縮されたビデオフレームと非圧縮のビデオフレームの二種類がある。以下を含む。
    • CMTime … プレゼンテーションタイム
    • CMVideoFormatDescription
    • 圧縮されたビデオの場合 … CMBlockBuffer
    • 非圧縮されたフレームの場合 … CVPixelBuffer
  • CMClock … mach_absolute_timeなどの勝手に進むなにかのラッパ
  • CMTimebase … CMClockを元に原点を決めたりとかいろいろ操作した時間

この辺は良く出てくるのでありがたい。

H.264のストリームのデコード(1つ目のケース)

10:00あたりから。15:00あたりからネットワークからCMSampleBufferへのコンバートの話が出てくる。

NetworkからくるH.264ストリームはElementary Streamと呼ばれる形式で、それとファイルに保存されるMPEG-4をベースとしたCMSampleBufferの間には変換が必要となる。

NAL Unitからmp4のCMVideoFormatDescriptionを作るのはCMVideoFormatDescriptorCreateFromH264ParameterSets。

CMSampleBufferを作るのに必要なのは以下の3つ。

  • CMTime
  • CMVideoFormatDescription
  • NAL Unit (ヘッダを長さに置き換える必要あり)

この3つを、CMSampleBufferCreateに食わせる。

VTDecompressSessionによるデコードした画像へのアクセス

20:00あたりから、ネットワークのストリームをデコードしてCVPixelBufferにアクセスする例に入る。 これにはVTDecompressSessionを使う。 この中にVideoDecoderが入っているらしい。

VTCompressionSessionでネットワークに圧縮フレームを直接送る

29:00あたりからCVPixelBufferを圧縮してネットワークに送る例が始まる。

VTCompressionSessionEncodeFrameでpixelBufferを送るっぽい。

最後に待つのはVTCompressionSessionCompleteFramesらしい。

Elementary Streamへの変換

34:00あたりからElementary Streamへの変換の話がある。 SPSとPPSを最初に送る必要があるが、これはCMVideoFormatDescriptionGetH264ParameterSetAtIndexというそのものずばりの関数がある。

次にNAL Unitの変換。I Frameなどは先頭に4バイトのlengthが入っているので、これを00 00 01の3 byteの開始コードに変換する必要がある。

メモ

使うか分からないメモを置いておく