상세 컨텐츠

본문 제목

FFmpeg for Android 설치 및 컴파일

오픈소스 연구/FFMPEG

by 류종택 2011. 3. 17. 12:48

본문


어제 새벽 작업 이후 내용을 추가합니다!!

컴파일된 libffmpeg.so 파일의 크기를 확인 못했었는데, 1KB로 표시되네요.  그리고, 원글을 제작한 개발자의 블로그에도 사용이 안된다고 나와 있습니다.  static 라이브러리로 사용하라는데, 일단 저는 다른 개발자가 만들어 놓은 libffmpeg.so를 이용해서 테스트 중 입니다.  직접 컴파일하는 것은 일단 다른 것들부터 진행하고 나서 천천히 해보려고 합니다.  

libffmpeg.so를 구할 수 있는 사이트는 아래와 같습니다.  밑에 download라고 되어 있는 링크를 사용하시기 바랍니다.  첨부 파일을 다운 받으셔도 됩니다.

http://odroid.foros-phpbb.com/t338-ffmpeg-compiled-with-android-ndk


libffmpeg.zip


참고로 위의 첨부에서는 img_convert(), sws_scale()의 함수는 포함되지 않은 것 같습니다.  이미지를 RGB로 변환하는 것은 따로 작성하셔야 합니다.

아래는 그동안 제가 고생한 내용을 정리합니다.  혹시나 도움이 되실 분들을 위해서..
  • Cygwin에서 작업하는 것보다는 우분투에서 작업하는 것이 더 쉽더군요. Cygwin에서 작업하다가 몇 일 더 까먹었습니다.
  • 우분투에 Z Lib를 설치하고 나서 재부팅하면 우분투가 부팅이 안되는 에러가 발생하였습니다.
     http://ryulib.tistory.com/119 를 참고하시기 바랍니다.
  • 윈도우 환경에서도 작업하기 위해서 제가 지원받은 PC가 내문서 등이 E: 드라이브로 설정되어 있었습니다.  이렇게 되면 Android 에뮬레이터가 실행되지 않는 에러가 발생합니다.  이클립스 및 안드로이드 SDK 문제인가 하고 계속 재 설치하느라, 몇 일 고생했습니다.  (일본 지진의 영향인지, 구글이 너무 느려서 다운로드 중 파일이 손상된 것인가 의심하느라)
    해당 에러 메시지를 구글에서 검색하시면 몇 가지 해결책이 나옵니다.  
    (저는 윈도우를 다시 설치하는 쪽으로..)  

 -- 아래는 위 링크의 사이트 내용입니다.

Create a new project, make jni folder, then download and extract ffmpeg, rename ffmpeg folder to ffmpeg.

 

Make a new config.sh in ffmpeg, notice a bout PREBUILT path and PLATFORM:

 

#!/bin/bash

PREBUILT=/home/abitno/Android/android-ndk-r4/build/prebuilt/linux-x86/arm-eabi-4.4.0
PLATFORM=/home/abitno/Android/android-ndk-r4/build/platforms/android-8/arch-arm

./configure --target-os=linux \
	--arch=arm \
	--enable-version3 \
	--enable-gpl \
	--enable-nonfree \
	--disable-stripping \
	--disable-ffmpeg \
	--disable-ffplay \
	--disable-ffserver \
	--disable-ffprobe \
	--disable-encoders \
	--disable-muxers \
	--disable-devices \
	--disable-protocols \
	--enable-protocol=file \
	--enable-avfilter \
	--disable-network \
	--disable-mpegaudio-hp \
	--disable-avdevice \
	--enable-cross-compile \
	--cc=$PREBUILT/bin/arm-eabi-gcc \
	--cross-prefix=$PREBUILT/bin/arm-eabi- \
	--nm=$PREBUILT/bin/arm-eabi-nm \
	--extra-cflags="-fPIC -DANDROID" \
	--disable-asm \
	--enable-neon \
	--enable-armv5te \
	--extra-ldflags="-Wl,-T,$PREBUILT/arm-eabi/lib/ldscripts/armelf.x -Wl,-rpath-link=$PLATFORM/usr/lib -L$PLATFORM/usr/lib -nostdlib $PREBUILT/lib/gcc/arm-eabi/4.4.0/crtbegin.o $PREBUILT/lib/gcc/arm-eabi/4.4.0/crtend.o -lc -lm -ldl"

 

Then change mode config.sh and run

 

chmod +x config.sh
./config.sh

 

 

When config is completed, open config.h, find:

#define restrict restrict

 

replace by

#define restrict

 

 

Open libavutil/libm.h, remove static keyword in all function declaration.

Open Makefile in libavcodec, libavfilter, libavformat, libavutil, libpostproc and libswscale and remove two lines:

 

include $(SUBDIR)../subdir.mak
include $(SUBDIR)../config.mak

 

 

add new av.mk file in ffmpeg folder:

 

# LOCAL_PATH is one of libavutil, libavcodec, libavformat, or libswscale

#include $(LOCAL_PATH)/../config-$(TARGET_ARCH).mak
include $(LOCAL_PATH)/../config.mak

OBJS :=
OBJS-yes :=
MMX-OBJS-yes :=
include $(LOCAL_PATH)/Makefile

# collect objects
OBJS-$(HAVE_MMX) += $(MMX-OBJS-yes)
OBJS += $(OBJS-yes)

FFNAME := lib$(NAME)
FFLIBS := $(foreach,NAME,$(FFLIBS),lib$(NAME))
FFCFLAGS  = -DHAVE_AV_CONFIG_H -Wno-sign-compare -Wno-switch -Wno-pointer-sign
FFCFLAGS += -DTARGET_CONFIG=\"config-$(TARGET_ARCH).h\"

ALL_S_FILES := $(wildcard $(LOCAL_PATH)/$(TARGET_ARCH)/*.S)
ALL_S_FILES := $(addprefix $(TARGET_ARCH)/, $(notdir $(ALL_S_FILES)))

ifneq ($(ALL_S_FILES),)
ALL_S_OBJS := $(patsubst %.S,%.o,$(ALL_S_FILES))
C_OBJS := $(filter-out $(ALL_S_OBJS),$(OBJS))
S_OBJS := $(filter $(ALL_S_OBJS),$(OBJS))
else
C_OBJS := $(OBJS)
S_OBJS :=
endif

C_FILES := $(patsubst %.o,%.c,$(C_OBJS))
S_FILES := $(patsubst %.o,%.S,$(S_OBJS))

FFFILES := $(sort $(S_FILES)) $(sort $(C_FILES))

 

 

Create Android.mk in jni folder:

include $(all-subdir-makefiles)

 

Create Android.mk in ffmpeg folder:

 

LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_STATIC_LIBRARIES := libavformat libavcodec libavutil libpostproc libswscale
LOCAL_MODULE := ffmpeg
include $(BUILD_SHARED_LIBRARY)
include $(call all-makefiles-under,$(LOCAL_PATH))

 

 

libavformat/Android.mk

LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
include $(LOCAL_PATH)/../av.mk
LOCAL_SRC_FILES := $(FFFILES)
LOCAL_C_INCLUDES :=		\
	$(LOCAL_PATH)		\
	$(LOCAL_PATH)/..
LOCAL_CFLAGS += $(FFCFLAGS)
LOCAL_CFLAGS += -include "string.h" -Dipv6mr_interface=ipv6mr_ifindex
LOCAL_LDLIBS := -lz
LOCAL_STATIC_LIBRARIES := $(FFLIBS)
LOCAL_MODULE := $(FFNAME)
include $(BUILD_STATIC_LIBRARY)

 

 

libavcodec/Android.mk

 

LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
include $(LOCAL_PATH)/../av.mk
LOCAL_SRC_FILES := $(FFFILES)
LOCAL_C_INCLUDES :=		\
	$(LOCAL_PATH)		\
	$(LOCAL_PATH)/..
LOCAL_CFLAGS += $(FFCFLAGS)
LOCAL_LDLIBS := -lz
LOCAL_STATIC_LIBRARIES := $(FFLIBS)
LOCAL_MODULE := $(FFNAME)
include $(BUILD_STATIC_LIBRARY)

 

 

libavfilter, libavutil, libpostproc and libswscale / Android.mk

 

LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
include $(LOCAL_PATH)/../av.mk
LOCAL_SRC_FILES := $(FFFILES)
LOCAL_C_INCLUDES :=		\
	$(LOCAL_PATH)		\
	$(LOCAL_PATH)/..
LOCAL_CFLAGS += $(FFCFLAGS)
LOCAL_STATIC_LIBRARIES := $(FFLIBS)
LOCAL_MODULE := $(FFNAME)
include $(BUILD_STATIC_LIBRARY)

 

 

now, just go to jni folder and type ndk-build, then you will have ffmpeg.so

 

Source: http://abitno.me/compile-ffmpeg-android-ndk

 

Edit: if you need a reference:

http://rockplayer.freecoder.org/download/rockplayer_ffmpeg.zip

 

If you have some error messages about assembler, try to add this line to Android.mk LOCAL_ARM_MODE := arm 

'오픈소스 연구 > FFMPEG' 카테고리의 다른 글

libffmpeg.so for Android  (5) 2011.12.14
간단하고 명료한 FFMPEG 샘플 코드  (0) 2011.09.23
FFMpeg for Android #2  (28) 2011.04.19
FFMpeg for Android #1  (0) 2011.04.15
FFmpeg for Android 설치 및 컴파일  (12) 2011.03.17
FFmpeg 기초 예제  (2) 2011.02.24

관련글 더보기

댓글 영역

  • 프로필 사진
    2011.03.30 19:01
    libffmpeg.so가 있어도 해당 라이브러리 파일 안에 jni wrapper가 있어야 되지 않나요?
    java쪽만 해봐서 이 부분을 어떻게 해서 사용할 수 있는지 궁금합니다.
    • 프로필 사진
      2011.03.30 21:23 신고
      아래 자료들을 참고하세요.

      JNI 관련자료
      http://java.sun.com/docs/books/jni/download/jni.pdf

      ffmpeg을 이용한 동영상 플레이어 소스
      https://github.com/tewilove/faplayer

      인사이드 안드로이드라는 책에
      NDK에 대한 설명이 나와 있습니다.
  • 프로필 사진
    2011.05.13 16:08
    첨부된 libffmpeg.so 를 사용하려고 하는데요...
    c언어에 jni 함수이름이 뭐로 되어 있는지 알고 싶은데요...
    java에서 테스트 하고 싶은데 메소드명을 몰라서...그런데...좀 가르쳐 주세요.
    • 프로필 사진
      2011.05.13 16:51 신고
      ffmpeg 함수 그대로 입니다.
      사용하시는 헤더에 포함된 함수 그대로 사용하시면 되며,
      위에 설명한데로,
      img_convert(), sws_scale() 등은 포함되지 않은 듯 합니다.
  • 프로필 사진
    2011.05.13 17:05
    오...빠른 답변 감사합니다...이렇게 빨리 대답해 주실줄은...감사해요....
    기존에 있던 함수는 자바에 네이티브 추가 해주면 된다는 말씀이세요?

    호출 할수 있는 메소드는 jni라고 선언한 함수만 호출 할수 있는게 아닌가요?

    jstring
    Java_com_example_hellojni_HelloJni_stringFromJNI( JNIEnv* env,
    jobject thiz )
    {
    return (*env)->NewStringUTF(env, "Hello from JNI !");
    }

    위와 같은 식으로....

    제가 지식이 부족한건지...so라이브러리도 되어 있어서..내부를 볼수 없어서

    so라이브러리 만든 사람이 Java_com_example_hellojni_HelloJni_stringFromJNI을
    뭐라고 한지 알수가 없어서 호출을 할수가 없는데....

    현재 제가 이해 못하고 있는지?

    죄송합니다.

    설명 부탁 드립니다.
    • 프로필 사진
      2011.05.13 17:28 신고
      jni 네이티브 c,c++ 소스에서,
      ffmpeg 함수를 호출하셔야 합니다.

      즉,
      libffmpeg.so --> c,c++ (jni) --> 새로운 so 파일

      자바에서는 libffmpeg.so와 새로운 so 파일 모두를 로드하세요.
  • 프로필 사진
    2011.05.13 17:47
    답변감사합니다.

    류종택 님이 첨부 해주신 libffmpeg.zip(libffmpeg.so)로 했거든요....

    libffmpeg.so --> c,c++ (jni) --> 새로운 so 파일 ??


    libffmpeg.so을 System.loadLibrary("ffmpeg"); 이렇게 로드해서
    씨언어에 선언되어 있는 jni 인터페이스 구현해서 호출 해주면 되는거 아닌가요?
    제가 이해 하기론 libffmpeg.so 화일에는 이미 jni구현이 되어 있는 줄 알았는데...

    위에 설명을 보면

    libffmpeg.so --> c,c++ (jni) --> 새로운 so 파일
    첨부 화일 ffmpeg.c(jni) 화일을 컴파일해서 so

    libffmpeg.so와 jni구현한(ffmpeg.c) so화일을 로드후 호출?
    이런식인가요?

    libffmpeg.so는 libavcodec, libavdevice, libavfilter, libavformat등등 컴파일 되어 있고
    jni를 사용하고 싶은 파일만 libavutil/avstring.h,avstring.c 작성해서 so컴파일 하고

    둘 로드 한다음 호출 ?

    죄송합니다.

    설명 부탁 드립니다.
    • 프로필 사진
      2011.05.15 14:15 신고
      첨부된 libffmpeg.so 파일은 jni와 전혀 상관없이,
      ffmpeg 자체를 동적 라이브러리화 한 것 입니다.
  • 프로필 사진
    2011.05.18 09:16
    답글 감사합니다.

    그럼 제가 사용하기 위해서는 저에게 맞게 jni를 만들어 Cygwin환경에서 컴파일을 해야한다는 말이군요.

    Cygwin환경에서 몇번 컴파일을 해봤는데 실패를 했었거든요...

    ->일단 저는 다른 개발자가 만들어 놓은 libffmpeg.so를 이용해서 테스트 중 입니다.

    위에 색이 들어있는 박스에 위 처럼 써 있어서 테스트 할수 있다고 생각했거든요.

    제가 제대로 이해 하고 있는건가요?
  • 프로필 사진
    2011.05.18 14:19
    제가 말씀드리는 컴파일은 네이티브를 넣어서 컴파일 하는 ffmpeg를 말하는것입니다.
    • 프로필 사진
      2011.05.18 17:01 신고
      저는 ffmpeg은 우분투에서 컴파일 했습니다.
      (제 블로그에 VMWare 이미지가 있습니다)
      사실 질문을 제가 이해 못하는 것 때문에 도움이 못되는 거 같습니다.
      죄송합니다.