Skip to content
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

Cocoa restructuring work for libmpv #721

Closed
wants to merge 9 commits into from
Closed

Cocoa restructuring work for libmpv #721

wants to merge 9 commits into from

Conversation

frau
Copy link
Contributor

@frau frau commented Apr 16, 2014

Here's some preliminary work for your consideration. It's not ready to merge, just a progress report.

With these changes, I can link and run a super simple client test that plays video (in a window created by mpv though, not the client's window) and the audio.

Now the question I have is how to rework cocoa_common to accommodate libmpv... cocoa_common is full of standalone-specific stuff, like most of struct vo_cocoa_state, that libmpv isn't going to want. I want to be able to access the IOSurface that gl_cocoa generates. Not sure what a good way forward is from here. Have to pass the GL texture through the client API somehow.

This is part of #556.

@pigoz
Copy link
Member

pigoz commented Apr 16, 2014

Hello I still have to review your code. For embedding, even if we are in the same process, maybe creating a custom vo_opengl backend that renders to IOSurface could be the way that gives most freedom to someone embedding mpv? I think we should also provide a way to simply embed the mpv openglview in another view or window (similar to --wid on other platforms).

How would you want to structure the video rendering in the client application?

@frau
Copy link
Contributor Author

frau commented Apr 16, 2014

Yep, please do review it! That's why it's here.

I want to go the IOSurface route, yeah. Should the IOSurface pointer be passed through the client API?

Video rendering happens on a textured quad in an OpenGL buffer.

@ghost
Copy link

ghost commented Apr 16, 2014

I want to go the IOSurface route, yeah. Should the IOSurface pointer be passed through the client API?

Yes, somehow it needs to be passed through. I see some possibilities:

  1. Pass the IOSurface pointer as integer with --wid.
  2. Pass a pointer to a struct that provides an "interface" for video display via --wid - the struct would contain an IOSurface pointer, and possibly some more callbacks, whatever is needed.
  3. Add a dedicated sub-API to the client API that handles these things.

All of these are fine for now.

By the way, maybe we need a ringbuffer of IOSurfaces, instead of a single one. Not sure yet. Also, I think it would be nice if we could add support for DisplayLink at one point for presentation - I'm not sure how this would affect the client API. I'm still thinking that we should maybe export some sort of cocoa widget, but I don't know enough about cocoa to know how reasonable this is.

@frau
Copy link
Contributor Author

frau commented Apr 16, 2014

DisplayLink is an interesting tangent. I'm guessing the display link needs to be bound to the client's GL context with CVDisplayLinkSetCurrentCGDisplayFromOpenGLContext so that it synchronizes with the client's window's screen refresh... I think for my use-case at least, libmpv is independent of DisplayLink, as I want to render my client's GL scene way more frequently than the 24fps or so that video frames arrive.

Where does the --wid code live? Also, 2) or 3) make sense, because I think there's some extra data like pixel formats we'll want to be passing too. Passing an IOSurface around as a number scares me a little since it's refcounted, but careful policy could deal with that I suppose.

@ghost
Copy link

ghost commented Apr 16, 2014

Where does the --wid code live?

Nowhere. It's just an int64 option that sets vo->opts->WinID (MPOpts.vo.WinID). That was good enough for X11 and win32, where window handles are globally valid numbers.

@frau
Copy link
Contributor Author

frau commented Apr 16, 2014

@pigoz A custom vo_opengl backend sounds good. Or can corevideo+vdpau work, since that produces the IOSurface? I don't know which is easier to integrate and maintain.

@ghost
Copy link

ghost commented Apr 16, 2014

corevideo+vdpau

What does vdpau do here?

@frau
Copy link
Contributor Author

frau commented Apr 17, 2014

Whoops, I meant vda-hwaccel. I'm confusing all these formats.

@pigoz
Copy link
Member

pigoz commented Apr 17, 2014

vo_corevideo is useless. It will be removed the next time it is problematic :)

@frau
Copy link
Contributor Author

frau commented Apr 17, 2014

Ah, good to know!

On 16 Apr 2014, at 22:22, Stefano Pigozzi notifications@github.com wrote:

vo_corevideo is useless. It will be removed the next time it is problematic :)


Reply to this email directly or view it on GitHub.

@ghost
Copy link

ghost commented Apr 21, 2014

Any news?

@frau
Copy link
Contributor Author

frau commented Apr 23, 2014

Well, the GL integration is going to take a lot of figuring out and time... the code in this PR could use a review in the meantime though!

@ghost
Copy link

ghost commented Apr 26, 2014

This is the target to generate libmpv: https://github.com/frau/mpv/blob/0e0f59cd5af45d34296fcec4762da81e8639740b/wscript_build.py#L445

As you can see, it doesn't add main_fn.c to the sources. What problem are you running into exactly? (Sorry, lost track of the context.)

@frau
Copy link
Contributor Author

frau commented Apr 27, 2014

@wm4 If I revert commit b6f8017 on my branch, then ./waf configure --enable-libmpv-shared && ./waf build, I see the line [161/640] c: player/main_fn.c -> build/player/main_fn.c.11.o and then I get this link error:

Undefined symbols for architecture x86_64:
  "_cocoa_main", referenced from:
      _main in main_fn.c.11.o
  "_mpv_main", referenced from:
      _main in main_fn.c.11.o
ld: symbol(s) not found for architecture x86_64

Is main_fn getting linked in because both ctx() calls have target="mpv"? I'm not really familiar with waf. What's the proper way to do this?

@ghost
Copy link

ghost commented Apr 27, 2014

Note that the command line mpv is also built in this mode, with a different target (and separate object files etc.!). Maybe that's the cause. The configure stuff in wscript doesn't really separate them. If it's not possible to do so properly, then we'll probably have make building the command line player and libmpv completely separate, i.e. you should add an if that enables either the command line mpv or libmpv, but never both. Sorry for the mess.

@frau
Copy link
Contributor Author

frau commented Apr 27, 2014

Right, uh, isn't that what b6f8017 accomplishes? With --enable-libmpv-shared being the toggle?

@ghost
Copy link

ghost commented Apr 27, 2014

Right, uh, isn't that what b6f8017 accomplishes? With --enable-libmpv-shared being the toggle?

Unfortunately, you're right. (I guess my thought process went full-circle.)

@ghedo
Copy link
Member

ghedo commented Apr 27, 2014

FWIW, making it impossible to build mpv and libmpv at the same time will make the life of Linux packagers who want both (i.e. me) harder. Could it be made os x specific if it really needs to be done?

@pigoz
Copy link
Member

pigoz commented Apr 28, 2014

I don't think them be mutually exclusive to be beneficial to any platform.

@ghedo
Copy link
Member

ghedo commented Apr 28, 2014

If I revert commit b6f8017 on my branch, then ./waf configure --enable-libmpv-shared && ./waf build, I see the line [161/640] c: player/main_fn.c -> build/player/main_fn.c.11.o and then I get this link error:

Undefined symbols for architecture x86_64:
"_cocoa_main", referenced from:
_main in main_fn.c.11.o
"_mpv_main", referenced from:
_main in main_fn.c.11.o
ld: symbol(s) not found for architecture x86_64

Not sure if this was the same problem, but reverting 21287ca too fixed the build for me.

@ghedo
Copy link
Member

ghedo commented Apr 28, 2014

...on Linux that is.

@ghost
Copy link

ghost commented Apr 29, 2014

We probably need something to build the two targets (mpv and libmpv) with different configuration. Could this be fixed with some waf magic? Currently, they produce a different set of object files anyway, so they're already very different. They merely share the configuration (config.h) and the file list.

@pigoz
Copy link
Member

pigoz commented Apr 29, 2014

For targets you mean run configure for libmpv and run configure for mpv itself and build them separately?

@ghost
Copy link

ghost commented Apr 29, 2014

Yes, essentially.

@ghost
Copy link

ghost commented Jun 1, 2014

Ping?

@ChrisK2 ChrisK2 added the osx label Jun 5, 2014
@frau
Copy link
Contributor Author

frau commented Aug 3, 2014

I'm back! 🔉

Rebased the PR onto master, dealt with bitrot, and removed that controversial main_fn.c-omitting commit. As a result, --enable-libmpv-shared is broken. So... I'm now blocked on the waf magic to make this all work. Anyone know how to make it happen?

@ghost
Copy link

ghost commented Aug 3, 2014

Welcome back... I hope pigoz can take a look.

@pigoz
Copy link
Member

pigoz commented Aug 4, 2014

Hello! Welcome back. Take a look at the branch pr/721, it should solve your problems (and can also be used by mpv developers to easily develop against different versions of FFmpeg or other libraries without having to rerun configure and build steps all the time).

Example usage would be:

./waf configure
./waf build
./waf --variant=somevariant --disable-cplayer --enable-libmpv-shared configure
./waf --variant=somevariant build

## -- modify some files

./waf build # -> builds changes to 'default' variant
./waf --variant=somevariant  build # -> builds changes to somevariant

@ghedo
Copy link
Member

ghedo commented Aug 4, 2014

I went another route and instead of hiding mpv_main in #if !HAVE_LIBMPV_SHARED ..., I simply moved it to player/main_fn.c, which is only built for the mpv binary. AFAICT mpv_main is not really part of the libmpv API so there's no need to include it in the library in the first place.

It seems to work fine here (linux), altough maybe a bit ugly (it require the terminal_initialized variable to be made global). Anyway, see https://github.com/ghedo/mpv/commit/20b2d4f7fe3b987a7f6f6861c9e5fb00f6b3e078.

@ghedo
Copy link
Member

ghedo commented Aug 4, 2014

it require the terminal_initialized variable to be made global

"global" as in non-static, it's already a global variable...

@pigoz
Copy link
Member

pigoz commented Aug 4, 2014

@ghedo if you see my branch, I reverted that particular commit which hides mpv_main since it's not needed at all.

@ghedo
Copy link
Member

ghedo commented Aug 4, 2014

Oh, right... I missed it (I only looked at the variants thingy). Still though, mpv_main in the library doesn't make a whole lot of sense, maybe just renaming it to mp_main so that its symbol is not exported would do as well.

@frau
Copy link
Contributor Author

frau commented Aug 5, 2014

@pigoz Awesome! Thanks for the waf work. That is nice. I will try building my sample project against it later today.

frau and others added 4 commits August 4, 2014 22:14
I had to put it after video options because it depends on cocoa;
is there anywhere better to put it rather than making a new group?
This builds but both the libmpv example and the cplayer block infinitely when
building libmpv. That's because we wait inifinitely in `dispatch_sync` as
there's no event loop in the main thread that allows for libdispatch to work..

Whiel we are at it, we should probably investigate how to use mp_dispatch
instead since it is a little lower level and could give us higher control in
building and event loop.
This allows the user to execute multiple configuration and build steps. It
can be used for several scenarios where you need different compiler flags.
@frau
Copy link
Contributor Author

frau commented Aug 5, 2014

So, great! pr/721 works for my sample app. Rebased it into this PR, removing the commit-revert pair, and doing a minor reorg. So, how can we get this merged? Do we need to deal with those Cocoa deadlocks first, or can those be dealt with in other PRs later? Or do we need to write the whole feature end-to-end before merging?

@pigoz
Copy link
Member

pigoz commented Aug 5, 2014

@frau please squash 1e5df72 with e621967.

We can merge immediately, the only issue is that using the default variant from build: expose waf variants to the user will now generate the object files and mpv executable in build/default/ (the naming scheme is build/${variant_name}). The install task is also variant aware so it should not be a problem, but maybe some build scripts or packages have hardcoded the build/ directory for some obscure reason (i.e. manually install some files). @ghedo, @Nikoli, @wm4 opinions?

@pigoz
Copy link
Member

pigoz commented Aug 5, 2014

@frau btw I'd love to see your sample application (does it deadlock)? I am thinking about some major restructuring of the Cocoa parts of mpv and it would be cool to have an idea how are you using it.

@ghedo
Copy link
Member

ghedo commented Aug 5, 2014

The zsh completion script works fine here with the patches applied, and mpv-build uses ./waf install (and the various packages should do that too). Dunno what other things may be affected.

@frau
Copy link
Contributor Author

frau commented Aug 5, 2014

@pigoz Okay, squashed!

The sample project is not really different than the client api example shipped with MPV, and is just for making sure that I can actually link to libmpv and play a video; the basic source is at https://gist.github.com/frau/10841304
(It doesn't deadlock, but it barely does anything)

My OpenGL stuff is nowhere near ready for integrating with mpv, but maybe soon...

@pigoz
Copy link
Member

pigoz commented Aug 5, 2014

I guess I will merge the branch this evening or tomorrow morning unless someone objects ^^

@ghost
Copy link

ghost commented Aug 5, 2014

will now generate the object files and mpv executable in build/default/

That sounds like a very bad idea. The old build system just put the mpv binary into the top-level directory. Everyone could find it. Then waf moved it to build/... That's already slightly harder to find. And now it's build/default/? I don't think a user would even expect it to find it there. What is "default" even? And how often is the binary path going to change? Will it be in build/default/no/look/harder/ next?

Short version: no, I don't like it.

@pigoz
Copy link
Member

pigoz commented Aug 5, 2014

Well it's the name of the default variant. We can use empty string '' so that the object files and executable will be in build/, unless someone specifies a --variant option during configure (in that case it has to go to a subdirectory of build). I just need to look at a bug which prevented to rebuild different variants without reconfiguring them.

Would that be better / acceptable?

@ghost
Copy link

ghost commented Aug 5, 2014

so that the object files and executable will be in build/

Sounds like it'd be the same as before. So, very acceptable.

@frau
Copy link
Contributor Author

frau commented Aug 5, 2014

Hmm... the more I work on integrating with OpenGL, the more it feels like that I'm just going to replace all #if HAVE_COCOA lines with #if HAVE_COCOA_APPLICATION.
Now I'm questioning whether the config introduced in b39a372 even makes sense. Well, it made sense to me three months ago, but I wonder what I was thinking...
Don't mind me. More experimentation needed.

@pigoz
Copy link
Member

pigoz commented Aug 6, 2014

I pushed everything after fixing the issues @wm4 suggested. I'm going to close this PR. Please open a new issue (even just for discussion) for the OpenGL changes!

@pigoz pigoz closed this Aug 6, 2014
@frau
Copy link
Contributor Author

frau commented Aug 6, 2014

🎊 Thanks all!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants