mediatomb キャッシュ機能開発

開発環境整理

  • cscope、git をインストールする。

進捗

  • 2011/04/21 完成

ソースコード調査

  • 既存のmediatombは、jpeg ファイルをメモリに展開するようだ。その箇所を特定する。
  • 設定ファイル(config.xml)の読み込み処理 config_manager.cc
  • video サムネイル処理 ffmpeg_handler.cc

  • FfmpegHandler::serveContent()
   if (video_thumbnailer_generate_thumbnail_to_buffer(th,
                                        item->getLocation().c_str(), img) != 0)
↑もろにソレっぽい名前の関数を発見。
これは ffmpegthumbnailer-2.0.6 の関数だった。
    • 引数
video_thumbnailer* thumbnailer
const char* movie_filename
image_data* generated_image_data
46 typedef struct image_data_struct
47 {
48     uint8_t*    image_data_ptr;       /* points to the image data after call to generate_thumbnail_to_buffer */
49     int         image_data_size;      /* contains the size of the image data after call to generate_thumbnail_to_buffer *    /
50
51     void*       internal_data;        /* for internal use only */
52 } image_data;

実装方法(OLD_API を削除して記述)

※意外に簡単かも・・・
316     if (video_thumbnailer_generate_thumbnail_to_buffer(th,
317                                          item->getLocation().c_str(), img) != 0)
319         throw _Exception(_("Could not generate thumbnail for ") +
320                 item->getLocation());
  • たぶん、この関数は以下のような動作をすると思う。
    • ビデオファイルのパス(input):item->getLocation().c_str()
    • サムネイル画像データ(output):バッファ img->image_data_ptr、サイズ img->image_data_size
  • よって、上記関数実行後にサムネイルファイル用のパスに img->image_data_ptr のデータをファイルに書き出せばよいはず。
  • また、書き出したファイルが次の上記関数呼び出し前に存在すれば、video_thumbnailer_generate_thumbnail_to_buffer を行わずにファイル read で代用できるはず。

321
322     *data_size = (off_t)img->image_data_size;
323     Ref<IOHandler> h(new MemIOHandler((void *)img->image_data_ptr,
324                                               img->image_data_size));
329     video_thumbnailer_destroy_image_data(img);
330     video_thumbnailer_destroy(th);

  • img->image_data_ptr, img->image_data_size をファイル書き出しすることで、
jpegファイルが作れるようになった。
  • しかし、そのファイルを img->image_data_ptr, img->image_data_size に読み込んだ
ところ、PS3 には正常に表示されない。(下半分がにじむ、ずれるなど)
  • destory_XXX() あたりを調査しなおす。

MemIOHandler::MemIOHandler(void *buffer, int length) : IOHandler()

   this->buffer = (char *)MALLOC(length);
   this->length = length;
   memcpy(this->buffer, buffer, length);

video_thumbnailer_destroy_image_data

   data->image_data_ptr    = 0;
   data->image_data_size   = 0;
   std::vector<uint8_t>* dataVector = reinterpret_cast<std::vector<uint8_t>* >(data->internal_data);
   delete dataVector;
   data->internal_data     = 0;
   delete data;

video_thumbnailer_destroy

   VideoThumbnailer* videoThumbnailer = reinterpret_cast<VideoThumbnailer*>(thumbnailer->thumbnailer);
   delete videoThumbnailer;
   FilmStripFilter* filmStripFilter = reinterpret_cast<FilmStripFilter*>(thumbnailer->filter);
   delete filmStripFilter;
   thumbnailer->thumbnailer = 0;
   delete thumbnailer;

まさかとは思ったが・・・ファイル読み込み後、return する前に 3 秒のsleep
を入れたら正しく表示されるようになった・・・
mediatombサーバとPS3間の問題(たとえば、ファイル受信完了認識の処理が甘い、など)
があるのかもしれない。
DLNAについて調べる必要がありそう・・

  • FfmpegHandler::serveContent() の呼び出し箇所
(gdb) bt
#0  FfmpegHandler::serveContent (this=0xb732bb38, item=..., resNum=1, data_size=0x32d10f0)
   at ../src/metadata/ffmpeg_handler.cc:337
#1  0x0811b34b in FileRequestHandler::open (this=0xb732d360,
   filename=0xb732d8f0 "/content/media/object_id/749/res_id/1/rh/6/ext/file.jpg", info=0x32d10f0, mode=UPNP_READ)
   at ../src/file_request_handler.cc:575
#2  0x080f3885 in web_open (filename=0xb732d8f0 "/content/media/object_id/749/res_id/1/rh/6/ext/file.jpg", info=0x32d10f0,
   mode=UPNP_READ) at ../src/web_callbacks.cc:198
#3  0x08154bbd in process_request (parser=0x32d118c, req=0x32d118c, info=0x32d126c)
   at ../upnp/src/genlib/net/http/webserver.c:1343
#4  web_server_callback (parser=0x32d118c, req=0x32d118c, info=0x32d126c) at ../upnp/src/genlib/net/http/webserver.c:1803
#5  0x0814d9c3 in dispatch_request (args=0xb6900480) at ../upnp/src/genlib/miniserver/miniserver.c:236
#6  handle_request (args=0xb6900480) at ../upnp/src/genlib/miniserver/miniserver.c:339
#7  0x0815b1d3 in WorkerThread (arg=0x81bf0c0) at ../threadutil/src/ThreadPool.c:594
#8  0x00459e99 in start_thread () from /lib/libpthread.so.0
#9  0x0075fd2e in clone () from /lib/libc.so.6
(gdb)

  • web_server_callback
    • process_request(): データの作成
    • http_SendMessage(): データの送信

(gdb) bt
#0  http_SendMessage (info=0x4ad426c, TimeOut=0x4ad413c, fmt=0x8170e46 "Ibf")
   at ../upnp/src/genlib/net/http/httpreadwrite.c:325
#1  0x081547cb in web_server_callback (parser=0x4ad418c, req=0x4ad418c, info=0x4ad426c)
   at ../upnp/src/genlib/net/http/webserver.c:1833
#2  0x0814d9c3 in dispatch_request (args=0xb6900480) at ../upnp/src/genlib/miniserver/miniserver.c:236
#3  handle_request (args=0xb6900480) at ../upnp/src/genlib/miniserver/miniserver.c:339
#4  0x0815b1d3 in WorkerThread (arg=0x81bf0c0) at ../threadutil/src/ThreadPool.c:594
#5  0x00459e99 in start_thread () from /lib/libpthread.so.0
#6  0x0075fd2e in clone () from /lib/libc.so.6
(gdb)

  • 以下で送信している。
           case RESP_WEBDOC:  //, I = further instruction to send data.
               /*
                  http_SendVirtualDirDoc( info, &timeout, "Ibf",&RespInstr,
                  headers.buf, headers.length,
                  filename.buf );
                */
               http_SendMessage( info, &timeout, "Ibf", &RespInstr,
                                 headers.buf, (size_t)headers.length,
                                 filename.buf, Fp );

ここで送信しているデータが
  • キャッシュなし(正常)
  • キャッシュあり(異常)

で違いがあるか、調査する。

→ 単なるコーディングミス。消えてしまったスタック領域を参照していたため。修正済み。
最終更新:2011年04月22日 23:55
ツールボックス

下から選んでください:

新しいページを作成する
ヘルプ / FAQ もご覧ください。