Issue
I have Android native code (C++
shared object), that want to read
model file kept in the assets
folder while creating APK.
Tensorflow Lite has two APIs: FromFile and FromBuffer
static std::unique_ptr<FlatBufferModel> BuildFromFile(const char* filename, ErrorReporter* error_reporter);
static std::unique_ptr<FlatBufferModel> BuildFromBuffer(const char* buffer, size_t buffer_size, ErrorReporter* error_reporter);
with following code i can access FromBuffer:
Java
code:
private AssetManager mgr;
// Get mgr
mgr = getResources().getAssets();
C++
code:
AAssetDir* assetDir = AAssetManager_openDir(mgr, "");
const char* filename = (const char*)NULL;
while ((filename = AAssetDir_getNextFileName(assetDir)) != NULL) {
AAsset* asset = AAssetManager_open(mgr, filename, AASSET_MODE_STREAMING);
char buf[BUFSIZ];
int nb_read = 0;
FILE* out = fopen(filename, "w");
while ((nb_read = AAsset_read(asset, buf, BUFSIZ)) > 0)
fwrite(buf, nb_read, 1, out);
fclose(out);
AAsset_close(asset);
}
AAssetDir_close(assetDir);
Any ideas, how can access assets
folder to use BuildFromFile
?
Solution
I don't think you can use BuildFromFile
without copying the asset file to a local file (which is equivalent to what you've done above, and then BuildFromBuffer
is more convenient in this case).
If you want to avoid memory copy, here is what you can do:
- (Java) Load the model through memory mapping.
AssetFileDescriptor fileDescriptor = getResources().getAssets().openFd(filePath);\
FileInputStream inputStream = new FileInputStream(fileDescriptor.getFileDescriptor());\
FileChannel fileChannel = inputStream.getChannel();\
long startOffset = fileDescriptor.getStartOffset();\
long declaredLength = fileDescriptor.getDeclaredLength();\
MappedByteBuffer modelBuffer = fileChannel.map(FileChannel.MapMode.READ_ONLY, startOffset, declaredLength);
- (Java) Pass the mapped file to C++ through jni, such as defining the following method:
private static native void initJniWithByteBuffer(ByteBuffer modelBuffer)
- (C++) Use the buffer file to initialize you model:
Java_xxxxxx_initJniWithByteBuffer(JNIEnv* env, jclass thiz, jobject model_buffer) {\
char* buffer = static_cast<char*>(env->GetDirectBufferAddress(model_buffer));\
size_t buffer_size = static_cast<size_t>(env->GetDirectBufferCapacity(model_buffer));\
}
Answered By - Lu Wang
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.