PDA

View Full Version : FFMpeg and XCode 3.0




RossOliver
Feb 8, 2008, 09:58 AM
Hi,

I want to play around with transcoding, but I can't figure out how to get FFMPeg (or any open source/compile yourself software) into XCode...

Any pointers would be greatly appreciated (I'm not looking to be spoon fed, just pointed in the right direction :))

Thanks for your time,

-Ross



kainjow
Feb 8, 2008, 12:41 PM
What do you mean "into Xcode"? Are you wanting to compile ffmpeg with Xcode? If so, it'd be far easier to compile it via the Terminal. I think once you have the prerequisites, it's just the normal ./configure && make.

RossOliver
Feb 8, 2008, 12:52 PM
I'm fairly sure I could compile it if that's what is required, but this is the area that's a bit gray to me...

Basically, I want to give FFMpeg a nice GUI so my program converts audio/video etc using FFMpeg as a back-end. To do this I thought I would have to include all the source code into XCode as a library which I can then utilize in my application...

My application is written in objective-c, but from what I've read I can use C and objective-c interchangeably so there shouldn't be any compatibility problems...

Hope that makes sense...

-Ross

kainjow
Feb 8, 2008, 12:58 PM
Well you need to become familiar with the licenses before you try using ffmpeg in your product because ffmpeg is built upon several other open sources projects and difference licenses.

Having said that, last time I compiled ffmpeg (~6 months ago) it only compiles as an CLI executable, not as a library. So you'd have to communicate with it as a separate process.

Krevnik
Feb 8, 2008, 03:01 PM
Well you need to become familiar with the licenses before you try using ffmpeg in your product because ffmpeg is built upon several other open sources projects and difference licenses.

Having said that, last time I compiled ffmpeg (~6 months ago) it only compiles as an CLI executable, not as a library. So you'd have to communicate with it as a separate process.

Which is possible... ffmpegX does it. A couple other apps do the same thing, IIRC.

The route I would recommend is building ffmpeg independantly of your app. And look at NSTask for how you can start and monitor a seperate application from a Cocoa app.

EDIT: There is also two parts to ffmpeg, there is libavcodec and libavformat (the libraries), and ffmpeg, which is a bare-bones front-end to those libraries. So if you are willing to accept the GPL terms for linking to libavcodec and libavformat, you /can/ use those directly. It will be more work though.

RossOliver
Feb 8, 2008, 04:52 PM
I understand the license implications and don't plan to sell my application and would happily make it open source...

I would rather include it directly, but if that is going to be a problem I guess I can use it as a separate program... but I imagine that would make getting feedback from FFMpeg as it's encoding/decoding much harder, although NSTask seems to be a reasonable fix for this...

Can you send me in the right direction for including libavcodec and libavformat directly?

Thanks for your help,

-Ross

Krevnik
Feb 8, 2008, 06:29 PM
I would rather include it directly, but if that is going to be a problem I guess I can use it as a separate program... but I imagine that would make getting feedback from FFMpeg as it's encoding/decoding much harder, although NSTask seems to be a reasonable fix for this...

It isn't easy, but usually when you spawn a process like that, you can attach to its stdout and watch the text stream. It takes a little bit of trial and error, but you can eventually strip out all the status information you want from it.


Can you send me in the right direction for including libavcodec and libavformat directly?


The two libraries are in the ffmpeg source tree (either gotten from SVN/CVS or downloaded), and are built when you build ffmpeg. As long as you build against the static libraries (libavcodec.a and libavformat.a), you should be able to just copy over the needed headers and the static lib into your project and use them. If you want to build a framework and include them that way, it might take a bit more work, but it is possible. You might need to write a script that generates the framework bundle from the built products yourself.

Unfortunately, I haven't touched the ffmpeg code in a long time (I think my patch went in back in 2004?), and I currently cannot poke around any GPL code right now under an agreement, so unfortunately, the best I can do is all theoretical knowledge based on my previous experience.

RossOliver
Feb 9, 2008, 09:08 AM
The two libraries are in the ffmpeg source tree (either gotten from SVN/CVS or downloaded), and are built when you build ffmpeg. As long as you build against the static libraries (libavcodec.a and libavformat.a), you should be able to just copy over the needed headers and the static lib into your project and use them. If you want to build a framework and include them that way, it might take a bit more work, but it is possible. You might need to write a script that generates the framework bundle from the built products yourself.


OK, I have compiled FFMpeg and installed it. I can now get at the libavcodec.a/libavcodec.dylib and libavformat.a/libavformat.dylib files in usr/local/lib.

I have added the two dynamic lib files to the "Other linker flags" in XCode and they seem to link correctly, although I do get the warnings:


ld: warning in /Developer/SDKs/MacOSX10.5.sdk/usr/local/lib/libavcodec.dylib, file is not of required architecture
ld: warning in /Developer/SDKs/MacOSX10.5.sdk/usr/local/lib/libavformat.dylib, file is not of required architecture


From what I have read, this appears because I'm using Leopard...

Now the only thing I need to find out is how I actually include these libraries in my code... I'm following the tutorial for FFMpeg but fall at the first hurdle:


#include <avcodec.h>
#include <avformat.h>


Do I still need to add all the header files physically to my project? As in Add > Existing files > *.h into their own group?

Thanks again,

-Ross

[edit]

Never mind, after a bit more reading I found out the header files you mentioned simply had to be copied from /usr/local/include/ffmpeg into my project. I think I'm back on the right track again now...

Krevnik
Feb 9, 2008, 11:42 AM
I have added the two dynamic lib files to the "Other linker flags" in XCode and they seem to link correctly, although I do get the warnings:


ld: warning in /Developer/SDKs/MacOSX10.5.sdk/usr/local/lib/libavcodec.dylib, file is not of required architecture
ld: warning in /Developer/SDKs/MacOSX10.5.sdk/usr/local/lib/libavformat.dylib, file is not of required architecture


From what I have read, this appears because I'm using Leopard...

Actually, it isn't. :)

When you built ffmpeg from the command-line, you built one architecture... the one your computer is (Intel or PPC). When you go to build your app in XCode, it is trying to build both Intel /and/ PPC. This will cause one of your two architectures to not build.

Now, my suggestion is that to prevent you from having to install the dylibs on machines that don't have them, is to link against the .a (static lib), or make frameworks from the dylibs. This way you can either include the framework in your app bundle, or at least not have to ship the library at all.

Having a framework also makes it slightly easier to include/reference the headers.

RossOliver
Feb 9, 2008, 01:36 PM
Now, my suggestion is that to prevent you from having to install the dylibs on machines that don't have them, is to link against the .a (static lib), or make frameworks from the dylibs. This way you can either include the framework in your app bundle, or at least not have to ship the library at all.

Having a framework also makes it slightly easier to include/reference the headers.

Ah right I see. So to link against the static libs do I just need to drop the .a files into Frameworks > Linked Frameworks?

I've been trying to get something to happen with the libs I built just for my intel machine (I'll worry about PPC at a later date). Including the headers seems to work fine, but when I try the first call:


#import <Cocoa/Cocoa.h>

#include <avcodec.h>
#include <avformat.h>

int main(int argc, char *argv[])
{
av_register_all();
return NSApplicationMain(argc, (const char **) argv);
}


I get the error messages:


"_av_register_all", referenced from:
_main in main.o
ld: symbol(s) not found
collect2: ld returned 1 exit status


That's with the current set up I have of headers under a classes group 'FFMpeg' and the two static libraries libavcodec.a and libavformat.a (I also read I might need libavutil and libz?) in Frameworks > Linked Frameworks (where I presume it will automatically link all frameworks)...

-Ross

Krevnik
Feb 9, 2008, 02:44 PM
That's with the current set up I have of headers under a classes group 'FFMpeg' and the two static libraries libavcodec.a and libavformat.a (I also read I might need libavutil and libz?) in Frameworks > Linked Frameworks (where I presume it will automatically link all frameworks)...

-Ross

You will want libavutil as well (I don't remember it being a library when I last looked, but you will probably want it).

Just because you add it to your project doesn't mean it will be linked in. You will want to look at your project's target, and look at the linker step. You can drag the .a files from your "Linked Frameworks" group into the linker step and it should then link.

RossOliver
Feb 10, 2008, 08:29 AM
I've started a new project, copied in the libavcodec.a libavformat.a and libavutil.a static libraries from /usr/local/lib to My Project > Frameworks > Linked Frameworks so they are now along side Cocoa.framework.

I checked My Project > Targets > My Project > Link Binary With Libraries and it contains all the static libraries I put in Linked Frameworks, along side the Cocoa.framework.

Next I copied in all the headers from /usr/local/include/ffmpeg to a new group I made under My Project > Classes.

The libraries seem to be linking (still giving me the warning about required architecture but I'm ignoring it for now), but it's still throwing me the error:


"_av_register_all", referenced from:
_main in main.o
ld: symbol(s) not found
collect2: ld returned 1 exit status


for the tiny bit of code I've tried that uses ffmpeg:


#import <Cocoa/Cocoa.h>
#include <avcodec.h>
#include <avformat.h>

int main(int argc, char *argv[])
{
av_register_all();
return NSApplicationMain(argc, (const char **) argv);
}


I feel like I'm at the last hurdle I need to struggle through, if you have any ideas I would greatly appreciate it :)

-Ross

[edit]

After playing around with the XCode settings, I noticed if I set the Active Build Configuration to Debug rather than Release, it compiles perfectly... setting it back to Release throws the error again ...

Krevnik
Feb 10, 2008, 11:32 AM
After playing around with the XCode settings, I noticed if I set the Active Build Configuration to Debug rather than Release, it compiles perfectly... setting it back to Release throws the error again ...

IIRC, Debug doesn't build both platforms. I would really recommend not building two platforms when you only have libraries for one. It will just make your build logs look confusing as you have seen.

RossOliver
Feb 10, 2008, 03:22 PM
IIRC, Debug doesn't build both platforms. I would really recommend not building two platforms when you only have libraries for one. It will just make your build logs look confusing as you have seen.

Ah, that was causing the errors :o I edited the build properties for I386 architectures only and it seems to be working correctly now...

All I have to do now is figure out how to compile a universal binary of ffmpeg :rolleyes:

Thanks for all your help

Cromulent
Feb 10, 2008, 03:38 PM
Ah, that was causing the errors :o I edited the build properties for I386 architectures only and it seems to be working correctly now...

All I have to do now is figure out how to compile a universal binary of ffmpeg :rolleyes:

Thanks for all your help

The GNU compiler supplied with Xcode is a cross compiler for both Intel and PPC architectures. All you would need to do is cross compiler FFMPEG for PPC in much the same way as you have already done. That does mean you will have two copies of the libraries though.

RossOliver
Feb 10, 2008, 03:55 PM
The GNU compiler supplied with Xcode is a cross compiler for both Intel and PPC architectures. All you would need to do is cross compiler FFMPEG for PPC in much the same way as you have already done. That does mean you will have two copies of the libraries though.

If I can get PPC and Intel copies of the library I believe I can join them to a universal library with lipo.

I can't seem to find information on compiling for PPC on an Intel mac though - is it just a simple case of using a certain switch?

-Ross

Krevnik
Feb 10, 2008, 04:07 PM
If I can get PPC and Intel copies of the library I believe I can join them to a universal library with lipo.

I can't seem to find information on compiling for PPC on an Intel mac though - is it just a simple case of using a certain switch?

-Ross

Yes. You will run ./configure with a specific architecture. I don't remember the specifics off-hand right now.

And you are right that lipo will join the two together into a universal library.

RossOliver
Feb 10, 2008, 04:14 PM
Ah I think I know what you mean. I already tried adding:


CFLAGS="-arch ppc -arch i386" --disable-dependency-tracking


I added the CFLAGS to the FFMPEG build because I read it doesn't support --disable-dependency-tracking, but I also tried building LAME with both the CFLAGS and --disable-dependency-tracking to no avail... lipo informed me the dylibs were still only built for i386 :(

From what I have read I have to compile on a PPC machine and then an Intel machine and join them, which is a pain since I only have access to Intel machines...

Perhaps just the -arch ppc will work by itself without -arch i386 and then allow me to join them...

dizziness
Feb 11, 2008, 08:47 PM
I'd like to build a current SVN binary for an Intel Mac with MMX enabled. The current port on Macports has "--disable-MMX" in its flags.

Is there a tutorial out there for someone who has no knowledge of building binaries? I'm not sure about how to compile with static libraries.

(I'm compiling for pyTivo, a streamer using Python to Tivos.)

I wouldn't mind just a link to a compiled binary that works out of the box. But a tutorial would allow me to stay bleeding edge.

kainjow
Feb 11, 2008, 09:01 PM
Last time I built ffmpeg I couldn't get it to compile as a UB on my Intel Mac. I had to use my PPC and join them manually.

Maury
Mar 26, 2008, 12:06 PM
Basically, I want to give FFMpeg a nice GUI so my program converts audio/video etc using FFMpeg as a back-end.

I'm interested in something similar, but without much transcoding. I find that many MKV files have playable H.264 inside, but as they are encoded in MKV I can't play them on my ATV. I would like to use ffmepg's container library to open and examine the files (no matter what they are) and report whether or not they could be played. If they can, I'll use the QuickTime libraries to save out a MOV.

I also managed to build ffmpeg on the command line, but this, IMHO, is sub-optimal. It would be nicer to have each library as a project, so a build of the Cocoa front-end would also bring the libs up-to-date (if needed). A fried passed along this:

http://developer.apple.com/opensource/buildingopensourceuniversal.html

Which does not work out of the box, but can be made to work with a little tweaking. You also have to run ./configure on the command line before it works right.

So have you made any progress on your project yet?

Maury

sp1k
May 11, 2008, 03:38 AM
I've started a new project, copied in the libavcodec.a libavformat.a and libavutil.a static libraries from /usr/local/lib to My Project > Frameworks > Linked Frameworks so they are now along side Cocoa.framework.

I checked My Project > Targets > My Project > Link Binary With Libraries and it contains all the static libraries I put in Linked Frameworks, along side the Cocoa.framework.

Next I copied in all the headers from /usr/local/include/ffmpeg to a new group I made under My Project > Classes.

The libraries seem to be linking (still giving me the warning about required architecture but I'm ignoring it for now), but it's still throwing me the error:


"_av_register_all", referenced from:
_main in main.o
ld: symbol(s) not found
collect2: ld returned 1 exit status


for the tiny bit of code I've tried that uses ffmpeg:


#import <Cocoa/Cocoa.h>
#include <avcodec.h>
#include <avformat.h>

int main(int argc, char *argv[])
{
av_register_all();
return NSApplicationMain(argc, (const char **) argv);
}


I feel like I'm at the last hurdle I need to struggle through, if you have any ideas I would greatly appreciate it :)

-Ross

[edit]

After playing around with the XCode settings, I noticed if I set the Active Build Configuration to Debug rather than Release, it compiles perfectly... setting it back to Release throws the error again ...

I don't know if this is to any help but yesterday I was trying to create a project with libavcodec/libavformat and I got the same error message as you. The problem I had was that my code was compiled as c++ and after some investigation I found that they have removed all extern "C" {} from their headers to make it pure C. So by placing that around my include part I got the project to compile, maybe that's what you need?

RossOliver
May 11, 2008, 12:03 PM
So have you made any progress on your project yet?


To be honest I just gave up on it - directing my attention to the iPhone SDK now...

-Ross

Cromulent
May 11, 2008, 12:17 PM
Okay quick tutorial.

Add the following lines into .profile in your home directory:

export PATH="$PATH:/usr/local/bin:/opt/local:/opt/local/bin"
export LD_LIBRARY_PATH="$LD_LIBRARY_PATH:/usr/local/lib:/opt/local/lib"
export LIBRARY_PATH="$LIBRARY_PATH:/usr/local/lib:/opt/local/lib"
export C_INCLUDE_PATH="$C_INCLUDE_PATH:/usr/local/include:/opt/local/include"

make sure you installed FFMPEG into /usr/local (it is the default for most software so no need to worry about that). Open Xcode > Project Menu > Edit Active Target. Then in the build tab click on the + icon on the linked libraries list. Add the FFMPEG libraries. Then just make sure you have the correct include for the the header file and away you go.

Edit : you can get rid of the /opt paths above if you do not have Mac Ports installed.