2.3 動画再生


前章までの設定でFSMCの操作でLCDを制御できるようになりました。
本章ではBMPファイルから動画データを作成して
LCDに転送する事で画像、または動画を表示します。

【動画データ】
 ○LCDのカラー表示

   LCDは赤・緑・青(RGB)のドットの集まりでフルカラーの画像を表現しています。
 

 
一つ一つのドットがRGBの混色で表現される。

 ○BMPから画像データの抽出
   BMPデータはLCDに直接出力できるRGBデータを含んでいます。
   LCDに16bitアクセスにて画像データを書き込む場合は当然16bitのRGBデータを必要としますが
   BMPの16bitカラーはRGB555の実質15bitカラーです。
   色数を活用する為には24bitカラーからRGB565のデータを取り出します。

   また、この時BMP画像のデータの並びをボトムアップからトップダウンへと入れ替えます。
   さらにサイズの低減とアクセスの簡易化を図る為にヘッダを削除します。
   参考HP「BMPファイルフォーマット
 
   以上のデータ加工を行い画像データを作成します。
 
 ○動画データの作成
   複数の画像データを連続して再生するとパラパラ漫画のように動画データとなります。

   3分で30fps(1秒辺りの枚数)の動画に必要な枚数は5400枚です。
   それだけの画像の処理は当然手作業では不可能ですので
   自作ソフトの作成が必要になります。
   参考ページ「動画データの作成」(私のブログです^^;)

   一応、今回の動画を作成したソフトを公開します。(使用方法はreadme参照)
   作成途上のものですので完成度はとても低いです。
   使用される方は下記の点にご注意ください。
   1.QVGAは画像枚数表示機能が使えません
   2.制御の都合上、画素の並び替えが特殊になっているため、
     液晶の初期化パラメータがサンプルプロジェクトと同一でないと再生できません。

   ダウンロード


【SDカードからの読み出し】
 作成した動画データは4分で1Gbyteを超える程大きなデータになる為、
 SDカードに保存して読み出します。
 
 今回の動画再生にはスピードクラス4のmicroSDカード
 「東芝製 マイクロSD 2G」を使用しました。(480円)


 また動画再生の際には高速にデータを読み出す必要があります。
 16bitカラー30fpsの場合に必要な読み出し速度は
 320(pixel)×240(pixel)×2(byte)×30(fps)= 4.6Mbyte/sec
 となります。

 読み出しにはSTM32大容量タイプに内蔵されたペリフェラルのSDIOを使用します。
 高速読み出しのコツ等については3章の「SDカードの読み出しについて」をご覧ください。


【FSMC→LCDへの直接データ転送】

 ○概要と条件
   FSMCを利用する事によってSDカードから読み出したデータを
   データストリームからバッファ無しでLCDへ直接転送する事が可能です。

   FSMCのメリットを説明する為に私が従来行っていたGPIOによる転送方法と比較してみました。
   まず、従来の方法を下図に示します。(今回の制御方法とは無関係なので理解しなくても構いません)

 

   1画面分のデータを分割して転送する必要があるため
   タイマを複数使用して転送の開始と終了を制御しています。
   なかなか複雑ですね・・・・

   新しい方法を下図に示します。 

 

   一度に1画面分のデータを転送できる為、FatFSの読み出し関数に
   1画面分の画素サイズを指定するだけでGPIO転送の時のような転送終了処理は不要です。

   以上のようにFSMCを使う事で非常にシンプルかつ高速になる上に、
   バッファが不要になるため使用するSRAMメモリが激減するメリットがあります。

   4kbyte程度のSRAM使用量で動画再生プログラムを組む事ができます。

   FSMCからLCDへ直接転送できる条件は下記の通りです。
   ①LCD側にGRAMが搭載されていて画面の自動リフレッシュ(再走査)が行われている事。
    これによりマイコン側はデータ書き込みのタイミングを走査信号に同期させる必要が無い。
   ②LCDのインターフェイスが8bit又は16bitバスである事。
     FSMCインターフェイス仕様より。
   ③GRAMへの連続データ書き込みが可能である事。
     つまり1pixelのデータ書き込む度にLCDコントローラーが
     GRAMアドレスの自動インクリメントを行う事。

 ○FatFSとの連携
    データストリームとしてSDIOをドライブとして実装したFatFSを使用します。
    FatFSを作成し公開されたChaN氏,
    STM32のSDIOにFatFSをポーティングされた
    Martin Thomas氏,J. Shaler氏,川内氏に感謝致します。

 ○FatFSを高速転送が可能なワードアクセスモードにする。

    事前準備としてFatFSが32bitでデータアクセスを行うように設定します。
    FSMCは32bitのAHBデータアクセスを16bit2回の外部SRAM(=LCD)アクセスに分割してくれる為、
    FSMCのアドレスへ32bitで書き込めば、16bitインターフェイスのLCDへデータが転送できます。
    設定方法:FatFSの設定情報で下記項目を「1」に設定する。     

 #define _WORD_ACCESS 1 /* 0 or 1 */

     バージョン0.09であれば「ffconf.h」に設定項目が有ります。(前のバージョンでは「ff.h」にあるようです。)


 ○データ転送手順
   動画再生は下記の手順を行います。
       ①書き込みを開始するGRAMアドレスを設定する。
       ②LCDへ書き込みコマンドを送信する。
       ③FSMCのアドレスを出力バッファに指定してFatFS読み出し開始。
       ④ ①~③までの手順をfpsの間隔毎に行う。
 
   
   以下順を追って説明します。

   ①書き込みを開始するGRAMアドレスをLCDへ設定して書き込みコマンドを送信する。
     前章のマクロを使ってGRAMアドレスを設定します。(通常x=0 y=0)

//開始アドレスの設定
SET_LCD_ADDRESS(x,y);


    ②LCDへ書き込みコマンドを送信する。
    
LCDへ書き込みコマンドを指示して、次のデータから画素を連続して送信する事を通知します。

// 書込みコマンド
LCD->CMD = 0x0022;

  
   ③FSMCのアドレスを出力バッファに指定してFatFS読み出し開始。
     設定が終われば、実際のLCD転送命令は非常にシンプルです。
     1画面分のバイト(画面幅×画面高さ×2(16bit))を指定してFSMCアドレスに読み込むだけです。
          アドレスはFatFSによりインクリメントされますが、RS信号に設定したA22のアドレスピンが
     High(コマンド)になるまで4Mbyte余裕があるので今回の場合は問題有りません。(1画面が154kbyteの為)

//画像データをFSMCへ
res = f_read(&moviet_file, (uint8_t*)&(LCD->DATA), (UINT)((DISPLAY_WIDTH * DISPLAY_HEIGHT) * 2 ), &br);

    以上でLCDへ一画面分の画面転送が行われます。

   ④ ①~③までの手順をfpsの間隔毎に行う。

    上記の手順を動画ファイル終了までfps周期で繰り返します。
    転送開始タイミング周期が正確でないと動画再生中にズレが生じる為タイマ割り込みを利用します。

 /* TIMER3 構造体宣言 */
TIM_TimeBaseInitTypeDef Tim_Base_st;
/* TIMER3クロック供給 */
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);
/* TIMER3 Init */
Tim_Base_st.TIM_Prescaler = 1000 - 1; /* 100 */
Tim_Base_st.TIM_CounterMode = TIM_CounterMode_Up;
Tim_Base_st.TIM_Period = ((72000000 / FPS) / 1000) - 1;      /* 1/FPSで更新。プリスケール分割る */
Tim_Base_st.TIM_ClockDivision = TIM_CKD_DIV1;
Tim_Base_st.TIM_RepetitionCounter = 0x00;
TIM_TimeBaseInit(TIM3, &Tim_Base_st);

/* 初期化 */
TIM_GenerateEvent(TIM3, TIM_EventSource_Update);
/* 更新フラグのクリア */
TIM_ClearITPendingBit(TIM3,TIM_IT_Update);

/* 更新リクエストによる割込み許可*/
TIM_ITConfig(TIM3, TIM_IT_Update, ENABLE);
※1 FPSは再生周期のマクロ定義(今回は30)
※2 タイマのカウンタは0を数える為、プリスケーラとプリロードレジスタの設定は1引いた値になります。

説明は以上です。

動画再生を使いこなせば、動画表示に留まらず、
動くアイコンや文字表現など
電子工作の表現の幅は大きく広がるものと感じています.。
思い通りのGUIが表現できるのも嬉しいですね。


○参考文献
  1.LCD&タッチセンサ活用の素