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.