k-nakai
2025年3月5日 16時40分
==========
製品型番:Armadillo-440
Debian/ABOSバージョン:atmark-dist v1.55.1
カーネルバージョン:Linux 3.14.36-at13
3G/LTE モジュール情報 (Debianのみ):-
その他:-
==========
お世話になっております。
中居と申します。
Armadillo上でRAWデータ(RGB形式)をJPEG圧縮したく、"gstreamer1.0"を有効にしたimageを使用しています。
有効箇所は以下で投稿した内容と同じです。
https://armadillo.atmark-techno.com/forum/armadillo/24297
Armadillo上で以下のように"gst-launch-1.0"コマンドを実行し、RAWデータ(RGB形式)のJPEG圧縮を試みましたが、
出力されたファイルが0byteとなり、うまく変換できておらず困っております。
[root@armadillo440-0 (ttymxc1) ~]# gst-launch-1.0 -vvv filesrc location=/mnt/test/DSC00058.rgb blocksize=$((2832*4240*2)) num-buffers=1 ! video/x-raw,format=RGB,width=2832,height=4240,framerate=1/1 ! jpegenc ! filesink location=/mnt/test/out.jpg Setting pipeline to PAUSED ... Pipeline is PREROLLING ... /GstPipeline:pipeline0/GstCapsFilter:capsfilter0.GstPad:src: caps = video/x-raw, format=(string)RGB, width=(int)2832, height=(int)4240, framerate=(fraction)1/1 /GstPipeline:pipeline0/GstJpegEnc:jpegenc0.GstPad:sink: caps = video/x-raw, format=(string)RGB, width=(int)2832, height=(int)4240, framerate=(fraction)1/1 Pipeline is PREROLLED ... Setting pipeline to PLAYING ... New clock: GstSystemClock Got EOS from element "pipeline0". Execution ended after 31007384 ns. Setting pipeline to PAUSED ... Setting pipeline to READY ... Setting pipeline to NULL ... Freeing pipeline ... [root@armadillo440-0 (ttymxc1) ~]# ls -l /mnt/test/ total 71096 -rwxr-xr-x 1 root root 72794880 Feb 28 16:33 DSC00058.rgb* -rwxr-xr-x 1 root root 0 Feb 28 16:39 out.jpg* [root@armadillo440-0 (ttymxc1) ~]#
※1 圧縮対象のRAWデータ(DSC00058.rgb)について、以下の通りです。
①SONY社の以下のJPEGデータをダウンロード。
https://www.dpreview.com/sample-galleries/6733082169/sony-a7s-iii-sampl…
②以下のサイトにて、JPEGからRGB形式に変換したものをArmadillo上で使用。
https://convertio.co/ja/
※2 画像サイズの指定(2832×4240)については、※1①のサイトに記載の"Dimensions"をもとに設定しております。
コマンドのオプション指定が悪いのか、そもそも何か足りていないのか、
もし分かる方いらっしゃいましたらご教示いただけますと幸いです。
コメント
k-nakai
佐藤様
返信ありがとうございます。
> gst-launch-1.0 コマンドのなかの
> blocksize=$((2832*4240*2))
> を
> blocksize=$((2832*4240*3))
> にしてみてください。
上記の通り、実行してみましたが、failed to allocateとエラーになってしまいました。
実行結果を以下に記します。
[root@armadillo440-0 (ttymxc1) ~]# gst-launch-1.0 -vvv filesrc location=/mnt/test/DSC00058.rgb blocksize=$((2832*4240*3)) num-buffers=1 ! video/x-raw,format=RGB,width=2832,height=4240,framerate=1/1 ! jpegenc ! filesink location=/mnt/test/out.jpg Setting pipeline to PAUSED ... Pipeline is PREROLLING ... /GstPipeline:pipeline0/GstCapsFilter:capsfilter0.GstPad:src: caps = video/x-raw, format=(string)RGB, width=(int)2832, height=(int)4240, framerate=(fraction)1/1 /GstPipeline:pipeline0/GstJpegEnc:jpegenc0.GstPad:sink: caps = video/x-raw, format=(string)RGB, width=(int)2832, height=(int)4240, framerate=(fraction)1/1 (gst-launch-1.0:1676): GLib-ERROR **: /build/buildd-glib2.0_2.33.12+really2.32.4-5-armel-5oMrEa/glib2.0-2.33.12+really2.32.4/./glib/gmem.c:165: failed to allocate 36023126 bytes Trace/breakpoint trap [root@armadillo440-0 (ttymxc1) ~]#
at_makoto.sato
佐藤です。
すいません。確認させてください。
ご自身の環境では DSC00058.rgb ファイルのファイルサイズは以下のとおりになっていますが、
-rwxr-xr-x 1 root root 72794880 Feb 28 16:33 DSC00058.rgb*
実際に以下の手順をやってみますと、
①SONY社の以下のJPEGデータをダウンロード。
https://www.dpreview.com/sample-galleries/6733082169/sony-a7s-iii-sampl…
②以下のサイトにて、JPEGからRGB形式に変換したものをArmadillo上で使用。
https://convertio.co/ja/
できあがる .rgb ファイルのファイルサイズは "36023040" でした。
DSC00058.rgb を作成した手順などに誤りはないでしょうか?
k-nakai
佐藤様
中居です。
> できあがる .rgb ファイルのファイルサイズは "36023040" でした。
> DSC00058.rgb を作成した手順などに誤りはないでしょうか?
申し訳ございません。ご指摘の通りです。
誤ったファイルを指定しておりました。
記載した手順で再度DSC00058.rgbを作成したところ、ファイルサイズは"36023040"でした。
ただ、再度作成したDSC00058.rgbを指定して、"blocksize=$((2832*4240*3))"でJPEG圧縮を試してみましたが、
変わらずfailed to allocateとエラーになってしまいました。実行結果を以下に記します。
[root@armadillo440-0 (ttymxc1) ~]# gst-launch-1.0 -vvv filesrc location=/mnt/test/DSC00058.rgb blocksize=$((2832*4240*3)) num-buffers=1 ! video/x-raw,format=RGB,width=2832,height=4240,framerate=1/1 ! jpegenc ! filesink location=/mnt/test/out.jpg Setting pipeline to PAUSED ... Pipeline is PREROLLING ... /GstPipeline:pipeline0/GstCapsFilter:capsfilter0.GstPad:src: caps = video/x-raw, format=(string)RGB, width=(int)2832, height=(int)4240, framerate=(fraction)1/1 /GstPipeline:pipeline0/GstJpegEnc:jpegenc0.GstPad:sink: caps = video/x-raw, format=(string)RGB, width=(int)2832, height=(int)4240, framerate=(fraction)1/1 (gst-launch-1.0:1698): GLib-ERROR **: /build/buildd-glib2.0_2.33.12+really2.32.4-5-armel-5oMrEa/glib2.0-2.33.12+really2.32.4/./glib/gmem.c:165: failed to allocate 36023126 bytes Trace/breakpoint trap [root@armadillo440-0 (ttymxc1) ~]# ls -l /mnt/test total 35184 -rwxr-xr-x 1 root root 36023040 Mar 5 2025 DSC00058.rgb* -rwxr-xr-x 1 root root 0 Feb 28 18:23 out.jpg* [root@armadillo440-0 (ttymxc1) ~]#
at_shota.shimoyama
k-nakai
下山様
中居です。
回答ありがとうございます。
> gst-launch-1.0 -v filesrc location=/mnt/test/DSC00058.rgb ! rawvideoparse format=rgb width=2832 height=4240 ! jpegenc ! filesink location=/mnt/test/out.jpg
上記のコマンドを実行したところ、no elementのWARNINGが出力されました。
何か足りないのでしょうか。実行結果を以下に記します。
[root@armadillo440-0 (ttymxc1) ~]# gst-launch-1.0 -v filesrc location=/mnt/test/DSC00058.rgb ! rawvideoparse format=rgb width=2832 height=4240 ! jpegenc ! filesink location=/mnt/test/out.jpg WARNING: erroneous pipeline: no element "rawvideoparse" [root@armadillo440-0 (ttymxc1) ~]# ls -l /mnt/test total 35184 -rwxr-xr-x 1 root root 36023040 Mar 5 2025 DSC00058.rgb* -rwxr-xr-x 1 root root 0 Feb 28 2025 out.jpg* [root@armadillo440-0 (ttymxc1) ~]#
at_shota.shimoyama
中居様
すみません、rawvideoparseだったらもしかしたらと思ったんですが、
gstreamerのバージョンが古くてrawvideoparseエレメントがそもそも無かったようですね…
(gst-launch-1.0:1698): GLib-ERROR **: /build/buildd-glib2.0_2.33.12+really2.32.4-5-armel-5oMrEa/glib2.0-2.33.12+really2.32.4/./glib/gmem.c:165: failed to allocate 36023126 bytes
元々のコマンドのエラー内容に戻りますが、こちらは36MBの領域の割り当てに失敗しているという意味です。
ほぼ画像のサイズと同じなので、おそらくgstreamerの内部で画像と同じサイズの領域以上をメモリに確保する処理があり、
メモリ不足のために失敗していると思われます。
ですので、解決するためには、
1.画像サイズを小さくする
2.gstreamerではなく、(動作は確認していませんが)libjpegや省メモリな組み込み向けのJPEG圧縮ソフト
https://github.com/bitbank2/JPEGENC
などを試してみる
3.Armadillo-640などのより豊富なメモリのCPUボードを使用する
などが考えられます。
差し支えなければ
・Armadillo-440の使用
・JPEG圧縮
の背景についてお聞きしてもよろしいでしょうか?
よろしくお願いします。
k-nakai
下山様
回答ありがとうございます。
また、返信が遅くなってしまい申し訳ございません。
> gstreamerのバージョンが古くてrawvideoparseエレメントがそもそも無かったようですね…
"--gst-debug=6"でデバッグログを出力してみたところ、videoparseエレメントではないかという内容が読み取れました。
videoparseエレメントで試したところ、"no element"のWARNINGは出力されませんでしたが、
"failed to allocate 36023126 bytes"のエラーが再び出力されるようになりました。
上記のエラーはメモリ不足によるものなのですね。また解決策について、ご提示ありがとうございます。
一番有力なのは、"1.画像サイズを小さくする"だと思います。
まだ入手できていないのですが、本番環境で使用想定の画像サイズ(※)は
テスト用で使用している画像より小さい想定です。入手でき次第再度試してみようと思います。
※同様の画像サイズのものがなかったため、テスト用では異なる画像サイズを使用しておりました。
> 差し支えなければ
> ・Armadillo-440の使用
> ・JPEG圧縮
> の背景についてお聞きしてもよろしいでしょうか?
上記に関してですが、どちらも「顧客からの要望のため」という回答になってしまいます。
ただし、Armadillo-440の使用については確定事項ではなく、使用する可能性が高いという段階です。
ご期待する回答ではないかもしれませんが、よろしくお願いいたします。
at_kazutaka.bito
尾藤です。
RGB形式をJPEG圧縮するだけのプログラム(お試し用。エラー処理とかない)です。
ATDE5でrgb2jpeg.cを作成します。
補足)ソースコード内で、WindowsPCのペイントで作成した
1920x1080の24ビットbmp(ヘッダ(DIB?)付き:54Byte)用に固定にしてます。
rgb2jpeg.c
#include <stdio.h> #include <stdlib.h> #include <memory.h> #include <jpeglib.h> #define RAW_WIDTH 1920 // 2832 // 4k:3840 // fhd:1920 #define RAW_HEIGHT 1080 // 4240 // 4k:2160 // fhd:1080 #define PIX_SIZE 3 // RGB888 #define HEADER 54 // header length #define JPEG_QUALITY 10 char rgb_file[] = "/mnt/original.bmp"; char jpg_file[] = "/home/www-data/result.jpg"; int main() { struct jpeg_compress_struct cinfo; struct jpeg_error_mgr jerr; FILE *outfile; FILE *infile; JSAMPARRAY img; int i, j; unsigned char *img_buf; img_buf = (unsigned char*)malloc(RAW_WIDTH *RAW_HEIGHT * 3 + HEADER); infile = fopen(rgb_file, "rb"); fread(img_buf, PIX_SIZE, RAW_WIDTH * RAW_HEIGHT + HEADER, infile); fclose(infile); img = (JSAMPARRAY)malloc(sizeof(JSAMPROW) * RAW_HEIGHT); for(i = 0; i < RAW_HEIGHT; i++) { img[i] = (JSAMPROW)malloc(sizeof(JSAMPLE) * 3 * RAW_WIDTH); for(j = 0; j < RAW_WIDTH; j++) { int org_i = RAW_HEIGHT - i; // if need to reverse virtial of original data img[i][j * 3 + 0] = *(img_buf + HEADER + (org_i * RAW_WIDTH * 3 + j * 3 + 2)); // BGR to RGB img[i][j * 3 + 1] = *(img_buf + HEADER + (org_i * RAW_WIDTH * 3 + j * 3 + 1)); // BGR to RGB img[i][j * 3 + 2] = *(img_buf + HEADER + (org_i * RAW_WIDTH * 3 + j * 3 + 0)); // BGR to RGB } } free(img_buf); cinfo.err = jpeg_std_error(&jerr); jpeg_create_compress(&cinfo); outfile = fopen(jpg_file, "wb"); jpeg_stdio_dest(&cinfo, outfile); cinfo.image_width = RAW_WIDTH; cinfo.image_height = RAW_HEIGHT; cinfo.input_components = 3; // RGB color cinfo.in_color_space = JCS_RGB; // RGB color jpeg_set_defaults(&cinfo); jpeg_set_quality(&cinfo, JPEG_QUALITY, TRUE); jpeg_start_compress(&cinfo, TRUE); jpeg_write_scanlines(&cinfo, img, RAW_HEIGHT); jpeg_finish_compress(&cinfo); jpeg_destroy_compress(&cinfo); fclose(outfile); for(i = 0; i < RAW_HEIGHT; i++) { free(img[i]); } free(img); }
ビルドします。
atmark@atde5:~$ arm-linux-gnueabi-gcc rgb2jpeg.c -o rgb2jpeg -ljpeg
ビルドにより生成された実行ファイル(rgb2jpeg)を
Armadillo-440に置いて、実行権限を付けます。
[root@armadillo440-0 (ttymxc1) ~]# chmod +x rgb2jpeg
Armadillo-440の/mntにRGBファイル(※)を「original.bmp」という名前で配置します。
備考)上記ソースのままビルドすると、DIB(54Byte)付の1920x1080のRGBファイル
original.bmpをUSBメモリのトップフォルダに置いてマウントする場合
[root@armadillo440-0 (ttymxc1) ~]# mount -t vfat /dev/sda1 /mnt
original.bmpを/mntをRAMDISKのまま置く場合(/mntのtmpfs化が必要)
[root@armadillo440-0 (ttymxc1) ~]# mount -t tmpfs tmpfs /mnt #実行後、/mntにoriginal.bmpを置く。
実行します。
[root@armadillo440-0 (ttymxc1) ~]# ./rgb2jpeg
/mnt/original.bmpをJPEG化して、/home/www/result.jpg(※)に保存されます。
※)/home/wwwに置いてあるので、PCとArmadillo-440が同一ネットワークであれば、
PCのWebブラウザで、下記のURLでJPEG化された画像が見れます。
[Armadillo-440のIPアドレス]/result.jpg
============================================
ここからが、2832×4240への挑戦です。
結論から言うと、下記制限を設けた方法でギリッギリできました。
(他のアプリ動かないと思います。できたといえるのか?)
Armadillo-440のカーネルとユーザーランドを下記にします。
Linuxカーネル ベーシックモデル用 (Linux 3.14対応) v2.08
https://armadillo.atmark-techno.com/files/downloads/armadillo-440/image…
ユーザーランド ベーシックモデル用 (Linux 3.14対応) v2.04
https://armadillo.atmark-techno.com/files/downloads/armadillo-420/image…
上記だと、RAMは80MBくらい使えます。
[root@armadillo440-0 (ttymxc1) ~]# free total used free shared buffers Mem: 123204 35524 87680 0 520 -/+ buffers: 35004 88200
rgb2jpeg.cのdefineを2832×4240用にします。
(ヘッダが54Byteを想定してます。)
#define RAW_WIDTH 2832 // 2832 // 4k:3840 // fhd:1920 #define RAW_HEIGHT 4240 // 4240 // 4k:2160 // fhd:1080 #define PIX_SIZE 3 // RGB888 #define HEADER 54 // header length #define JPEG_QUALITY 10
備考)DSC00058.rgbのサイズが、36023040byteということは、
ヘッダが無いので、この場合、HEADERは、0にします。
2832×4240のbmpファイルをoriginal.bmpという名前で作成し、
USBメモリのトップフォルダに置いてマウントします。(後述、参考1参照)
[root@armadillo440-0 (ttymxc1) ~]# mount -t vfat /dev/sda1 /mnt
rgb2jpegの実行と実行結果result.jpgは上述と同じです。
参考1)
実行中のメモリ消費具合を見てると、使用可能な約80MB中、ほぼ80MB消費してました。
(つまり、2832×4240のbmpファイルをArmadillo-440のRAMDISKに置く余裕は全くないので、
USBメモリをマウントして、USBメモリ上のoriginal.bmpを直接扱うようにしてます。)
参考2)
JPEG_QUALITY
を上げると、生成されるJPEGファイルが大きくなりメモリを消費します。
ちなみに、圧縮率の悪そうなurandamで作った2832×4240を試すと、
JPEG_QUALITY 10
で、JPEGファイルサイズが1MBちょい、が限界でした。
(普通の画像はここまで圧縮率悪くないので、JPEG_QUALITYは上げれるかと思います。)
参考3)
上下が逆転する、RGBが入れ替わる、などの場合は、rgb2jpeg.cの下記の箇所を調整ください。
int org_i = RAW_HEIGHT - i; // if need to reverse virtial of original data img[i][j * 3 + 0] = *(img_buf + HEADER + (org_i * RAW_WIDTH * 3 + j * 3 + 2)); // BGR to RGB img[i][j * 3 + 1] = *(img_buf + HEADER + (org_i * RAW_WIDTH * 3 + j * 3 + 1)); // BGR to RGB img[i][j * 3 + 2] = *(img_buf + HEADER + (org_i * RAW_WIDTH * 3 + j * 3 + 0)); // BGR to RGB
at_shota.shimoyama
中居様
> まだ入手できていないのですが、本番環境で使用想定の画像サイズ(※)は
> テスト用で使用している画像より小さい想定です。入手でき次第再度試してみようと思います。
> ※同様の画像サイズのものがなかったため、テスト用では異なる画像サイズを使用しておりました。
左様でしたか。差し支えなければ本番環境で使用想定の画像サイズをお聞きしてもよろしいでしょうか?
(もし具体的なサイズが分かっていれば、ツールなどで用意できるのではないかと思った次第です)
ちなみに、前の回答で
2.gstreamerではなく、(動作は確認していませんが)libjpegや省メモリな組み込み向けのJPEG圧縮ソフト
https://github.com/bitbank2/JPEGENC
などを試してみる
と申し上げましたが、libjpeg-toolsとJPEGENCについてDSC00058の画像でそれぞれ検証してみました。
結論ですが、libjpeg-toolsについてはgstreamer同様、メモリ不足となりJPEG圧縮できませんでした。
JPEGENCについては素のままでは化け&メモリ不足となりJPEG圧縮できませんでしたが、
化け&メモリ不足どちらも解消するパッチを作ったところ、DSC00058でもJPEG圧縮することができました。
■パッチを当てたJPEGENCの使用方法
以下、JPEGENCにパッチを当てて使用する手順になります。ご参考になれば幸いです。
1.ATDE5のホームディレクトリでJPEGENCをダウンロードする
atmark@atde5:~$ git clone https://github.com/bitbank2/JPEGENC.git
2.~/JPEGENC/ に添付のパッチファイル(jpegenc_readbmp-memsave.patch)をコピー
3.パッチを適用
atmark@atde5:~$ cd JPEGENC atmark@atde5:~/JPEGENC$ cat jpegenc_readbmp-memsave.patch | patch -p1
4.コンパイル
atmark@atde5:~/JPEGENC$ cd linux atmark@atde5:~/JPEGENC/linux$ CC=arm-linux-gnueabi-gcc CXX=arm-linux-gnueabi-g++ make
5.~/JPEGENC/linux/jpegenc というバイナリができるので、これをArmadilloにコピーします。
6./mnt/test.bmpを/mnt/test.jpgにJPEG圧縮
[root@armadillo440-0 (ttymxc1) ~]# ./jpegenc /mnt/test.bmp /mnt/test.jpg
■JPEGENC使用の前提
JPEGENCを使用するにあたって、入力ファイルはWindows BMP形式(.bmp)である必要があります。
.bmpと.rgbとの違いはほとんどヘッダーの有無です。
入力画像を.bmpとして入手できれば確実ですが、もし.rgbとして入手することが決まっている場合は、
.rgbにヘッダーをつけて.bmpにするようなプログラムを用意するか、JPEGENC内のヘッダー読み取り部分の処理を改造して.rgb対応のプログラムに直すかといった処置が必要になると思います。
■パッチを当てたJPEGENCの使用メモリ量
元々のJPEGENCでは入力画像2枚分のメモリの空き容量(DSC00058であれば72MB)が必要なのですが、入力画像1枚分の空き容量(DSC00058であれば36MB)で済むようにプログラムを修正しました。
何かご不明な点がございましたら遠慮なくお聞きください。
よろしくおねがいします。
ファイル | ファイルの説明 |
---|---|
jpegenc_readbmp-memsave.patch |
sirakawa
at_makoto.sato
2025年3月5日 17時51分
佐藤です。
gst-launch-1.0 コマンドのなかの
blocksize=$((2832*4240*2))
を
blocksize=$((2832*4240*3))
にしてみてください。