Armadilloフォーラム

デコード画像を一部編集して表示

yseki

2016年8月29日 1時09分

お世話になっております。

H264映像をacmh264decでデコードして、acmfbdevsinkでHDMI出力する際に、線を引くなどの加工をしたく考えています。
パイプラインとしては、下記のようにできればと考えています。

gst-launch ・・・・ acmh264dec ! myfillter ! acmfbdevsink device=/dev/fb0

GstBaseTransformをベースクラスとしてtransform_ip関数で加工できると思い、いろいろ試しているのですが、画像データが登録されているアドレスを取得することができません。

transform_ip関数の引数のGstBufferからgst_buffer_get_meta関数で使用しているフレーム番号やファイルディスクリプタは取得できています。
このファイルディスクリプタを引数にmmapするとエラーになります。

あるいは、引数のGstBufferをgst_buffer_mapやgst_buffer_get_memoryでアドレスを取得しようとしてもエラーになるか、0が帰ってきます。

申し訳ありませんが、画像データが登録されているアドレスを取得する方法を教えてください。
GstBaseTransformを使用しない方法でもかまいませんので、よろしくお願いします。

コメント

GstBaseTransform[1] でも基本は同じで、upstream から chain method を通して
やってくる GstBuffer に必要な情報は全て含まれています。

acmh264dec は、DMABuf に対応しているので、ちょっとややこしいかもしれま
せん。画像をいじるのであれば DMABufの恩恵はどっちみち受けられないので、
無視してかまいません。

線を引くのであれば、out 側の GstBuffer サイズが in 側の GstBuffer より
大きくなることはないはずなので、transform_ip を使って大丈夫です。
transform_ip() で渡される GstBuffer から GstMemory にアクセスするための
GstMapInfo を gst_buffer_map() を使って取得します。

https://gstreamer.freedesktop.org/data/doc/gstreamer/head/gstreamer-lib…
https://gstreamer.freedesktop.org/data/doc/gstreamer/head/gstreamer/htm…
https://gstreamer.freedesktop.org/data/doc/gstreamer/head/pwg/html/sect…
http://hellolibraryworld.blogspot.jp/2015/12/gstreamer-6-buffer-memory…

Video を扱うなら GstBaseTransform から派生している GstVideoFilter の方
が便利です。が、新しい GStreamer にしか入っていないかな?

> 線を引くのであれば、out 側の GstBuffer サイズが in 側の GstBuffer より
> 大きくなることはないはずなので、transform_ip を使って大丈夫です。
> transform_ip() で渡される GstBuffer から GstMemory にアクセスするための
> GstMapInfo を gst_buffer_map() を使って取得します。

gst-buffer_map()でTRUEは返ってくるのですが、GstMapInfoのメンバーがすべて0となっています。
gst_buffer_get_acm_dmabuf_meta()でindexやfdは取得できますので、transform_ip() で渡される GstBuffer は間違っていないと思われます。

コードのほかにも、何か注意事項などありますでしょうか。
たとえば、ライブラリの追加が必要とか。

申し訳ありませんが、よろしくお願いします。

> gst_buffer_get_acm_dmabuf_meta()でindexやfdは取得できますので、transform_ip() で渡される GstBuffer は間違っていないと思われます。

取れた fd を mmap()してやると、画像データーが見えませんか?

> 取れた fd を mmap()してやると、画像データーが見えませんか?

FullHDのRGBxフォーマットで、下記のようにmmapしているのですが、エラー(EPERM)となってしまいます。
mmap(NULL, 1920*1080*4,(PROT_WRITE | PROT_READ), MAP_SHARED, fd, 0);

なにがおかしいのでしょうか。

添付した test.c のようにやってみましたが、たしかに mmap() に失敗しました。
もうちょっと調べてみます。

ファイル ファイルの説明
test.c

ごめんなさい。

acmh264dec が使っている frame bufferのメモリは mmap() に対応していませんでした。
acmh264*enc* 側では ceu2rtp[1] で mmap() しているので、勘違いしていました。

mmap() が簡単に実装できないか確認中です。

[1]: https://github.com/atmark-techno/ceu2rtp

at_takahiro.nakamura

2016年9月14日 17時00分

takahiro.nakamuraです。

videobuf2-dma-contig.cのvb2_dc_mmap()を参考に簡単なパッチを作ってみました。
(add-support-mmap-for-lcdcfb-dmabuf.patch)
mmapとバッファーの書換えが出来ます。

ファイル ファイルの説明
add-support-mmap-for-lcdcfb-dmabuf.patch