目次: Linux
半年経ったら完全に忘れるのでメモします。最近JPEGのデコードエンコードが必要になって色々調べていました。Jetson特有のAPI群がありまして、API名はJetson Linux API(のなかのMultimedia APIs)だそうです(Jetson Linux APIドキュメント)。ハードウェアJPEGデコーダ/エンコーダ(NVJPG)を自動的に使用してくれます。
今回はエンコードのAPIをご紹介します。APIの使い方は簡単です。こんな感じでした。
	NvJPEGEncoder *jpgenc = nullptr;
	NvBuffer *inbuf = nullptr;
	uint8_t *buffer = nullptr;
	size_t bufsize = 0;
	int r;
	// Create
	jpgenc = NvJPEGEncoder::createJPEGEncoder("jpgenc");
	// Align
#define ALIGN_2N(a, b)    (((a) + (b) - 1) & ~((b) - 1))
	NvBuffer::NvBufferPlaneFormat fmts[3];
	fmts[0].width = width;
	fmts[0].height = height;
	fmts[0].bytesperpixel = 1;
	fmts[0].stride = ALIGN_2N(width, 256);
	fmts[0].sizeimage = fmts[0].stride * fmts[0].height;
	fmts[1].width = width / 2;
	fmts[1].height = height / 2;
	fmts[1].bytesperpixel = 1;
	fmts[1].stride = ALIGN_2N(width / 2, 256);
	fmts[1].sizeimage = fmts[1].stride * fmts[1].height;
	fmts[2].width = width / 2;
	fmts[2].height = height / 2;
	fmts[2].bytesperpixel = 1;
	fmts[2].stride = ALIGN_2N(width / 2, 256);
	fmts[2].sizeimage = fmts[2].stride * fmts[2].height;
	inbuf = new NvBuffer(V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE, V4L2_MEMORY_USERPTR, 3, fmts, 0);
	if (!inbuf) {
		printf("error in %s:%d\n", __func__, __LINE__);
		return -1;
	}
	r = inbuf->allocateMemory();
	if (r) {
		printf("error in %s:%d\n", __func__, __LINE__);
		return -1;
	}
	bufsize = width * height * 3 / 2;
	buffer = (uint8_t *)malloc(bufsize);
	// Encoding
	uint8_t *jpegbuf = buffer;
	size_t jpegsize = bufsize;
	int quality = 80;
	r = jpgenc->encodeFromBuffer(*inbuf, JCS_YCbCr, &jpegbuf, jpegsize, quality);
	// Destroy
	free(buffer);
	delete inbuf;
	delete jpgenc;
若干NvBufferの確保がややこしいです(参考: NvBufferPlaneのドキュメント、その隣のNvBufferPlaneFormatも参考になります)けど、基本的にはencodeFromBuffer()を呼ぶだけです。
ソースコードを置いておきます。
使い方はコードの先頭にコメントで書いている通りですが、ここでも説明しておきます。引数はありません。ファイル名test_420.yuvのRaw YUV420ファイルを読み込んで、ファイル名jetson_420.jpgのJPEGファイルを書き出します。
$ g++ -g -O2 -g -Wall \
    -I jetson_multimedia_api/include/ \
    -I jetson_multimedia_api/include/libjpeg-8b/ \
    jetson_multimedia_api/samples/common/classes/NvJpegDecoder.cpp \
    jetson_multimedia_api/samples/common/classes/NvJpegEncoder.cpp \
    jetson_multimedia_api/samples/common/classes/NvBuffer.cpp \
    jetson_multimedia_api/samples/common/classes/NvElement.cpp \
    jetson_multimedia_api/samples/common/classes/NvElementProfiler.cpp \
    jetson_multimedia_api/samples/common/classes/NvLogging.cpp \
    jetson_enc.cpp \
    -L /usr/lib/aarch64-linux-gnu/nvidia/ \
    -lnvjpeg
$ ./a.out
$ ffplay -i jetson_420.jpg
エンコード結果はJPEGです。ffplayでも普段お使いの画像ビューアでも、何を使って確認しても構いません。
 この記事にコメントする
 この記事にコメントする
目次: Linux
半年経ったら完全に忘れるのでメモします。最近JPEGのデコードエンコードが必要になって色々調べていました。Jetson特有のAPI群がありまして、API名はJetson Linux API(のなかのMultimedia APIs)だそうです(Jetson Linux APIドキュメント)。ハードウェアJPEGデコーダ/エンコーダ(NVJPG)を自動的に使用してくれます。
今回はデコードのAPIをご紹介します。APIの使い方は簡単でこんな感じでした。
	NvJPEGDecoder *jpgdec = nullptr;
	NvBuffer *outbuf = nullptr;
	int r;
	// Create
	jpgdec = NvJPEGDecoder::createJPEGDecoder("jpgdec");
	// Decoding
	uint32_t jpeg_pixfmt;
	uint32_t jpeg_width;
	uint32_t jpeg_height;
	r = jpgdec->decodeToBuffer(&outbuf, jpegbuf, jpegsize, &jpeg_pixfmt, &jpeg_width, &jpeg_height);
	// Destroy
	delete outbuf;
	delete jpgdec;
注意すべき点は2つあります。1つ目はdecodeToBuffer()が勝手にoutbufを確保して返してくるので、delete outbufしなければならないことです。Turbo JPEGと異なり、予めバッファを確保しておけばメモリ確保処理を回避するような仕組みはなさそうでした。イマイチです。
2つ目はProgressive JPEGがデコードできないことです。デコードしようとするとdecodeToBuffer()でハングします。どんなJPEGファイルが来るかわからない状況で使う場合、JPEGファイルの中身をチェックしてBaseline JPEGはハードウェアデコード、Progressive JPEGはソフトウェアデコードする仕組みが必要です。
しかし前に話したとおりJetson APIの裏にいるlibnvjpeg.soが謎にIJG JPEGのAPIを実装しているため、本家IJG JPEGのlibjpeg.soがリンクできません。この状態でどうやってProgressive JPEGをソフトウェアデコードすれば良いのでしょう。Jetson APIの裏にいるlibnvjpeg.soをIJG JPEGだと思って呼べば動作するんでしょうか?
ソースコードを置いておきます。
使い方はコードの先頭にコメントで書いている通りですが、ここでも説明しておきます。引数はありません。ファイル名test_420.yuvのRaw YUV420ファイルを読み込んで、ファイル名jetson_420.jpgのJPEGファイルを書き出します。
$ g++ -g -O2 -g -Wall \
    -I jetson_multimedia_api/include/ \
    -I jetson_multimedia_api/include/libjpeg-8b/ \
    jetson_multimedia_api/samples/common/classes/NvJpegDecoder.cpp \
    jetson_multimedia_api/samples/common/classes/NvJpegEncoder.cpp \
    jetson_multimedia_api/samples/common/classes/NvBuffer.cpp \
    jetson_multimedia_api/samples/common/classes/NvElement.cpp \
    jetson_multimedia_api/samples/common/classes/NvElementProfiler.cpp \
    jetson_multimedia_api/samples/common/classes/NvLogging.cpp \
    jetson_dec.cpp \
    -L /usr/lib/aarch64-linux-gnu/nvidia/ \
    -lnvjpeg
$ ./a.out
$ ffplay -f rawvideo -video_size 1920x1440 -pixel_format yuv420p -i jetson_420.yuv
デコード結果のRawvideoを確認するときはffplayを使うと便利です。
 この記事にコメントする
 この記事にコメントする
目次: Linux
半年経ったら完全に忘れるのでメモします。最近JPEGのデコードエンコードが必要になって色々調べていました。Jetson特有のAPI群がありまして、API名はJetson Linux API(のなかのMultimedia APIs)だそうです(Jetson Linux APIドキュメント)。
Jetsonを持っていないと使えません。最新機種はJetson AGX OrinかJetson Orin Nanoですが、AGX Orinは40万円、Orin Nanoは10万円近くするボッタクリ価格です。Xavierまではそこそこ安かったのにねえ……。
Jetson Linux APIがもしシステムにインストールされていなければapt-get install nvidia-l4t-jetson-multimedia-apiで使えるようになるはずです。Jetson用のパッケージは一覧があります(一覧へのリンク)ので、手動でダウンロードしたいときにはありがたいですね。
Jetson Linux APIは実装も使い方もかなり独特というか……はっきり言って変です。
変な点その1、APIの提供方法です。API実装は/usr/src/jetson_multimedia_api/samples/common/classesにソースコードで置かれています。ライセンスはBSDライセンスです。なぜ*.soや*.aで提供しないのでしょう?
後ほど紹介するJPEGデコード、エンコードのコンパイルにはNvJpegDecoder.cppとNvJpegEncoder.cppとお供のツール類が必要ですから、あえてディレクトリ名を省かずに書くと、下記のようなコマンドでコンパイルできます。面倒ならばjetson_multimedia_api/samples/common/classes/*.cppで良いです、NVIDIA提供のサンプルもワイルドカードを使っていました。
g++ -O2 -g -Wall \ -I jetson_multimedia_api/include/ \ -I jetson_multimedia_api/include/libjpeg-8b/ \ jetson_multimedia_api/samples/common/classes/NvJpegDecoder.cpp \ jetson_multimedia_api/samples/common/classes/NvJpegEncoder.cpp \ jetson_multimedia_api/samples/common/classes/NvBuffer.cpp \ jetson_multimedia_api/samples/common/classes/NvElement.cpp \ jetson_multimedia_api/samples/common/classes/NvElementProfiler.cpp \ jetson_multimedia_api/samples/common/classes/NvLogging.cpp \ (自分のソースコード) \ -L /usr/lib/aarch64-linux-gnu/nvidia/ \ -lnvjpeg
変な点その2、JPEG機能のヘッダ名です。jetson_multimedia_api/include/NvJpegDecoder.hを見ると、JPEG関連の機能はjetson_multimedia_api/include/libjpeg-8b/jpeglib.hにあるjpeglib.hヘッダにて定義されています。そう、このヘッダ名はIJG JPEGライブラリのヘッダと同じ名前です。なぜそんな場所にヘッダを置くのか?IJG JPEGと互換性がない(APIが増えている)のになぜ同じ名前?
変な点その3、JPEG機能のライブラリ名です。jpeglib.hだからlibjpeg.soかと思うじゃないですか、それは罠でリンクすべきはlibnvjpeg.soです。良くないことにlibjpeg.soも存在していて、さらに良くないことにデコード機能だけ使っている場合は間違ってlibjpeg.soを指定してもリンクできてしまい、
$ ./a.out JPEG parameter struct mismatch: library thinks size is 656, caller expects 776
実行時にこのようなエラーが出るだけでうんともすんとも動きません。IJG JPEGと同じAPI名にするならTurbo JPEGのようにlibjpeg.soの方も置き換えれば問題は起きなかったのに、なぜ中途半端な実装に?
変な点その4、Jetson APIとNVJPEGの衝突です。以前紹介したNVJPEGはJetsonでも動きますがインストールはオススメしないです。
この2つが両方ともインストールされ、同じ-lnvjpegでリンクしてもライブラリパスによってリンクエラーになったり実行時のダイナミックリンクエラーになります。全く違う機能とAPI体系なのに、なぜ同じライブラリ名になっているの?
JPEGデコードの話は次にしたいと思います。Jetsonは適当なのか突貫なのか知りませんが、すっごい変だしちょっと使っただけなのに無限に疑問が出てきます。みんな良くこんなの使ってるなあ……。
 この記事にコメントする
 この記事にコメントする
目次: Linux
FFMPEG(ffmpeg)を使ってYUV420やYUV444のrawvideo画像を生成する方法です。元にしたJPEG画像の解像度は1920x1440なので、YUV444の場合は1920 * 1440 * 3 = 8294400バイト、YUV420の場合は1920 * 1440 * 1.5 = 4147200バイトになるはずです。
$ ffmpeg -i test_420.jpg -f rawvideo -pix_fmt yuvj444p output_444.yuv $ ls -la output.yuv -rw-r--r-- 1 katsuhiro katsuhiro 8294400 12月 4 00:43 output_444.yuv $ ffmpeg -i test_420.jpg -f rawvideo -pix_fmt yuvj420p output_420.yuv $ ls -la output_420.yuv -rw-r--r-- 1 katsuhiro katsuhiro 4147200 12月 4 00:44 output_420.yuv
FFMPEG(ffplay)を使ってYUV420やYUV444のrawvideo画像を表示する方法です。ffmpegとffplayはピクセルフォーマットのオプションが微妙に違うのが嫌なところですね……。
$ ffplay -f rawvideo -video_size 1920x1440 -pixel_format yuv420p output_420.yuv
 この記事にコメントする
 この記事にコメントする
目次: Linux
半年経ったら完全に忘れるのでメモします。最近JPEGのデコードエンコードが必要になって色々調べていました。libjpeg-turboを使ってJPEGのデコードとエンコードを行う方法を紹介します(公式ドキュメントへのリンク)。
以前(2024年11月25日の日記参照)紹介したようにlibjpeg-turboは2.x系と3.x系の2系統のAPIがありまして、今回は2.x系APIの使い方を紹介します。DebianやUbuntuのaptパッケージだと2.x系が使われているので特に困らないと思いますが、最新版をビルドして使う場合は3.x系APIになるのでご注意ください。
デコードと対になるような作りです。libjpeg-turboはとても簡単でありがたい。
	tj_handle = tjInitCompress();
	// Rawvideo
	img_stride[0] = width;
	img_stride[1] = width / 2;
	img_stride[2] = width / 2;
	img_buf[0] = (uint8_t *)malloc(img_stride[0] * height);
	img_buf[1] = (uint8_t *)malloc(img_stride[1] * height / 2);
	img_buf[2] = (uint8_t *)malloc(img_stride[2] * height / 2);
	// Encoding
	tjCompressFromYUVPlanes(tj_handle, (const uint8_t **)img_buf, width, img_stride, height, subsamp, &jpegbuf, &jpegsize, quality, 0);
	// Destroy
	free(img_buf[0]);
	free(img_buf[1]);
	free(img_buf[2]);
	tjDestroy(tj_handle);
デコード同様にinitしてエンコードするだけです。デコードと違う点が1つあって、エンコードではJPEGを格納するバッファ(上記だとjpegbuf)のサイズが不明である問題があります。解決方法は2つあります。連続でエンコードする場合など、メモリの確保解放を減らしたい場合は1番目が良いでしょう。1枚だけエンコードするだけならどちらでも構いません。
やってはいけないのが1番目だけどバッファサイズが不足することです。エンコード関数が勝手にバッファmalloc()してポインタを返してきて、元々確保していたバッファが行方不明になってしまいます。メモリリークするので注意が必要です。
私のコードは1番目の方法をとっていて、バッファサイズはYUV420つまり非圧縮時のサイズです。非圧縮時のサイズを上回ることはほぼないらしいのであまり問題ないはず。気になる人はlibjpeg-turboのAPIにJPEGサイズの最大値を返すtjBufSize()があるので、APIが返す値でjpegbufを確保するのが正しいお作法です。
ソースコードを置いておきます。
使い方はコードの先頭にコメントで書いている通りですが、ここでも説明しておきます。引数はありません。ファイル名test_420.yuvのRaw YUV420ファイルを読み込んで、ファイル名turbo2_420.jpgのJPEGファイルを書き出します。
$ g++ -g -O2 -Wall 20241205_turbo2_enc.cpp -lturbojpeg $ ./a.out $ ffplay -i turbo2_420.jpg
エンコード結果はJPEGです。ffplayでも普段お使いの画像ビューアでも、何を使って確認しても構いません。
 この記事にコメントする
 この記事にコメントする
目次: Linux
半年経ったら完全に忘れるのでメモします。最近JPEGのデコードエンコードが必要になって色々調べていました。libjpeg-turboを使ってJPEGのデコードとエンコードを行う方法を紹介します(公式ドキュメントへのリンク)。
以前(2024年11月25日の日記参照)紹介したようにlibjpeg-turboは2.x系と3.x系の2系統のAPIがありまして、今回は2.x系APIの使い方を紹介します。DebianやUbuntuのaptパッケージだと2.x系が使われているので特に困らないと思いますが、最新版をビルドして使う場合は3.x系APIになるのでご注意ください。
前に使ったnvJPEGは訳のわからん儀式が必要でしたが、libjpeg-turboはとても簡単です。
	// Create
	tj_handle = tjInitDecompress();
		
	// Rawvideo
	img_stride[0] = width;
	img_stride[1] = width / 2;
	img_stride[2] = width / 2;
	img_sz[0] = img_stride[0] * height;
	img_sz[1] = img_stride[1] * height / 2;
	img_sz[2] = img_stride[2] * height / 2;
	img_buf[0] = (uint8_t *)malloc(img_sz[0]);
	img_buf[1] = (uint8_t *)malloc(img_sz[1]);
	img_buf[2] = (uint8_t *)malloc(img_sz[2]);
	// Decoding
	tjDecompressToYUVPlanes(tj_handle, jpegbuf, jpegsize, img_buf, width, img_stride, height, 0);
	// Destroy
	free(img_buf[0]);
	free(img_buf[1]);
	free(img_buf[2]);
	tjDestroy(tj_handle);
基本的にはinitしてデコードするだけです。
ソースコードを置いておきます。
使い方はコードの先頭にコメントで書いている通りですが、ここでも説明しておきます。引数はありません。ファイル名test_420.jpgのJPEGファイルを読み込んで、ファイル名turbo2_420.yuvのRawvideoファイルを書き出します。
$ g++ -g -O2 -Wall 20241204_turbo2_dec.cpp -lturbojpeg $ ./a.out $ ffplay -f rawvideo -video_size 1920x1440 -pixel_format yuv420p -i turbo2_420.yuv
デコード結果のRawvideoを確認するときはffplayを使うと便利です。
 この記事にコメントする
 この記事にコメントする
目次: Linux
Debian Testingのapt-get updateをしたら、xrdp経由で起動しているX.orgがエラーで起動しなくなりました。こんなエラーが出ています。
[  1416.016] (EE)
[  1416.016] (EE) Backtrace:
[  1416.016] (EE) 0: /usr/lib/xorg/Xorg (OsLookupColor+0x14d) [0x556fb13c8dad]
[  1416.017] (EE) 1: /lib/x86_64-linux-gnu/libc.so.6 (__sigaction+0x40) [0x7f084f9dad20]
[  1416.017] (EE) 2: /lib/x86_64-linux-gnu/libc.so.6 (pthread_key_delete+0x14c) [0x7f084fa2ee5c]
[  1416.017] (EE) 3: /lib/x86_64-linux-gnu/libc.so.6 (gsignal+0x12) [0x7f084f9dac82]
[  1416.018] (EE) 4: /lib/x86_64-linux-gnu/libc.so.6 (abort+0xd3) [0x7f084f9c34f0]
[  1416.018] (EE) 5: /lib/x86_64-linux-gnu/libc.so.6 (perror+0xcb7) [0x7f084f9c432d]
[  1416.018] (EE) 6: /lib/x86_64-linux-gnu/libc.so.6 (timer_settime+0x395) [0x7f084fa389e5]
[  1416.019] (EE) 7: /lib/x86_64-linux-gnu/libc.so.6 (timer_settime+0x59c) [0x7f084fa38bec]
[  1416.019] (EE) 8: /lib/x86_64-linux-gnu/libc.so.6 (__libc_free+0xb8) [0x7f084fa3d548]
[  1416.019] (EE) 9: /lib/x86_64-linux-gnu/libdrm.so.2 (drmFreeDevice+0x7d) [0x7f084febf13d]
[  1416.020] (EE) 10: /lib/x86_64-linux-gnu/libdrm.so.2 (drmFreeDevices+0x2e) [0x7f084febf2ae]
[  1416.020] (EE) 11: /lib/x86_64-linux-gnu/libnvidia-egl-gbm.so.1 (loadEGLExternalPlatform+0x8a8) [0x7f084477dd18]
[  1416.020] (EE) 12: /lib/x86_64-linux-gnu/libEGL_nvidia.so.0 (NvEglwlaf47906in+0x6e240) [0x7f08404ad480]
[  1416.020] (EE) 13: /lib/x86_64-linux-gnu/libEGL_nvidia.so.0 (NvEglwlaf47906in+0xd73c) [0x7f084044c97c]
[  1416.020] (EE) unw_get_proc_name failed: no unwind info found [-10]
[  1416.020] (EE) 14: /lib/x86_64-linux-gnu/libEGL.so.1 (?+0x0) [0x7f0844a6ead5]
[  1416.020] (EE) unw_get_proc_name failed: no unwind info found [-10]
[  1416.020] (EE) 15: /usr/lib/x86_64-linux-gnu/dri/swrast_dri.so (?+0x0) [0x7f0844aaf3f3]
[  1416.021] (EE) unw_get_proc_name failed: no unwind info found [-10]
[  1416.021] (EE) 16: /usr/lib/xorg/modules/extensions/libglx.so (?+0x0) [0x7f084f65cbe3]
[  1416.021] (EE) unw_get_proc_name failed: no unwind info found [-10]
[  1416.021] (EE) 17: /usr/lib/xorg/modules/extensions/libglx.so (?+0x0) [0x7f084f65ba1f]
[  1416.021] (EE) 18: /usr/lib/xorg/Xorg (_CallCallbacks+0x3c) [0x556fb125002c]
[  1416.021] (EE) 19: /usr/lib/xorg/Xorg (dri3_send_open_reply+0x111f) [0x556fb138334f]
[  1416.021] (EE) 20: /usr/lib/xorg/Xorg (InitExtensions+0x89) [0x556fb12bde29]
[  1416.021] (EE) 21: /usr/lib/xorg/Xorg (InitFonts+0x1f8) [0x556fb124e968]
[  1416.022] (EE) 22: /lib/x86_64-linux-gnu/libc.so.6 (__libc_init_first+0x88) [0x7f084f9c4d68]
[  1416.022] (EE) 23: /lib/x86_64-linux-gnu/libc.so.6 (__libc_start_main+0x85) [0x7f084f9c4e25]
[  1416.022] (EE) 24: /usr/lib/xorg/Xorg (_start+0x21) [0x556fb12373f1]
[  1416.022] (EE)
[  1416.022] (EE)
Fatal server error:
[  1416.022] (EE) Caught signal 6 (Aborted). Server aborting
[  1416.022] (EE)
[  1416.022] (EE)
Please consult the The X.Org Foundation support
         at http://wiki.x.org
 for help.
[  1416.022] (EE) Please also check the log file at ".xorgxrdp.10.log" for additional information.
[  1416.022] (EE)
[  1416.022] rdpLeaveVT:
[  1416.022] (EE) Server terminated with error (1). Closing log file.
エラーの原因であるlibEGL_nvidia.soを削除すれば起動しそうだったので、libegl-nvidia0パッケージを消したところX.orgが起動しました。めでたしめでたし……ではありません。どうしてこうなった?
他にも何か起きているだろうか?と調べたらCUDAが使えないし、nvidia-smiがデバイスがないと言っています。NVIDIA系の機能が全滅です。どうやらnvidia.koが消滅していて、GPUカードが認識されなくなったようです。NVIDIAドライバパッケージを再インストールするとこんなメッセージが出ました。
nvidia-kernel-dkms (535.216.03-1) を設定しています ... Loading new nvidia-current-535.216.03 DKMS files... Building for 6.11.10-amd64 Module build for kernel 6.11.10-amd64 was skipped since the kernel headers for this kernel do not seem to be installed.
メッセージはカーネルヘッダをインストールしないとカーネルモジュールがビルドされないとおっしゃっています。カーネルヘッダパッケージlinux-headers-6.11.10-amd64をインストールしたところ無事/lib/modules/6.11.10-amd64/updates/dkms/の下にnvidia-current.ko.xzが生成され、CUDAが復活しました。めでたしめでたし……じゃないんだ、まだ。
X.orgは/dev/driの下にあるデバイスファイルにアクセスするので、DRM関連のドライバも必要です。DRM用のドライバパッケージをインストールするとnvidia-current-drm.ko.xzが生成されます。たしかパッケージ名はnvidia-vdpau-driverだったと思います。
カーネルモジュールが生成されたらmodprobe nvidia-drmでロードすれば/dev/dri/card0が出現します。先ほど削除したlibegl-nvidia0パッケージを再インストールしてもX.orgの起動に失敗しなくなりました。めでたしめでたし。
とはいえxrdp経由で起動していると、DRMが有効でも"unsupported render mode"と言われてしまってHWアクセラレーションが効いてなさそうに見えます。せっかく直したのに悲しいですね……。
 この記事にコメントする
 この記事にコメントする
| < | 2024 | > | ||||
| << | < | 12 | > | >> | ||
| 日 | 月 | 火 | 水 | 木 | 金 | 土 | 
| 1 | 2 | 3 | 4 | 5 | 6 | 7 | 
| 8 | 9 | 10 | 11 | 12 | 13 | 14 | 
| 15 | 16 | 17 | 18 | 19 | 20 | 21 | 
| 22 | 23 | 24 | 25 | 26 | 27 | 28 | 
| 29 | 30 | 31 | - | - | - | - | 
 25年10月27日
 25年10月27日
 23年4月10日
 23年4月10日
 25年10月15日
 25年10月15日
 25年10月18日
 25年10月18日
 22年5月5日
 22年5月5日
 25年10月19日
 25年10月19日
 23年4月11日
 23年4月11日
 06年4月22日
 06年4月22日
 25年10月17日
 25年10月17日
 25年10月6日
 25年10月6日
 25年10月13日
 25年10月13日
 20年10月23日
 20年10月23日
 25年10月12日
 25年10月12日
 20年8月29日
 20年8月29日
 19年1月13日
 19年1月13日
 18年10月13日
 18年10月13日
 18年9月3日
 18年9月3日
 18年8月20日
 18年8月20日
 18年7月23日
 18年7月23日
 18年7月22日
 18年7月22日
 wiki
 wiki Linux JM
 Linux JM Java API
 Java API 2002年
 2002年 2003年
 2003年 2004年
 2004年 2005年
 2005年 2006年
 2006年 2007年
 2007年 2008年
 2008年 2009年
 2009年 2010年
 2010年 2011年
 2011年 2012年
 2012年 2013年
 2013年 2014年
 2014年 2015年
 2015年 2016年
 2016年 2017年
 2017年 2018年
 2018年 2019年
 2019年 2020年
 2020年 2021年
 2021年 2022年
 2022年 2023年
 2023年 2024年
 2024年 2025年
 2025年 過去日記について
 過去日記について アクセス統計
 アクセス統計 サーバ一覧
 サーバ一覧 サイトの情報
 サイトの情報合計: 
本日: