Closed c1400700226 closed 8 months ago
I think it's a correct behavior
I think it's a correct behavior
I do not think so. This issue seems to be a duplicate of #18023 and can be fixed after reverting this 097206d50d34ab7fc0eb4c0ff20ae80ee73fd901 commit @truboxl
I got the hint from this thread https://android.stackexchange.com/questions/253750/hardware-accelerated-ffmpeg-using-mediacodec-on-android
I got the hint from this thread https://android.stackexchange.com/questions/253750/hardware-accelerated-ffmpeg-using-mediacodec-on-android
Ok now got it, but ffmpeg in termux not hardware accelerated though particularly arm32.
Mediacodec actually works in Termux. Nothing is broken.
In my case I had only to disable audio stream (-an
option) because it triggered an error in aac encoder (unsupported channel layouts). But video recoding works perfectly using mediacodec.
In your case the issue may be a video with properties not supported by mediacodec natively. You may need to specify additional options. Otherwise indeed switch to libx264.
Another attempt, 8k h264 + aac. Using default ffmpeg configuration. Zero issues.
P.S. In case with 8k, the mediacodec is a must have feature for ffmpeg. I would be against reverting commit as suggested before. Because with libx264 it takes much more time and overloads the device.
Another attempt, 8k h264 + aac. Using default ffmpeg configuration. Zero issues.
P.S. In case with 8k, the mediacodec is a must have feature for ffmpeg. I would be against reverting commit as suggested before. Because with libx264 it takes much more time and overloads the device.
Weird, I did reinstall termux, problem still
Problem can happen due to unsupported properties of your original video file or some incompatibility between ffmpeg and mediacodec implementation on your device.
I will try it on other my devices, maybe one of them will show behavior similar to yours.
Edit: still can't reproduce the issue on all of my devices (all AArch64, Android OS 8/14). Tried h264 video from various sources (camera, YouTube).
Weird, I did reinstall termux, problem still
You are not helping if you are not posting the full termux info
I have attached two text file with the output of termux-info and ffmpeg error message.
Problem can happen due to unsupported properties of your original video file or some incompatibility between ffmpeg and mediacodec implementation on your device.
I will try it on other my devices, maybe one of them will show behavior similar to yours.
Edit: still can't reproduce the issue on all of my devices (all AArch64, Android OS 8/14). Tried h264 video from various sources (camera, YouTube).
It happens with any video. And I have tried static compiled ffmpeg, no such problem.
I have attached two text file with the output of termux-info and ffmpeg error message.
Exactly the same situation here
Weird, I did reinstall termux, problem still
You are not helping if you are not posting the full termux info
Sorry, I have updated the post
Referring https://github.com/termux/termux-packages/issues/18023#issuecomment-1897987187
Does adding -pix_fmt nv12
helped?
I have ran the following command. It shows some warnings/errors in the output but the ffmpeg process continues without exiting.
ffmpeg -hwaccel mediacodec -i test.mp4 -c:a copy -c:v h264_mediacodec -b:v 2M -pix_fmt nv12 output.mp4
I have attached the output in a text file here. ffmpeg-output-pix-fmt-nv12.txt
Referring #18023 (comment)
Does adding
-pix_fmt nv12
helped?
Yes, it works with this parameter. Or just add "-c:v libx264". But both shouldn't be necessary.
-c:v libx264
is using CPU which will be super slow.
The bug is ffmpeg mediacodec limited detection mechanism as noted by the ffmpeg developer who provided the workaround. If by reverting means turn off mediacodec support, you will be left with CPU encoding. I rather fix the bug than to turn off support. I will see how to switch to NV12 by default/fallback if that is possible.
Is there any way to detect if the underlying hardware is capable of the ffmpeg mediacodec, like lscpu, vulkaninfo tools?
Also, is the issue related to any software like binary blobs? I am running LineageOS 21.
Mediacodec via NDK is still new for ffmpeg. So I expect @quink-black to answer questions and not some random stackexchange or reddit user.
Referring #18023 (comment) Does adding
-pix_fmt nv12
helped?Yes, it works with this parameter. Or just add "-c:v libx264". But both shouldn't be necessary.
It's very important to specify the encoder. Hardware encoder can be significant faster than software encoder, and use less CPU/battery. Software encoder on mobile devices should only be applied on low resolution cases.
Whether -pix_fmt nv12 is needed depends on the device. It's well known some Qualcomm chips don't support yuv420p as encoder input format, but other deivces have no such problem. What's the real problem is that, Android NDK don't provide API to query what format is supported. There is an ugly Java API, it's not useful here since we have no access to JVM.
So, due to the missing API and it's device dependent, I don't have a idea to solve it automatically. There is an easy method: always use -pix_fmt nv12 since it should work on almost all devices.
I will add a hint message to FFmpeg.
diff --git a/libavcodec/mediacodecenc.c b/libavcodec/mediacodecenc.c
index 086b545590..984014f1b1 100644
--- a/libavcodec/mediacodecenc.c
+++ b/libavcodec/mediacodecenc.c
@@ -319,6 +319,9 @@ static av_cold int mediacodec_init(AVCodecContext *avctx)
ret = ff_AMediaCodec_configure(s->codec, format, s->window, NULL, ret);
if (ret) {
av_log(avctx, AV_LOG_ERROR, "MediaCodec configure failed, %s\n", av_err2str(ret));
+ if (avctx->pix_fmt == AV_PIX_FMT_YUV420P)
+ av_log(avctx, AV_LOG_ERROR, "Please try -pix_fmt nv12, some devices don't "
+ "support yuv420p as encoder input format.\n");
goto bailout;
}
Referring #18023 (comment) Does adding
-pix_fmt nv12
helped?Yes, it works with this parameter. Or just add "-c:v libx264". But both shouldn't be necessary.
- It's very important to specify the encoder. Hardware encoder can be significant faster than software encoder, and use less CPU/battery. Software encoder on mobile devices should only be applied on low resolution cases.
- Whether -pix_fmt nv12 is needed depends on the device. It's well known some Qualcomm chips don't support yuv420p as encoder input format, but other deivces have no such problem. What's the real problem is that, Android NDK don't provide API to query what format is supported. There is an ugly Java API, it's not useful here since we have no access to JVM.
So, due to the missing API and it's device dependent, I don't have a idea to solve it automatically. There is an easy method: always use -pix_fmt nv12 since it should work on almost all devices.
I will add a hint message to FFmpeg.
diff --git a/libavcodec/mediacodecenc.c b/libavcodec/mediacodecenc.c index 086b545590..984014f1b1 100644 --- a/libavcodec/mediacodecenc.c +++ b/libavcodec/mediacodecenc.c @@ -319,6 +319,9 @@ static av_cold int mediacodec_init(AVCodecContext *avctx) ret = ff_AMediaCodec_configure(s->codec, format, s->window, NULL, ret); if (ret) { av_log(avctx, AV_LOG_ERROR, "MediaCodec configure failed, %s\n", av_err2str(ret)); + if (avctx->pix_fmt == AV_PIX_FMT_YUV420P) + av_log(avctx, AV_LOG_ERROR, "Please try -pix_fmt nv12, some devices don't " + "support yuv420p as encoder input format.\n"); goto bailout; }
Thanks for the info, but I think for compatibility reason software encoding should always be used by default, just like on other platforms.
Referring #18023 (comment) Does adding
-pix_fmt nv12
helped?Yes, it works with this parameter. Or just add "-c:v libx264". But both shouldn't be necessary.
- It's very important to specify the encoder. Hardware encoder can be significant faster than software encoder, and use less CPU/battery. Software encoder on mobile devices should only be applied on low resolution cases.
- Whether -pix_fmt nv12 is needed depends on the device. It's well known some Qualcomm chips don't support yuv420p as encoder input format, but other deivces have no such problem. What's the real problem is that, Android NDK don't provide API to query what format is supported. There is an ugly Java API, it's not useful here since we have no access to JVM.
So, due to the missing API and it's device dependent, I don't have a idea to solve it automatically. There is an easy method: always use -pix_fmt nv12 since it should work on almost all devices. I will add a hint message to FFmpeg.
diff --git a/libavcodec/mediacodecenc.c b/libavcodec/mediacodecenc.c index 086b545590..984014f1b1 100644 --- a/libavcodec/mediacodecenc.c +++ b/libavcodec/mediacodecenc.c @@ -319,6 +319,9 @@ static av_cold int mediacodec_init(AVCodecContext *avctx) ret = ff_AMediaCodec_configure(s->codec, format, s->window, NULL, ret); if (ret) { av_log(avctx, AV_LOG_ERROR, "MediaCodec configure failed, %s\n", av_err2str(ret)); + if (avctx->pix_fmt == AV_PIX_FMT_YUV420P) + av_log(avctx, AV_LOG_ERROR, "Please try -pix_fmt nv12, some devices don't " + "support yuv420p as encoder input format.\n"); goto bailout; }
Thanks for the info, but I think for compatibility reason software encoding should always be used by default, just like on other platforms.
FFmpeg doesn't sort encoders that way.
Can help test https://github.com/termux/termux-packages/pull/19408 if it does changed to use libx264 by default?
I have tested the CI artifact and it does change to libx264 by default now.
Problem description
ffmpeg failure without specifying the video codec
[amediacodec_ndk @ 0xb400007342d7d540] Encoder configure failed, -10000 [h264_mediacodec @ 0xb400007342d8a800] MediaCodec configure failed, Generic error in an external library [vost#0:0/h264_mediacodec @ 0xb400007342d84780] Error while opening encoder - maybe incorrect parameters such as bit_rate, rate, width or height. Error while filtering: Generic error in an external library [out#0/mp4 @ 0xb400007342d09780] Nothing was written into output file, because at least one of its streams received no packets.
No problem if you specify the video codec for example "-c:v libx264"
What steps will reproduce the bug?
ffmpeg -i test.mp4 output.mp4
What is the expected behavior?
No response
System information
termux-info: Version 0.118 Termux Variables: TERMUX_APK_RELEASE=UNKNOWN TERMUX_APP_PACKAGE_MANAGER=apt TERMUX_APP_PID=13495 TERMUX_IS_DEBUGGABLE_BUILD=0 TERMUX_MAIN_PACKAGE_FORMAT=debian TERMUX_VERSION=0.118.0 TERMUX__USER_ID=0 Packages CPU architecture: aarch64 Subscribed repositories:
sources.list
deb https://packages-cf.termux.dev/apt/termux-main stable main
root-repo (sources.list.d/root.list)
deb https://packages-cf.termux.dev/apt/termux-root/ root stable Updatable packages: command-not-found/stable 2.4.0-14 aarch64 [upgradable from: 2.4.0-13] debianutils/stable 5.17 aarch64 [upgradable from: 5.16] libxcb/stable 1.16.1 aarch64 [upgradable from: 1.16] termux-tools/stable 1.40.7 all [upgradable from: 1.40.6] termux-tools version: 1.40.6 Android version: 11 Kernel build information: Linux localhost 4.19.113-perf-g2dec83098f88 #1 SMP PREEMPT Fri Dec 17 11:18:47 CST 2021 aarch64 Android Device manufacturer: Xiaomi Device model: M2012K11AC LD Variables: LD_LIBRARY_PATH= LD_PRELOAD=/data/data/com.termux/files/usr/lib/libtermux-exec.so