第11回 Raspberry Pi で監視カメラを作ろう! ~動画保存編~


Raspberry Piと専用のカメラモジュールを使用し、ONVIF対応の監視カメラを作成するシリーズ記事です。
本記事はリンク情報システム株式会社の有志が作成しています。


今回は動画データのファイル保存について説明します。

動画保存

ffmpegを使用してTSファイル保存

・動画のファイル形式について
H.264形式の動画ファイルのファイルコンテナとしては、MP4,AVI,TS等が考えられます。
全体の再生時間や含まれる映像データ、音声データの形式といった情報と実際のデータを保存する仕組みがファイルコンテナになります。

今回は複数のファイルを単純に連結するだけで、1つの長い動画が作成できる、TS形式で動画ファイルを作成します。

ffmpegを使用した動画ファイル作成処理は、以下の様な処理になります。

// ファイル出力用のコンテキストを割り当てる
ic = avformat_alloc_context();

// フォーマットを設定
AVOutputFormat* fmt = av_guess_format(NULL, "dummy.ts", NULL);
ic->oformat = fmt;

// 動画を追加
AVStream* st = avformat_new_stream(ic, NULL);
st->codec->codec_type     = AVMEDIA_TYPE_VIDEO;
st->codec->codec_id       = AV_CODEC_ID_H264;
st->codec->width          = m_width;
st->codec->height         = m_height;
st->time_base.num         = ts_time_base.num;
st->time_base.den         = ts_time_base.den;
st->codec->extradata_size = video_extradata_size;

st->codec->extradata = (uint8_t*)av_malloc(video_extradata_size + FF_INPUT_BUFFER_PADDING_SIZE);
memcpy(st->codec->extradata, video_extradata, video_extradata_size);
memset(st->codec->extradata + video_extradata_size, 0, FF_INPUT_BUFFER_PADDING_SIZE);

if (fmt->flags & AVFMT_GLOBALHEADER)
{
st->codec->flags |= CODEC_FLAG_GLOBAL_HEADER;
}

// ヘッダを出力
avformat_write_header(ic, NULL);

while(指定された時間繰り返す)
{
  // 動画データを出力
  av_interleaved_write_frame(ic, &inpkt);
}

// フッダを出力
av_write_trailer(ic);

// ストリーム出力を開放する
av_free(ic->pb);
ic->pb = NULL;
avformat_free_context(ic);

上記の例では記載していませんが、いろいろな再生アプリで再生可能な、互換性が高いファイルを作成するには、以下のような工夫をする必要があります。

・一番最初に出力する動画データは、IDRフレームの動画データにする。
・IDRフレームの前には、必ずSPS、PPSを付与する。

このルールを守っていないと、TSファイルとしては正しいのですが、アプリケーションによっては再生できない事があります。

ですので、一定時間でファイルを分割する場合は、IDRフレームに到達した時点で、それまでのファイルを閉じ、IDRフレーム以降を新しいファイルに出力する必要があります。


インデックス記事へ
第10回記事へ
第12回記事へ


リンク情報システム株式会社では一緒に働く仲間を随時募集しています!
また、お仕事のご依頼、ビジネスパートナー様も募集しております。お気軽にご連絡ください。