-
Notifications
You must be signed in to change notification settings - Fork 2.9k
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
The format:stereo-in
filter doesn't work when encoding videos
#15225
Comments
I really need mpv's fantastic subtitle renderer when doing these re-encodes. The way mpv lets me style the subtitles is fantastic. Just need to solve this 3D issue... I had a theory that the built-in Lines 32 to 41 in b402418
But even after copying that profile to my own Well, the core issue is that the 3D rendering of subtitles fails in encoding mode, and it seems like that will require some actual code changes... |
I have been researching more and have the following information which may be helpful:
So, since I think mpv uses libass for rendering, the process is similar in mpv's code. But since mpv already has an implementation of 3D SBS/OU subtitle rendering in "pseudo-gui/OSC" mode, I hope all the code already exists in mpv to make this 3D rendering change for the encoder filter pipeline too. |
I just began deeper investigations of the source code to see how to implement this. The 3D subtitle rendering is handled as follows:
Now... here's what that means for encoding:
Does anyone have any insights or advice that could help figure out the rest of this journey? Perhaps even some ideas for using the OSD "double rendering" technique in encode mode? Maybe we can render the subtitles as a layer and duplicate it directly? Ultimately, I'm trying to have fun with my brother and watch 3D movies with great subtitles and direct re-encoding from mpv to the streaming server (which is a project that I'll release as a GitHub repo when it's complete), which unfortunately isn't possible currently with mpv... |
I just had an idea if we can make a filter graph. This rendering would even be better than mpv's official GUI/OSD-based rendering:
This would actually implement proper ANAMORPHIC subtitle stretching, which mpv doesn't currently do. (So when the 3D is unstretched, mpv's current GUI-based 3D Subtitles are being stretched and elongated.) Although I'd have to be careful with the difference between anamorphic 3D: half-OU/half-SBS, and non-anamorphic 3D: full-OU/full-SBS. Squashing should only be done when the input is half-resolution (anamorphic). And mpv's stereo3d flags currently make no distinction between those. So I'd need to add an extra Anyway... lavfi filtering like this, if possible, would be the best way to implement subtitles for both above-below and side-by-side modes. It means the subtitle renderer only has to do its job once, and then we do a cheap copy, optional squash, and overlay. If we're able to make filter graphs for the subtitle renderer in the lavc output, I could prototype it via pure ffmpeg tomorrow and design a graph that does such rendering for all combos: OU, SBS, and anamorphic variants of each. |
Oh this reminds me... gpu (and gpu-next) work with libass directly and render to a separate layer that's unconstrained by the video resolution. This is for rendering sharp text on top of the GUI window regardless of video resolution. It's a good solution for GUIs but not for video encoding filter graphs. So the "3D subtitles" code in the OSD is probably totally useless for video encoding. We'll need a filter graph instead, if that's possible. Does anyone know where video/out/vo_lavc.c currently does the subtitle rendering? I haven't seen it yet and need to go to bed now. Edit: Oh... #include "sub/osd.h"
static void draw_frame(struct vo *vo, struct vo_frame *voframe)
{
struct priv *vc = vo->priv;
struct encoder_context *enc = vc->enc;
struct encode_lavc_context *ectx = enc->encode_lavc_ctx;
AVCodecContext *avc = enc->encoder;
if (voframe->redraw || voframe->repeat || voframe->num_frames < 1)
return;
struct mp_image *mpi = voframe->frames[0];
struct mp_osd_res dim = osd_res_from_image_params(vo->params);
osd_draw_on_image(vo->osd, dim, mpi->pts, OSD_DRAW_SUB_ONLY, mpi); (The first and last lines are most relevant here.) I'll have to investigate tomorrow to see whether those calls can be adapted to draw twice. I guess it's drawing directly on top of the video frame via libass then, before it's being sent to the lavc encoder! But I haven't checked in depth yet. It might be possible to implement both the 3D subtitle rendering and anamorphic squashing (by rendering to a separate, squashed layer before compositing it), but I'll focus on just getting 3D rendering working in the encoder at first. The hackiest part will be figuring out how to adapt So I'll need to add some flag to the "osd subtitle renderer" to say "render the subtitles in 3D mode if Edit: Yeah... I think it would be clean to do Hopefully there's a way to give the subtitle renderer the "usable region (x/y/width/height)" so I can tell it to only render in half of the frame, and then I can manually copy those pixels to the 2nd half. But since it seems to draw directly on the video frame, I would need to first draw to a temporary buffer and then composite the buffer twice onto the frame. Alternatively, I could call libass rendering twice, but that's wasteful. I am guessing that the current GUI 3D subtitle code doesn't render twice? Or does it? If it does, then I guess the performance of doing that is fine. Most likely, my first implementation will call the subtitle rendering twice. Just to get things rolling. Then we can look at using a draw buffer for the copy instead, but I would need guidance for such an advanced task in this unfamiliar codebase. |
mpv Information
Important Information
Reproduction Steps
First play the video normally. You will see correctly rendered subtitles (they will be duplicated at the top and bottom halves of the video):
Now use mpv as an encoder. The filter now fails and the subtitles only render once (at the bottom of the screen).
To see the streaming video of the second example, open a second terminal and run
mpv /tmp/mpv-enc
after having started the "stream" above.Expected Behavior
Since I am re-encoding 3D videos and burning-in the subtitles, I need the subtitles to appear in 3D format, which is the purpose of that filter. But it's not working in encoding mode. :(
Actual Behavior
The filter is ignored. I see from the log that the filter/its metadata is being inserted, but the correct subtitle rendering code isn't being activated in mpv's encoding mode.
Log File
output2.txt
Sample Files
No response
I carefully read all instruction and confirm that I did the following:
--log-file=output.txt
.The text was updated successfully, but these errors were encountered: