1. Welcome to the new MacRumors forums. See our announcement and read our FAQ

FFMpeg and XCode 3.0

Discussion in 'Mac Programming' started by RossOliver, Feb 8, 2008.

  1. macrumors regular

    #1
    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
     
  2. Moderator emeritus

    kainjow

    #2
    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.
     
  3. macrumors regular

    #3
    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
     
  4. Moderator emeritus

    kainjow

    #4
    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.
     
  5. macrumors 68020

    Krevnik

    #5
    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.
     
  6. macrumors regular

    #6
    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
     
  7. macrumors 68020

    Krevnik

    #7
    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.

    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.
     
  8. macrumors regular

    #8
    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:

    Code:
    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:

    Code:
    #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...
     
  9. macrumors 68020

    Krevnik

    #9
    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.
     
  10. macrumors regular

    #10
    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:

    Code:
    #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:

    Code:
      "_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
     
  11. macrumors 68020

    Krevnik

    #11
    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.
     
  12. macrumors regular

    #12
    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:

    Code:
    "_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:

    Code:
    #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 ...
     
  13. macrumors 68020

    Krevnik

    #13
    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.
     
  14. macrumors regular

    #14
    Ah, that was causing the errors :eek: 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
     
  15. macrumors 603

    Cromulent

    #15
    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.
     
  16. macrumors regular

    #16
    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
     
  17. macrumors 68020

    Krevnik

    #17
    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.
     
  18. macrumors regular

    #18
    Ah I think I know what you mean. I already tried adding:

    Code:
    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...
     
  19. macrumors newbie

    #19
    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.
     
  20. Moderator emeritus

    kainjow

    #20
    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.
     
  21. macrumors 6502

    #21
    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
     
  22. macrumors newbie

    #22
    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?
     
  23. macrumors regular

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

    -Ross
     
  24. macrumors 603

    Cromulent

    #24
    Okay quick tutorial.

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

    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.
     

Share This Page