Loading media/libstagefright/bqhelper/Android.bp +1 −1 Original line number Diff line number Diff line Loading @@ -4,7 +4,7 @@ cc_library_shared { vndk: { enabled: true, }, double_loadable: true, srcs: [ "Conversion.cpp", "FrameDropper.cpp", Loading media/ndk/Android.bp +29 −2 Original line number Diff line number Diff line Loading @@ -63,7 +63,6 @@ cc_library_shared { cflags: [ "-fvisibility=hidden", "-DEXPORT=__attribute__((visibility(\"default\")))", "-Werror", "-Wall", ], Loading @@ -73,6 +72,8 @@ cc_library_shared { ], shared_libs: [ "android.hardware.graphics.bufferqueue@1.0", "android.hidl.token@1.0-utils", "libbinder", "libmedia", "libmedia_omx", Loading @@ -81,12 +82,15 @@ cc_library_shared { "libmediaextractor", "libstagefright", "libstagefright_foundation", "libstagefright_bufferqueue_helper", "liblog", "libutils", "libcutils", "libandroid", "libandroid_runtime", "libbinder", "libhwbinder", "libhidlbase", "libgui", "libui", "libmedia2_jni_core", Loading @@ -105,7 +109,9 @@ cc_library_shared { llndk_library { name: "libmediandk", symbol_file: "libmediandk.map.txt", export_include_dirs: ["include"], export_include_dirs: [ "include", ], } cc_library { Loading Loading @@ -148,3 +154,24 @@ cc_library { }, }, } cc_test { name: "AImageReaderWindowHandleTest", srcs: ["tests/AImageReaderWindowHandleTest.cpp"], shared_libs: [ "libbinder", "libmediandk", "libnativewindow", "libgui", "libutils", "libui", "libcutils", "android.hardware.graphics.bufferqueue@1.0", ], cflags: [ "-D__ANDROID_VNDK__", ], include_dirs: [ "frameworks/av/media/ndk/", ], } media/ndk/NdkImageReader.cpp +98 −0 Original line number Diff line number Diff line Loading @@ -28,6 +28,7 @@ #include <android_runtime/android_view_Surface.h> #include <android_runtime/android_hardware_HardwareBuffer.h> #include <grallocusage/GrallocUsageConversion.h> #include <media/stagefright/bqhelper/WGraphicBufferProducer.h> using namespace android; Loading @@ -43,6 +44,10 @@ const char* AImageReader::kCallbackFpKey = "Callback"; const char* AImageReader::kContextKey = "Context"; const char* AImageReader::kGraphicBufferKey = "GraphicBuffer"; static constexpr int kWindowHalTokenSizeMax = 256; static native_handle_t *convertHalTokenToNativeHandle(const HalToken &halToken); bool AImageReader::isSupportedFormatAndUsage(int32_t format, uint64_t usage) { // Check whether usage has either CPU_READ_OFTEN or CPU_READ set. Note that check against Loading Loading @@ -363,6 +368,15 @@ AImageReader::~AImageReader() { mBufferItemConsumer->abandon(); mBufferItemConsumer->setFrameAvailableListener(nullptr); } if (mWindowHandle != nullptr) { int size = mWindowHandle->data[0]; hidl_vec<uint8_t> halToken; halToken.setToExternal( reinterpret_cast<uint8_t *>(&mWindowHandle->data[1]), size); deleteHalToken(halToken); native_handle_delete(mWindowHandle); } } media_status_t Loading Loading @@ -522,6 +536,25 @@ AImageReader::releaseImageLocked(AImage* image, int releaseFenceFd) { } } media_status_t AImageReader::getWindowNativeHandle(native_handle **handle) { if (mWindowHandle != nullptr) { *handle = mWindowHandle; return AMEDIA_OK; } sp<HGraphicBufferProducer> hgbp = new TWGraphicBufferProducer<HGraphicBufferProducer>(mProducer); HalToken halToken; if (!createHalToken(hgbp, &halToken)) { return AMEDIA_ERROR_UNKNOWN; } mWindowHandle = convertHalTokenToNativeHandle(halToken); if (!mWindowHandle) { return AMEDIA_ERROR_UNKNOWN; } *handle = mWindowHandle; return AMEDIA_OK; } int AImageReader::getBufferWidth(BufferItem* buffer) { if (buffer == NULL) return -1; Loading Loading @@ -585,6 +618,58 @@ AImageReader::acquireLatestImage(/*out*/AImage** image, /*out*/int* acquireFence } } static native_handle_t *convertHalTokenToNativeHandle( const HalToken &halToken) { // We attempt to store halToken in the ints of the native_handle_t after its // size. The first int stores the size of the token. We store this in an int // to avoid alignment issues where size_t and int do not have the same // alignment. size_t nhDataByteSize = halToken.size(); if (nhDataByteSize > kWindowHalTokenSizeMax) { // The size of the token isn't reasonable.. return nullptr; } size_t numInts = ceil(nhDataByteSize / sizeof(int)) + 1; // We don't check for overflow, whether numInts can fit in an int, since we // expect kWindowHalTokenSizeMax to be a reasonable limit. // create a native_handle_t with 0 numFds and numInts number of ints. native_handle_t *nh = native_handle_create(0, numInts); if (!nh) { return nullptr; } // Store the size of the token in the first int. nh->data[0] = nhDataByteSize; memcpy(&(nh->data[1]), halToken.data(), nhDataByteSize); return nh; } static sp<HGraphicBufferProducer> convertNativeHandleToHGBP ( const native_handle_t *handle) { // Read the size of the halToken vec<uint8_t> hidl_vec<uint8_t> halToken; halToken.setToExternal( reinterpret_cast<uint8_t *>(const_cast<int *>(&(handle->data[1]))), handle->data[0]); sp<HGraphicBufferProducer> hgbp = HGraphicBufferProducer::castFrom(retrieveHalInterface(halToken)); return hgbp; } EXPORT sp<HGraphicBufferProducer> AImageReader_getHGBPFromHandle( const native_handle_t *handle) { if (handle == nullptr) { return nullptr; } if (handle->numFds != 0 || handle->numInts < ceil(sizeof(size_t) / sizeof(int))) { return nullptr; } return convertNativeHandleToHGBP(handle); } EXPORT media_status_t AImageReader_new( int32_t width, int32_t height, int32_t format, int32_t maxImages, Loading @@ -594,6 +679,19 @@ media_status_t AImageReader_new( width, height, format, AHARDWAREBUFFER_USAGE_CPU_READ_OFTEN, maxImages, reader); } extern "C" { EXPORT media_status_t AImageReader_getWindowNativeHandle( AImageReader *reader, /*out*/native_handle_t **handle) { if (reader == nullptr || handle == nullptr) { return AMEDIA_ERROR_INVALID_PARAMETER; } return reader->getWindowNativeHandle(handle); } } //extern "C" EXPORT media_status_t AImageReader_newWithUsage( int32_t width, int32_t height, int32_t format, uint64_t usage, Loading media/ndk/NdkImageReaderPriv.h +9 −0 Original line number Diff line number Diff line Loading @@ -69,6 +69,8 @@ struct AImageReader : public RefBase { media_status_t acquireNextImage(/*out*/AImage** image, /*out*/int* fenceFd); media_status_t acquireLatestImage(/*out*/AImage** image, /*out*/int* fenceFd); media_status_t getWindowNativeHandle(/*out*/native_handle_t **handle); ANativeWindow* getWindow() const { return mWindow.get(); }; int32_t getWidth() const { return mWidth; }; int32_t getHeight() const { return mHeight; }; Loading Loading @@ -160,10 +162,17 @@ struct AImageReader : public RefBase { sp<Surface> mSurface; sp<BufferItemConsumer> mBufferItemConsumer; sp<ANativeWindow> mWindow; native_handle_t* mWindowHandle = nullptr; List<AImage*> mAcquiredImages; Mutex mLock; }; // Retrieves HGraphicBufferProducer corresponding to the native_handle_t // provided. This method also deletes the HalToken corresponding to the // native_handle_t. Thus, if it is used twice in succession, the second call // returns nullptr; sp<HGraphicBufferProducer> AImageReader_getHGBPFromHandle(const native_handle_t *handle); #endif // _NDK_IMAGE_READER_PRIV_H media/ndk/include/media/NdkImageReader.h +20 −0 Original line number Diff line number Diff line Loading @@ -37,6 +37,9 @@ #define _NDK_IMAGE_READER_H #include <sys/cdefs.h> #ifdef __ANDROID_VNDK__ #include <cutils/native_handle.h> #endif #include <android/native_window.h> #include "NdkMediaError.h" Loading Loading @@ -461,6 +464,23 @@ typedef struct AImageReader_BufferRemovedListener { media_status_t AImageReader_setBufferRemovedListener( AImageReader* reader, AImageReader_BufferRemovedListener* listener) __INTRODUCED_IN(26); #ifdef __ANDROID_VNDK__ /* * Get the native_handle_t corresponding to the ANativeWindow owned by the * AImageReader provided. * * @param reader The image reader of interest. * @param handle The output native_handle_t. This native handle is owned by * this image reader. * * @return AMEDIA_OK if the method call succeeds. * AMEDIA_ERROR_INVALID_PARAMETER if reader or handle are NULL. * AMEDIA_ERROR_UNKNOWN if some other error is encountered. */ media_status_t AImageReader_getWindowNativeHandle( AImageReader *reader, /* out */native_handle_t **handle); #endif #endif /* __ANDROID_API__ >= 26 */ __END_DECLS Loading Loading
media/libstagefright/bqhelper/Android.bp +1 −1 Original line number Diff line number Diff line Loading @@ -4,7 +4,7 @@ cc_library_shared { vndk: { enabled: true, }, double_loadable: true, srcs: [ "Conversion.cpp", "FrameDropper.cpp", Loading
media/ndk/Android.bp +29 −2 Original line number Diff line number Diff line Loading @@ -63,7 +63,6 @@ cc_library_shared { cflags: [ "-fvisibility=hidden", "-DEXPORT=__attribute__((visibility(\"default\")))", "-Werror", "-Wall", ], Loading @@ -73,6 +72,8 @@ cc_library_shared { ], shared_libs: [ "android.hardware.graphics.bufferqueue@1.0", "android.hidl.token@1.0-utils", "libbinder", "libmedia", "libmedia_omx", Loading @@ -81,12 +82,15 @@ cc_library_shared { "libmediaextractor", "libstagefright", "libstagefright_foundation", "libstagefright_bufferqueue_helper", "liblog", "libutils", "libcutils", "libandroid", "libandroid_runtime", "libbinder", "libhwbinder", "libhidlbase", "libgui", "libui", "libmedia2_jni_core", Loading @@ -105,7 +109,9 @@ cc_library_shared { llndk_library { name: "libmediandk", symbol_file: "libmediandk.map.txt", export_include_dirs: ["include"], export_include_dirs: [ "include", ], } cc_library { Loading Loading @@ -148,3 +154,24 @@ cc_library { }, }, } cc_test { name: "AImageReaderWindowHandleTest", srcs: ["tests/AImageReaderWindowHandleTest.cpp"], shared_libs: [ "libbinder", "libmediandk", "libnativewindow", "libgui", "libutils", "libui", "libcutils", "android.hardware.graphics.bufferqueue@1.0", ], cflags: [ "-D__ANDROID_VNDK__", ], include_dirs: [ "frameworks/av/media/ndk/", ], }
media/ndk/NdkImageReader.cpp +98 −0 Original line number Diff line number Diff line Loading @@ -28,6 +28,7 @@ #include <android_runtime/android_view_Surface.h> #include <android_runtime/android_hardware_HardwareBuffer.h> #include <grallocusage/GrallocUsageConversion.h> #include <media/stagefright/bqhelper/WGraphicBufferProducer.h> using namespace android; Loading @@ -43,6 +44,10 @@ const char* AImageReader::kCallbackFpKey = "Callback"; const char* AImageReader::kContextKey = "Context"; const char* AImageReader::kGraphicBufferKey = "GraphicBuffer"; static constexpr int kWindowHalTokenSizeMax = 256; static native_handle_t *convertHalTokenToNativeHandle(const HalToken &halToken); bool AImageReader::isSupportedFormatAndUsage(int32_t format, uint64_t usage) { // Check whether usage has either CPU_READ_OFTEN or CPU_READ set. Note that check against Loading Loading @@ -363,6 +368,15 @@ AImageReader::~AImageReader() { mBufferItemConsumer->abandon(); mBufferItemConsumer->setFrameAvailableListener(nullptr); } if (mWindowHandle != nullptr) { int size = mWindowHandle->data[0]; hidl_vec<uint8_t> halToken; halToken.setToExternal( reinterpret_cast<uint8_t *>(&mWindowHandle->data[1]), size); deleteHalToken(halToken); native_handle_delete(mWindowHandle); } } media_status_t Loading Loading @@ -522,6 +536,25 @@ AImageReader::releaseImageLocked(AImage* image, int releaseFenceFd) { } } media_status_t AImageReader::getWindowNativeHandle(native_handle **handle) { if (mWindowHandle != nullptr) { *handle = mWindowHandle; return AMEDIA_OK; } sp<HGraphicBufferProducer> hgbp = new TWGraphicBufferProducer<HGraphicBufferProducer>(mProducer); HalToken halToken; if (!createHalToken(hgbp, &halToken)) { return AMEDIA_ERROR_UNKNOWN; } mWindowHandle = convertHalTokenToNativeHandle(halToken); if (!mWindowHandle) { return AMEDIA_ERROR_UNKNOWN; } *handle = mWindowHandle; return AMEDIA_OK; } int AImageReader::getBufferWidth(BufferItem* buffer) { if (buffer == NULL) return -1; Loading Loading @@ -585,6 +618,58 @@ AImageReader::acquireLatestImage(/*out*/AImage** image, /*out*/int* acquireFence } } static native_handle_t *convertHalTokenToNativeHandle( const HalToken &halToken) { // We attempt to store halToken in the ints of the native_handle_t after its // size. The first int stores the size of the token. We store this in an int // to avoid alignment issues where size_t and int do not have the same // alignment. size_t nhDataByteSize = halToken.size(); if (nhDataByteSize > kWindowHalTokenSizeMax) { // The size of the token isn't reasonable.. return nullptr; } size_t numInts = ceil(nhDataByteSize / sizeof(int)) + 1; // We don't check for overflow, whether numInts can fit in an int, since we // expect kWindowHalTokenSizeMax to be a reasonable limit. // create a native_handle_t with 0 numFds and numInts number of ints. native_handle_t *nh = native_handle_create(0, numInts); if (!nh) { return nullptr; } // Store the size of the token in the first int. nh->data[0] = nhDataByteSize; memcpy(&(nh->data[1]), halToken.data(), nhDataByteSize); return nh; } static sp<HGraphicBufferProducer> convertNativeHandleToHGBP ( const native_handle_t *handle) { // Read the size of the halToken vec<uint8_t> hidl_vec<uint8_t> halToken; halToken.setToExternal( reinterpret_cast<uint8_t *>(const_cast<int *>(&(handle->data[1]))), handle->data[0]); sp<HGraphicBufferProducer> hgbp = HGraphicBufferProducer::castFrom(retrieveHalInterface(halToken)); return hgbp; } EXPORT sp<HGraphicBufferProducer> AImageReader_getHGBPFromHandle( const native_handle_t *handle) { if (handle == nullptr) { return nullptr; } if (handle->numFds != 0 || handle->numInts < ceil(sizeof(size_t) / sizeof(int))) { return nullptr; } return convertNativeHandleToHGBP(handle); } EXPORT media_status_t AImageReader_new( int32_t width, int32_t height, int32_t format, int32_t maxImages, Loading @@ -594,6 +679,19 @@ media_status_t AImageReader_new( width, height, format, AHARDWAREBUFFER_USAGE_CPU_READ_OFTEN, maxImages, reader); } extern "C" { EXPORT media_status_t AImageReader_getWindowNativeHandle( AImageReader *reader, /*out*/native_handle_t **handle) { if (reader == nullptr || handle == nullptr) { return AMEDIA_ERROR_INVALID_PARAMETER; } return reader->getWindowNativeHandle(handle); } } //extern "C" EXPORT media_status_t AImageReader_newWithUsage( int32_t width, int32_t height, int32_t format, uint64_t usage, Loading
media/ndk/NdkImageReaderPriv.h +9 −0 Original line number Diff line number Diff line Loading @@ -69,6 +69,8 @@ struct AImageReader : public RefBase { media_status_t acquireNextImage(/*out*/AImage** image, /*out*/int* fenceFd); media_status_t acquireLatestImage(/*out*/AImage** image, /*out*/int* fenceFd); media_status_t getWindowNativeHandle(/*out*/native_handle_t **handle); ANativeWindow* getWindow() const { return mWindow.get(); }; int32_t getWidth() const { return mWidth; }; int32_t getHeight() const { return mHeight; }; Loading Loading @@ -160,10 +162,17 @@ struct AImageReader : public RefBase { sp<Surface> mSurface; sp<BufferItemConsumer> mBufferItemConsumer; sp<ANativeWindow> mWindow; native_handle_t* mWindowHandle = nullptr; List<AImage*> mAcquiredImages; Mutex mLock; }; // Retrieves HGraphicBufferProducer corresponding to the native_handle_t // provided. This method also deletes the HalToken corresponding to the // native_handle_t. Thus, if it is used twice in succession, the second call // returns nullptr; sp<HGraphicBufferProducer> AImageReader_getHGBPFromHandle(const native_handle_t *handle); #endif // _NDK_IMAGE_READER_PRIV_H
media/ndk/include/media/NdkImageReader.h +20 −0 Original line number Diff line number Diff line Loading @@ -37,6 +37,9 @@ #define _NDK_IMAGE_READER_H #include <sys/cdefs.h> #ifdef __ANDROID_VNDK__ #include <cutils/native_handle.h> #endif #include <android/native_window.h> #include "NdkMediaError.h" Loading Loading @@ -461,6 +464,23 @@ typedef struct AImageReader_BufferRemovedListener { media_status_t AImageReader_setBufferRemovedListener( AImageReader* reader, AImageReader_BufferRemovedListener* listener) __INTRODUCED_IN(26); #ifdef __ANDROID_VNDK__ /* * Get the native_handle_t corresponding to the ANativeWindow owned by the * AImageReader provided. * * @param reader The image reader of interest. * @param handle The output native_handle_t. This native handle is owned by * this image reader. * * @return AMEDIA_OK if the method call succeeds. * AMEDIA_ERROR_INVALID_PARAMETER if reader or handle are NULL. * AMEDIA_ERROR_UNKNOWN if some other error is encountered. */ media_status_t AImageReader_getWindowNativeHandle( AImageReader *reader, /* out */native_handle_t **handle); #endif #endif /* __ANDROID_API__ >= 26 */ __END_DECLS Loading