Showing the changes to libavcodec (2 of 2 files). Show all
Unified · Split
| @@ -1762,6 +1762,14 @@ static int mediacodec_jni_signalEndOfInputStream(FFAMediaCodec *ctx) · 1761 unmodified lines | |||
| 1762 | return 0; | 1762 | return 0; |
| 1763 | } | 1763 | } |
| 1764 | 1764 | ||
| 1765 | static int mediacodec_jni_setAsyncNotifyCallback(FFAMediaCodec *codec, | ||
| 1766 | const FFAMediaCodecOnAsyncNotifyCallback *callback, | ||
| 1767 | void *userdata) | ||
| 1768 | { | ||
| 1769 | av_log(codec, AV_LOG_ERROR, "Doesn't support aync mode with JNI, please try ndk_codec=1\n"); | ||
| 1770 | return AVERROR(ENOSYS); | ||
| 1771 | } | ||
| 1772 | |||
| 1765 | static const FFAMediaFormat media_format_jni = { | 1773 | static const FFAMediaFormat media_format_jni = { |
| 1766 | .class = &amediaformat_class, | 1774 | .class = &amediaformat_class, |
| 1767 | 1775 | ||
| @@ -1821,6 +1829,7 @@ static const FFAMediaCodec media_codec_jni = { · 53 unmodified lines | |||
| 1821 | .getConfigureFlagEncode = mediacodec_jni_getConfigureFlagEncode, | 1829 | .getConfigureFlagEncode = mediacodec_jni_getConfigureFlagEncode, |
| 1822 | .cleanOutputBuffers = mediacodec_jni_cleanOutputBuffers, | 1830 | .cleanOutputBuffers = mediacodec_jni_cleanOutputBuffers, |
| 1823 | .signalEndOfInputStream = mediacodec_jni_signalEndOfInputStream, | 1831 | .signalEndOfInputStream = mediacodec_jni_signalEndOfInputStream, |
| 1832 | .setAsyncNotifyCallback = mediacodec_jni_setAsyncNotifyCallback, | ||
| 1824 | }; | 1833 | }; |
| 1825 | 1834 | ||
| 1826 | typedef struct FFAMediaFormatNdk { | 1835 | typedef struct FFAMediaFormatNdk { |
| @@ -1842,6 +1851,9 @@ typedef struct FFAMediaCodecNdk { · 15 unmodified lines | |||
| 1842 | AMediaCodec *impl; | 1851 | AMediaCodec *impl; |
| 1843 | ANativeWindow *window; | 1852 | ANativeWindow *window; |
| 1844 | 1853 | ||
| 1854 | FFAMediaCodecOnAsyncNotifyCallback async_cb; | ||
| 1855 | void *async_userdata; | ||
| 1856 | |||
| 1845 | // Available since API level 28. | 1857 | // Available since API level 28. |
| 1846 | media_status_t (*getName)(AMediaCodec*, char** out_name); | 1858 | media_status_t (*getName)(AMediaCodec*, char** out_name); |
| 1847 | void (*releaseName)(AMediaCodec*, char* name); | 1859 | void (*releaseName)(AMediaCodec*, char* name); |
| @@ -1849,6 +1861,8 @@ typedef struct FFAMediaCodecNdk { · 1 unmodified line | |||
| 1849 | // Available since API level 26. | 1861 | // Available since API level 26. |
| 1850 | media_status_t (*setInputSurface)(AMediaCodec*, ANativeWindow *); | 1862 | media_status_t (*setInputSurface)(AMediaCodec*, ANativeWindow *); |
| 1851 | media_status_t (*signalEndOfInputStream)(AMediaCodec *); | 1863 | media_status_t (*signalEndOfInputStream)(AMediaCodec *); |
| 1864 | media_status_t (*setAsyncNotifyCallback)(AMediaCodec *, | ||
| 1865 | struct AMediaCodecOnAsyncNotifyCallback callback, void *userdata); | ||
| 1852 | } FFAMediaCodecNdk; | 1866 | } FFAMediaCodecNdk; |
| 1853 | 1867 | ||
| 1854 | static const FFAMediaFormat media_format_ndk; | 1868 | static const FFAMediaFormat media_format_ndk; |
| @@ -1866,6 +1880,32 @@ static const AVClass amediacodec_ndk_class = { · 11 unmodified lines | |||
| 1866 | .version = LIBAVUTIL_VERSION_INT, | 1880 | .version = LIBAVUTIL_VERSION_INT, |
| 1867 | }; | 1881 | }; |
| 1868 | 1882 | ||
| 1883 | static int media_status_to_error(media_status_t status) | ||
| 1884 | { | ||
| 1885 | switch (status) { | ||
| 1886 | case AMEDIA_OK: | ||
| 1887 | return 0; | ||
| 1888 | case AMEDIACODEC_ERROR_INSUFFICIENT_RESOURCE: | ||
| 1889 | return AVERROR(ENOMEM); | ||
| 1890 | case AMEDIA_ERROR_MALFORMED: | ||
| 1891 | return AVERROR_INVALIDDATA; | ||
| 1892 | case AMEDIA_ERROR_UNSUPPORTED: | ||
| 1893 | return AVERROR(ENOTSUP); | ||
| 1894 | case AMEDIA_ERROR_INVALID_PARAMETER: | ||
| 1895 | return AVERROR(EINVAL); | ||
| 1896 | case AMEDIA_ERROR_INVALID_OPERATION: | ||
| 1897 | return AVERROR(EOPNOTSUPP); | ||
| 1898 | case AMEDIA_ERROR_END_OF_STREAM: | ||
| 1899 | return AVERROR_EOF; | ||
| 1900 | case AMEDIA_ERROR_IO: | ||
| 1901 | return AVERROR(EIO); | ||
| 1902 | case AMEDIA_ERROR_WOULD_BLOCK: | ||
| 1903 | return AVERROR(EWOULDBLOCK); | ||
| 1904 | default: | ||
| 1905 | return AVERROR_EXTERNAL; | ||
| 1906 | } | ||
| 1907 | } | ||
| 1908 | |||
| 1869 | static FFAMediaFormat *mediaformat_ndk_create(AMediaFormat *impl) | 1909 | static FFAMediaFormat *mediaformat_ndk_create(AMediaFormat *impl) |
| 1870 | { | 1910 | { |
| 1871 | FFAMediaFormatNdk *format = av_mallocz(sizeof(*format)); | 1911 | FFAMediaFormatNdk *format = av_mallocz(sizeof(*format)); |
| @@ -2060,6 +2100,7 @@ static inline FFAMediaCodec *ndk_codec_create(int method, const char *arg) { · 188 unmodified lines | |||
| 2060 | 2100 | ||
| 2061 | GET_SYMBOL(setInputSurface) | 2101 | GET_SYMBOL(setInputSurface) |
| 2062 | GET_SYMBOL(signalEndOfInputStream) | 2102 | GET_SYMBOL(signalEndOfInputStream) |
| 2103 | GET_SYMBOL(setAsyncNotifyCallback) | ||
| 2063 | 2104 | ||
| 2064 | #undef GET_SYMBOL | 2105 | #undef GET_SYMBOL |
| 2065 | 2106 | ||
| @@ -2335,6 +2376,94 @@ static int mediacodec_ndk_signalEndOfInputStream(FFAMediaCodec *ctx) · 269 unmodified lines | |||
| 2335 | return 0; | 2376 | return 0; |
| 2336 | } | 2377 | } |
| 2337 | 2378 | ||
| 2379 | static void mediacodec_ndk_onInputAvailable(AMediaCodec *impl, void *userdata, | ||
| 2380 | int32_t index) | ||
| 2381 | { | ||
| 2382 | FFAMediaCodecNdk *codec = userdata; | ||
| 2383 | codec->async_cb.onAsyncInputAvailable((FFAMediaCodec *) codec, | ||
| 2384 | codec->async_userdata, index); | ||
| 2385 | } | ||
| 2386 | |||
| 2387 | static void mediacodec_ndk_onOutputAvailable(AMediaCodec *impl, | ||
| 2388 | void *userdata, | ||
| 2389 | int32_t index, | ||
| 2390 | AMediaCodecBufferInfo *buffer_info) | ||
| 2391 | { | ||
| 2392 | FFAMediaCodecNdk *codec = userdata; | ||
| 2393 | FFAMediaCodecBufferInfo info = { | ||
| 2394 | .offset = buffer_info->offset, | ||
| 2395 | .size = buffer_info->size, | ||
| 2396 | .presentationTimeUs = buffer_info->presentationTimeUs, | ||
| 2397 | .flags = buffer_info->flags, | ||
| 2398 | }; | ||
| 2399 | |||
| 2400 | codec->async_cb.onAsyncOutputAvailable(&codec->api, codec->async_userdata, | ||
| 2401 | index, &info); | ||
| 2402 | } | ||
| 2403 | |||
| 2404 | static void mediacodec_ndk_onFormatChanged(AMediaCodec *impl, void *userdata, | ||
| 2405 | AMediaFormat *format) | ||
| 2406 | { | ||
| 2407 | FFAMediaCodecNdk *codec = userdata; | ||
| 2408 | FFAMediaFormat *media_format = mediaformat_ndk_create(format); | ||
| 2409 | if (!media_format) | ||
| 2410 | return; | ||
| 2411 | |||
| 2412 | codec->async_cb.onAsyncFormatChanged(&codec->api, codec->async_userdata, | ||
| 2413 | media_format); | ||
| 2414 | ff_AMediaFormat_delete(media_format); | ||
| 2415 | } | ||
| 2416 | |||
| 2417 | static void mediacodec_ndk_onError(AMediaCodec *impl, void *userdata, | ||
| 2418 | media_status_t status, | ||
| 2419 | int32_t actionCode, | ||
| 2420 | const char *detail) | ||
| 2421 | { | ||
| 2422 | FFAMediaCodecNdk *codec = userdata; | ||
| 2423 | int error = media_status_to_error(status); | ||
| 2424 | |||
| 2425 | codec->async_cb.onAsyncError(&codec->api, codec->async_userdata, error, | ||
| 2426 | detail); | ||
| 2427 | } | ||
| 2428 | |||
| 2429 | static int mediacodec_ndk_setAsyncNotifyCallback(FFAMediaCodec *ctx, | ||
| 2430 | const FFAMediaCodecOnAsyncNotifyCallback *callback, | ||
| 2431 | void *userdata) | ||
| 2432 | { | ||
| 2433 | FFAMediaCodecNdk *codec = (FFAMediaCodecNdk *)ctx; | ||
| 2434 | struct AMediaCodecOnAsyncNotifyCallback cb = { | ||
| 2435 | .onAsyncInputAvailable = mediacodec_ndk_onInputAvailable, | ||
| 2436 | .onAsyncOutputAvailable = mediacodec_ndk_onOutputAvailable, | ||
| 2437 | .onAsyncFormatChanged = mediacodec_ndk_onFormatChanged, | ||
| 2438 | .onAsyncError = mediacodec_ndk_onError, | ||
| 2439 | }; | ||
| 2440 | media_status_t status; | ||
| 2441 | |||
| 2442 | if (!codec->setAsyncNotifyCallback) { | ||
| 2443 | av_log(codec, AV_LOG_ERROR, "setAsyncNotifyCallback unavailable\n"); | ||
| 2444 | return AVERROR(ENOSYS); | ||
| 2445 | } | ||
| 2446 | |||
| 2447 | if (!callback || | ||
| 2448 | !callback->onAsyncInputAvailable || | ||
| 2449 | !callback->onAsyncOutputAvailable || | ||
| 2450 | !callback->onAsyncFormatChanged || | ||
| 2451 | !callback->onAsyncError) | ||
| 2452 | return AVERROR(EINVAL); | ||
| 2453 | |||
| 2454 | codec->async_cb = *callback; | ||
| 2455 | codec->async_userdata = userdata; | ||
| 2456 | |||
| 2457 | status = codec->setAsyncNotifyCallback(codec->impl, cb, codec); | ||
| 2458 | if (status != AMEDIA_OK) { | ||
| 2459 | av_log(codec, AV_LOG_ERROR, "setAsyncNotifyCallback failed, %d\n", | ||
| 2460 | status); | ||
| 2461 | return AVERROR_EXTERNAL; | ||
| 2462 | } | ||
| 2463 | |||
| 2464 | return 0; | ||
| 2465 | } | ||
| 2466 | |||
| 2338 | static const FFAMediaFormat media_format_ndk = { | 2467 | static const FFAMediaFormat media_format_ndk = { |
| 2339 | .class = &amediaformat_ndk_class, | 2468 | .class = &amediaformat_ndk_class, |
| 2340 | 2469 | ||
| @@ -2396,6 +2525,7 @@ static const FFAMediaCodec media_codec_ndk = { · 55 unmodified lines | |||
| 2396 | .getConfigureFlagEncode = mediacodec_ndk_getConfigureFlagEncode, | 2525 | .getConfigureFlagEncode = mediacodec_ndk_getConfigureFlagEncode, |
| 2397 | .cleanOutputBuffers = mediacodec_ndk_cleanOutputBuffers, | 2526 | .cleanOutputBuffers = mediacodec_ndk_cleanOutputBuffers, |
| 2398 | .signalEndOfInputStream = mediacodec_ndk_signalEndOfInputStream, | 2527 | .signalEndOfInputStream = mediacodec_ndk_signalEndOfInputStream, |
| 2528 | .setAsyncNotifyCallback = mediacodec_ndk_setAsyncNotifyCallback, | ||
| 2399 | }; | 2529 | }; |
| 2400 | 2530 | ||
| 2401 | FFAMediaFormat *ff_AMediaFormat_new(int ndk) | 2531 | FFAMediaFormat *ff_AMediaFormat_new(int ndk) |
| @@ -178,6 +178,22 @@ struct FFAMediaCodecBufferInfo { · 177 unmodified lines | |||
| 178 | typedef struct FFAMediaCodecBufferInfo FFAMediaCodecBufferInfo; | 178 | typedef struct FFAMediaCodecBufferInfo FFAMediaCodecBufferInfo; |
| 179 | 179 | ||
| 180 | typedef struct FFAMediaCodec FFAMediaCodec; | 180 | typedef struct FFAMediaCodec FFAMediaCodec; |
| 181 | |||
| 182 | typedef struct FFAMediaCodecOnAsyncNotifyCallback { | ||
| 183 | void (*onAsyncInputAvailable)(FFAMediaCodec *codec, void *userdata, | ||
| 184 | int32_t index); | ||
| 185 | |||
| 186 | void (*onAsyncOutputAvailable)(FFAMediaCodec *codec, void *userdata, | ||
| 187 | int32_t index, | ||
| 188 | FFAMediaCodecBufferInfo *buffer_info); | ||
| 189 | |||
| 190 | void (*onAsyncFormatChanged)(FFAMediaCodec *codec, void *userdata, | ||
| 191 | FFAMediaFormat *format); | ||
| 192 | |||
| 193 | void (*onAsyncError)(FFAMediaCodec *codec, void *userdata, int error, | ||
| 194 | const char *detail); | ||
| 195 | } FFAMediaCodecOnAsyncNotifyCallback; | ||
| 196 | |||
| 181 | struct FFAMediaCodec { | 197 | struct FFAMediaCodec { |
| 182 | const AVClass *class; | 198 | const AVClass *class; |
| 183 | 199 | ||
| @@ -219,6 +235,11 @@ struct FFAMediaCodec { · 35 unmodified lines | |||
| 219 | 235 | ||
| 220 | // For encoder with FFANativeWindow as input. | 236 | // For encoder with FFANativeWindow as input. |
| 221 | int (*signalEndOfInputStream)(FFAMediaCodec *); | 237 | int (*signalEndOfInputStream)(FFAMediaCodec *); |
| 238 | |||
| 239 | // Introduced in Android API 28 | ||
| 240 | int (*setAsyncNotifyCallback)(FFAMediaCodec *codec, | ||
| 241 | const FFAMediaCodecOnAsyncNotifyCallback *callback, | ||
| 242 | void *userdata); | ||
| 222 | }; | 243 | }; |
| 223 | 244 | ||
| 224 | static inline char *ff_AMediaCodec_getName(FFAMediaCodec *codec) | 245 | static inline char *ff_AMediaCodec_getName(FFAMediaCodec *codec) |
| @@ -343,6 +364,13 @@ static inline int ff_AMediaCodec_signalEndOfInputStream(FFAMediaCodec *codec) · 118 unmodified lines | |||
| 343 | return codec->signalEndOfInputStream(codec); | 364 | return codec->signalEndOfInputStream(codec); |
| 344 | } | 365 | } |
| 345 | 366 | ||
| 367 | static inline int ff_AMediaCodec_setAsyncNotifyCallback(FFAMediaCodec *codec, | ||
| 368 | const FFAMediaCodecOnAsyncNotifyCallback *callback, | ||
| 369 | void *userdata) | ||
| 370 | { | ||
| 371 | return codec->setAsyncNotifyCallback(codec, callback, userdata); | ||
| 372 | } | ||
| 373 | |||
| 346 | int ff_Build_SDK_INT(AVCodecContext *avctx); | 374 | int ff_Build_SDK_INT(AVCodecContext *avctx); |
| 347 | 375 | ||
| 348 | enum FFAMediaFormatColorRange { | 376 | enum FFAMediaFormatColorRange { |