-
Notifications
You must be signed in to change notification settings - Fork 25
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
New lavc api #23
New lavc api #23
Conversation
Since it's used as AVPacket payload, the API requires it to be padded. Signed-off-by: James Almer <jamrial@gmail.com>
Signed-off-by: James Almer <jamrial@gmail.com>
Is this still relying on libavresample, which was deprecated from ffmpeg? |
@quequotion |
@jamrial I am only thinking that even with not exactly matched input type for the encoder some sound has to be produced... In your new do_encode() before avcodec_send_frame() (jamrial@3aec2b2#diff-96ce76abb22778de0d96ef94d576d3eb582a74c32dfe4f7ad8f560444b04f20eR120)
otherwise I've got EINVAL from that function (using "original" rec->frame). Do you have a clue why is passing a frame which was previously working in avcodec_encode_audio2 has to be allocated again and memcopied before this new API call? ps. I know that above code is ugly and not complete - it is rather a playground to understand some things and at least something is audible from the speakers... |
The reason it fails is probably because the send/receive API attempts to create a new reference to the frame internally, whereas the old API would not and simply pass it as is to the underlying encoder, and creating a new reference requires certain AVFrame fields to be set. In this case, format and channel_layout were missing. Using av_samples_alloc() is fine even for the new API, it will just result in some extra data copy when creating the new reference. I set the two relevant fields in alloc_input_buffer() and pushed the changes. See if that helps. |
Thanks, yeah it helps in this matter that I don't need to set those extra data in do_encode() and my minimal patch to get some distorted AC3 sound shrink to:
Without this - I've got EINVAL from encoding, so it still needs more work... |
Maybe now? |
When trying to play audio through an a52 device using pulseaudio, this happens more times per second than I can count:
speaker-test isn't happy with it either (pulseaudio disabled):
|
Unless avcodec_send_frame() or avcodec_receive_packet() are the ones returning an error code, i can't help you. This PR is only trying to port the plugin to the new encode API to be used with ffmpeg versions 4.4 and newer. Someone familiar with ALSA should adapt this plugin to pass S32 planar audio to the encoder when it expects it, for starters. Otherwise you're not going to get proper AC3 frames out of it. |
@jamrial regarding your last commit with extended_data - no change... @quequotion
|
@manio What function is failing, avcodec_send_frame or avcodec_receive_packet? And what error code does it return? (Not talking about the hardcoded -EINVAL i made do_encode() propagate) |
@jamrial |
ffmpeg 4.4 is the last version with avcodec_encode_audio2(). Starting from the next release the new decoupled input-output API will be the only one available. BugLink: alsa-project#22 Signed-off-by: James Almer <jamrial@gmail.com>
Can you try again with the latest addition? |
@jamrial |
It's no longer available starting with LIBAVCODEC_VERSION_MAJOR == 59. Signed-off-by: James Almer <jamrial@gmail.com>
@perexg |
Do we have another issue/feature request for the plugin to use S32 instead of S16 yet? Edit: Not specific to a52, but this looks like it. We should Thanks for your hard work @jamrial & @manio! Edit: SwiftKey is the most evil creation in the history of keyboards; link fixed. |
The ac3_fixed encoder in ffmpeg 4.4 and newer takes S32 planar audio as input, but this plugin exclusively handles S16 audio, as seen in the line you linked. Line 984 in 2352e4e
If you can't get S32 audio from ALSA to pass to the encoder for versions where it expects it, you could use a resampler like libswresample. |
Just set the format constrains to S32 according the codec->sample_fmts[0] in Line 776 in 2352e4e
plug: automatic ALSA plugin can be used for the internal format conversion.
If the av codec accepts multiple formats, pick the more common S16 by default. |
I'll leave that to you or someone else familiar with ALSA that can also test such changes. This MR is to ensure the plugin can work with the new encode public API, regardless of what the underlying encoder handles. |
If i'm reading this right, it looks like S16 is still being hardcoded in rec->format, in SND_PCM_PLUGIN_DEFINE_FUNC(a52), which is then used in convert_data() and passed to snd_pcm_hw_params_set_format(). |
It's output format (for the packed A52 data), so it should be ok. |
Intel HDMI: PERIOD_SIZE: [32 4272000] PERIOD_BYTES: [128 17088000] PERIODS: [2 32] BUFFER_SIZE: [64 8544000] BUFFER_BYTES: [256 34176000] Selected: PERIOD_SIZE: 768 PERIOD_BYTES: 3072 PERIODS: 32 BUFFER_SIZE: 24576 BUFFER_BYTES: 98304 The a52_hw_params() tries to set the big 4271616 buffer size (frames) for speaker-test which is beyond the maximal slave buffer. BugLink: alsa-project#23 Signed-off-by: Jaroslav Kysela <perex@perex.cz>
The recent a52 encoder in ffmpeg accepts planar S32 (fixed encoder) or planar float (normal encoder) only. Extend the routines to support all combinations of 16-bit, 32-bit and float source samples. BugLink: alsa-project#23 Signed-off-by: Jaroslav Kysela <perex@perex.cz>
Yes, it's bad, but this code is only used for drain (at the end of playback). It's fixed now. Speaker-test fix: perexg@4f5903b I found another missing piece in the code (missing |
Thank you guys! I can see a big progress :) |
Sorry for being very late to the game, as I've been too busy for other tasks. And thanks for Jaroslav for taking care of this! I took a quick glance, checked the code, and it looks mostly good, but there are a few small bugs. |
@tiwai |
Hm, you can try revert one by one to figure out which one broke; they are only 3 small commits. |
Morning!
Now I have sound back - now I am trying only to revert this single commit...
Now the best news ever: the sound is crystal clear!!! :D:D To sum it all: the commit which is wrong is: "a52: Don't swap bytes for the recent libavcodec for LE", after reverting only this one from @tiwai tree I have a correct sound! :) @quequotion where are you man, can you also confirm if everything is working also on your hardware? |
On the clock! I'll try some test builds when I get home tonight (~19:00 JST). Most days I'm working 08:30~23:00, including commutes. Can't believe the progress we've made these last few weeks! After years of struggling to keep surround sound working with hacks, homebrewed packages, and copy pasta configurations, we're a just handful of commits away from ready out-of-the-box functionality. Looking forward to it! |
Good to hear! Now I dropped the wrong patch and re-pushed. |
Since it's used as AVPacket payload, the API requires it to be padded. BugLink: #23 Signed-off-by: James Almer <jamrial@gmail.com> Signed-off-by: Jaroslav Kysela <perex@perex.cz>
BugLink: #23 Signed-off-by: James Almer <jamrial@gmail.com> Signed-off-by: Jaroslav Kysela <perex@perex.cz>
ffmpeg 4.4 is the last version with avcodec_encode_audio2(). Starting from the next release the new decoupled input-output API will be the only one available. BugLink: #23 Signed-off-by: James Almer <jamrial@gmail.com> Signed-off-by: Jaroslav Kysela <perex@perex.cz>
It's no longer available starting with LIBAVCODEC_VERSION_MAJOR == 59. BugLink: #23 Signed-off-by: James Almer <jamrial@gmail.com> Signed-off-by: Jaroslav Kysela <perex@perex.cz>
Intel HDMI: PERIOD_SIZE: [32 4272000] PERIOD_BYTES: [128 17088000] PERIODS: [2 32] BUFFER_SIZE: [64 8544000] BUFFER_BYTES: [256 34176000] Selected: PERIOD_SIZE: 768 PERIOD_BYTES: 3072 PERIODS: 32 BUFFER_SIZE: 24576 BUFFER_BYTES: 98304 The a52_hw_params() tries to set the big 4271616 buffer size (frames) for speaker-test which is beyond the maximal slave buffer. BugLink: #23 Signed-off-by: Jaroslav Kysela <perex@perex.cz>
The recent a52 encoder in ffmpeg accepts planar S32 (fixed encoder) or planar float (normal encoder) only. Extend the routines to support all combinations of 16-bit, 32-bit and float source samples. BugLink: #23 Signed-off-by: Jaroslav Kysela <perex@perex.cz>
Fixed via #26 . If you have a problem, please, open a new ticket. |
Thank you all very much! :) |
If you like, please, retest with the current master branch. I pushed more cleanups there. The functionality should not be changed, but the more testing would be nice. |
Just building those updates now, was about to post that I had a few problems. Not sure if they are problems with this code though: First, I can't get Then, pulseaudio just barely starts (had to comment out a lot of custom configuration) and then crashes the moment something plays audio through the a52 plugin. Edit: Crashing persists even with a completely default pulseaudio configuration. At first I thought this was because it seems to insist on reloading the plugin's sink with a different sample format (it creates the sink with s32le, then reloads with float32le), but even with a client (mpv) configured to use s32le, it still crashes as soon as audio is loaded. Hopefully the cleanups help! I'll be back in a few minutes. Edit: Bad news, pulseaudio still crashes any time audio is played through the plugin. Here's a log, note that it is 1874 lines long and mostly junk. You should probably work your way up from the bottom. |
Don't use .ac3 file for tests. It's already the compressed format (like output from the a52 plugin). You need to convert them back to a PCM format before use (for aplay). |
That makes sense. Still, either file is crashing pulseaudio where both should work there (edit: because the file encoding is irrelevant to pulseaudio, which should be sending the ouput of its client, mpv in this case, to plug:a52). I'll see if I can find a specific commit that might be the cause (although audio quality was terrible, pulseaudio wasn't crashing yesterday). Edit: pulseaudio would last output through the a52 plugin without crashing as of c12a6ae |
@perexg @quequotion |
My meaning was that the next commit, f11e7a8, which changes the plugin to use s32le, is where it breaks down. I did try to revert just that commit to test the later ones, but git wanted to do a manual merge and I decided to go to bed instead. Might have time for it tonight. This troubles me because it seems like it's woking for ALSA, but pulseaudio has a problem with it. I don't think pulseaudio has any code specific to this plugin, so I wouldn't expect its developers to take on working around changes to it. On the other hand, it seems to be working well enough for ALSA-only setups, so it might seem like this is an issues that can be passed to the pulseaudio team to deal with. I think the problem results from the recent commits and needs to be fixed in alsa-plugins, but maybe I should open a new issue for this. |
This is untested (I don't have access to a system with alsa, but the change was straightforward enough that i could write it).
It is unlikely that it will fix the silence issue described in #22, but it nonetheless is a change required in order to support future versions of ffmpeg.
The silence is, as far as i could tell, related to the fact that starting with ffmpeg 4.4, the ac3_fixed encoder takes S32 planar as input, versus the S16 planar it used to. This plugin should look at the AVCodec sample_fmts[0] value and feed the encoder the appropriate data.