目次: サンタ
去年(2023年12月24日の日記参照)と同様に、飛行機の位置をリアルタイムに表示するFlightradar24というサービス(サイトへのリンク)にてサンタが出現しました。クリスマス・イブの日にサンタが出現するのは毎年恒例のお約束演出です。私が見たときは南米付近を飛んでいました。
去年までのサンタは表示された対地速度とサンタの位置から計算した速度が全く違っていたので、今年もチェックしてみようと思います。対地速度の表示ですが、今年は従来と異なり速度が変動しています。私が見たときの表示は11,000kts程度(20,000km/h, マッハ16くらい)でした。メチャ速いです、ジェット機なんて目じゃありません。
13:07:00時点の位置(緯度-0.26043度、経度-44.00613度)
13:08:00時点の位置(緯度1.15381度、経度-47.1023度)
去年同様、ある程度の時間をあけ(今回は1分間)でどれくらい進んだか計算します。今回も距離の計算には国土地理院のページを使いました、緯度経度から距離を一発で計算してくれて便利です(サイトへのリンク)。
2地点間の距離は約378.5km、時間差は60秒から計算すると、対地速度は約22,710km/hです。地上でのマッハ18(ただし、サンタが飛んでいる高さ60,000ftsだとマッハ数はもっと高く出る)です。地球の重力と釣り合って人工衛星になれる速度(第一宇宙速度)が28,400km/hですから、今年のサンタさんは宇宙へ行かんばかりの勢いで疾走しています。
今年は例年と異なり表示速度と進んだ距離から計算した速度が大体合っていました。だんだん改善されているんでしょうか?来年の速度も気になりますので、覚えていたらまた計算してみましょう。
目次: 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を使うと便利です。
< | 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 | - | - | - | - |
合計:
本日: