Recherche avancée

Médias (0)

Mot : - Tags -/xmlrpc

Aucun média correspondant à vos critères n’est disponible sur le site.

Autres articles (61)

  • L’utiliser, en parler, le critiquer

    10 avril 2011

    La première attitude à adopter est d’en parler, soit directement avec les personnes impliquées dans son développement, soit autour de vous pour convaincre de nouvelles personnes à l’utiliser.
    Plus la communauté sera nombreuse et plus les évolutions seront rapides ...
    Une liste de discussion est disponible pour tout échange entre utilisateurs.

  • Les statuts des instances de mutualisation

    13 mars 2010, par

    Pour des raisons de compatibilité générale du plugin de gestion de mutualisations avec les fonctions originales de SPIP, les statuts des instances sont les mêmes que pour tout autre objets (articles...), seuls leurs noms dans l’interface change quelque peu.
    Les différents statuts possibles sont : prepa (demandé) qui correspond à une instance demandée par un utilisateur. Si le site a déjà été créé par le passé, il est passé en mode désactivé. publie (validé) qui correspond à une instance validée par un (...)

  • MediaSPIP Init et Diogène : types de publications de MediaSPIP

    11 novembre 2010, par

    À l’installation d’un site MediaSPIP, le plugin MediaSPIP Init réalise certaines opérations dont la principale consiste à créer quatre rubriques principales dans le site et de créer cinq templates de formulaire pour Diogène.
    Ces quatre rubriques principales (aussi appelées secteurs) sont : Medias ; Sites ; Editos ; Actualités ;
    Pour chacune de ces rubriques est créé un template de formulaire spécifique éponyme. Pour la rubrique "Medias" un second template "catégorie" est créé permettant d’ajouter (...)

Sur d’autres sites (6917)

  • undefined reference to ffmpeg functions in native code using Android Studio 2.2

    12 octobre 2016, par Krzysztof Kansy

    I have a problem with using ffmpeg in Android Studio 2.2 using NDK 13 and new Cmake building system. FFmpeg version is 3.1.4.
    The system I’m working on is Linux Mint 18 64-bit.
    At the build time I’m getting undefined reference error each time I use ffpeg functions.

    My MainActivity.java :

    public class MainActivity extends AppCompatActivity {

       @Override
       protected void onCreate(Bundle savedInstanceState) {
           super.onCreate(savedInstanceState);
           setContentView(R.layout.activity_main);

       // Example of a call to a native method
       TextView tv = (TextView) findViewById(R.id.sample_text);
       tv.setText(stringFromJNI());
       }

       /**
        * A native method that is implemented by the 'native-lib' native library,
        * which is packaged with this application.
        */
       public native String stringFromJNI();

       // Used to load the 'native-lib' library on application startup.
       static {
           System.loadLibrary("native-lib");
       }
    }

    My native class (undefined reference is pointing to av_init_packet(&avPacket)) :

    #include
    #include <string>
    #include <android></android>log.h>
    #include <libavcodec></libavcodec>avcodec.h>


    extern "C"
    jstring
    Java_com_example_tito_jnitest_MainActivity_stringFromJNI(
           JNIEnv* env,
           jobject /* this */) {

       std::string hello = "Hello from C++";

       __android_log_print(ANDROID_LOG_INFO, "JNItest", "Hello from JNI!");

       AVPacket avPacket;
       av_init_packet(&amp;avPacket);

       return env->NewStringUTF(hello.c_str());
    }
    </string>

    build.gradle script

    apply plugin: 'com.android.application'

    android {
       compileSdkVersion 24
       buildToolsVersion "24.0.3"
       defaultConfig {
           applicationId "com.example.tito.jnitest"
           minSdkVersion 19
           targetSdkVersion 24
           versionCode 1
           versionName "1.0"
           testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
           externalNativeBuild {
               cmake {
                   // Passes optional arguments to CMake.
                   cppFlags "-frtti -fexceptions"
                   abiFilters 'armeabi'
               }
           }
       }

       sourceSets {
           main {
               jniLibs.srcDirs = ['/home/tito/AndroidStudioProjects/JNItest/app/src/main/jniLibs']
           }
       }

       buildTypes {
           release {
               minifyEnabled false
               proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
           }
       }
       externalNativeBuild {
           cmake {
               path "CMakeLists.txt"
           }
       }
    }

    dependencies {
       compile fileTree(dir: 'libs', include: ['*.jar'])
       androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
           exclude group: 'com.android.support', module: 'support-annotations'
       })
       compile 'com.android.support:appcompat-v7:24.2.1'
       testCompile 'junit:junit:4.12'
    }

    CMakeLists.txt

    cmake_minimum_required(VERSION 3.4.1)

    include_directories(/home/tito/Android/Sdk/ndk-bundle/sources/ffmpeg-3.1.4/android/${ANDROID_ABI}/include)

    #set(CMAKE_VERBOSE_MAKEFILE on)
    #set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=gnu++11")

    add_library( avutil
                SHARED
                IMPORTED )

    set_target_properties(
                   avutil
                   PROPERTIES IMPORTED_LOCATION
                   /home/tito/AndroidStudioProjects/JNItest/app/src/main/jniLibs/${ANDROID_ABI}/libavutil-55.so )

    add_library( swscale
                SHARED
                IMPORTED )

    set_target_properties(
                   swscale
                   PROPERTIES IMPORTED_LOCATION
                   /home/tito/AndroidStudioProjects/JNItest/app/src/main/jniLibs/${ANDROID_ABI}/libswscale-4.so )

    add_library( swresample
                SHARED
                IMPORTED )

    set_target_properties(
                   swresample
                   PROPERTIES IMPORTED_LOCATION
                   /home/tito/AndroidStudioProjects/JNItest/app/src/main/jniLibs/${ANDROID_ABI}/libswresample-2.so )

    add_library( avcodec
                SHARED
                IMPORTED )

    set_target_properties(
                   avcodec
                   PROPERTIES IMPORTED_LOCATION
                   /home/tito/AndroidStudioProjects/JNItest/app/src/main/jniLibs/${ANDROID_ABI}/libavcodec-57.so )

    add_library( avfilter
                SHARED
                IMPORTED )

    set_target_properties(
                   avfilter
                   PROPERTIES IMPORTED_LOCATION
                   /home/tito/AndroidStudioProjects/JNItest/app/src/main/jniLibs/${ANDROID_ABI}/libavfilter-6.so )

    add_library( avformat
                SHARED
                IMPORTED )

    set_target_properties(
                   avformat
                   PROPERTIES IMPORTED_LOCATION
                   /home/tito/AndroidStudioProjects/JNItest/app/src/main/jniLibs/${ANDROID_ABI}/libavformat-57.so )

    add_library( avdevice
                SHARED
                IMPORTED )

    set_target_properties(
                   avdevice
                   PROPERTIES IMPORTED_LOCATION
                   /home/tito/AndroidStudioProjects/JNItest/app/src/main/jniLibs/${ANDROID_ABI}/libavdevice-57.so )

    add_library( native-lib
                SHARED
                src/main/cpp/native-lib.cpp )

    find_library( log-lib
                 log )

    target_link_libraries(native-lib ${log-lib} avutil swscale swresample avcodec avfilter avformat avdevice)

    Build process of ffmpeg seemed to be successful. Here’s my build script :

    #!/bin/bash
    NDK=/home/tito/Android/Sdk/ndk-bundle
    SYSROOT=$NDK/platforms/android-19/arch-arm/
    TOOLCHAIN=$NDK/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64
    function build_one
    {
    ./configure \
    --prefix=$PREFIX \
    --disable-static \
    --enable-shared \
    --disable-doc \
    --disable-ffmpeg \
    --disable-ffplay \
    --disable-ffprobe \
    --disable-ffserver \
    --disable-doc \
    --cross-prefix=$TOOLCHAIN/bin/arm-linux-androideabi- \
    --target-os=linux \
    --arch=arm \
    --enable-cross-compile \
    --sysroot=$SYSROOT \
    --extra-cflags="-Os -fpic -marm" \
    --extra-ldflags="-marm" \
    $ADDITIONAL_CONFIGURE_FLAG
    make clean
    make
    make install
    }
    CPU=armeabi
    PREFIX=$(pwd)/android/$CPU
    build_one

    One thing I noticed that could indicate that something is wrong with ffmpeg build is warning WARNING: /home/tito/Android/Sdk/ndk-bundle/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64/bin/arm-linux-androideabi-pkg-config not found, library detection may fail. during building. I’m not sure if this may be cause of problems.

    I was trying to build for all of the ABIs, but for now I decided to focus on making just armeabi working. I’m having exact same failure after using e.g. arm64-v8a.

    Finally, here is the gradle console’s content with error :

    Executing tasks: [:app:assembleDebug]

    Configuration on demand is an incubating feature.
    Incremental java compilation is an incubating feature.
    :app:preBuild UP-TO-DATE
    :app:preDebugBuild UP-TO-DATE
    :app:checkDebugManifest
    :app:preReleaseBuild UP-TO-DATE
    :app:prepareComAndroidSupportAnimatedVectorDrawable2421Library UP-TO-DATE
    :app:prepareComAndroidSupportAppcompatV72421Library UP-TO-DATE
    :app:prepareComAndroidSupportSupportCompat2421Library UP-TO-DATE
    :app:prepareComAndroidSupportSupportCoreUi2421Library UP-TO-DATE
    :app:prepareComAndroidSupportSupportCoreUtils2421Library UP-TO-DATE
    :app:prepareComAndroidSupportSupportFragment2421Library UP-TO-DATE
    :app:prepareComAndroidSupportSupportMediaCompat2421Library UP-TO-DATE
    :app:prepareComAndroidSupportSupportV42421Library UP-TO-DATE
    :app:prepareComAndroidSupportSupportVectorDrawable2421Library UP-TO-DATE
    :app:prepareDebugDependencies
    :app:compileDebugAidl UP-TO-DATE
    :app:compileDebugRenderscript UP-TO-DATE
    :app:generateDebugBuildConfig UP-TO-DATE
    :app:generateDebugResValues UP-TO-DATE
    :app:generateDebugResources UP-TO-DATE
    :app:mergeDebugResources UP-TO-DATE
    :app:processDebugManifest UP-TO-DATE
    :app:processDebugResources
    :app:generateDebugSources
    :app:incrementalDebugJavaCompilationSafeguard UP-TO-DATE
    :app:compileDebugJavaWithJavac UP-TO-DATE
    :app:generateJsonModelDebug UP-TO-DATE
    :app:externalNativeBuildDebug
     building /home/tito/AndroidStudioProjects/JNItest/app/build/intermediates/cmake/debug/obj/armeabi/libnative-lib.so
    :app:externalNativeBuildDebug FAILED

    FAILURE: Build failed with an exception.

    * What went wrong:
    Execution failed for task ':app:externalNativeBuildDebug'.
    > Build command failed.
     Error while executing '/home/tito/Android/Sdk/cmake/3.6.3155560/bin/cmake' with arguments {--build /home/tito/AndroidStudioProjects/JNItest/app/.externalNativeBuild/cmake/debug/armeabi --target native-lib}
     [1/2] Building CXX object CMakeFiles/native-lib.dir/src/main/cpp/native-lib.cpp.o
     [2/2] Linking CXX shared library ../../../../build/intermediates/cmake/debug/obj/armeabi/libnative-lib.so
     FAILED: : &amp;&amp; /home/tito/Android/Sdk/ndk-bundle/toolchains/llvm/prebuilt/linux-x86_64/bin/clang++  -target armv5te-none-linux-androideabi -gcc-toolchain /home/tito/Android/Sdk/ndk-bundle/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64 --sysroot=/home/tito/Android/Sdk/ndk-bundle/platforms/android-19/arch-arm -fPIC -g -DANDROID -ffunction-sections -funwind-tables -fstack-protector-strong -no-canonical-prefixes -march=armv5te -mtune=xscale -msoft-float -fno-integrated-as -mthumb -Wa,--noexecstack -Wformat -Werror=format-security -fno-exceptions -fno-rtti -g -DANDROID -ffunction-sections -funwind-tables -fstack-protector-strong -no-canonical-prefixes -march=armv5te -mtune=xscale -msoft-float -fno-integrated-as -mthumb -Wa,--noexecstack -Wformat -Werror=format-security -fno-exceptions -fno-rtti -frtti -fexceptions -O0 -fno-limit-debug-info -O0 -fno-limit-debug-info  -Wl,--build-id -Wl,--warn-shared-textrel -Wl,--fatal-warnings -Wl,--no-undefined -Wl,-z,noexecstack -Qunused-arguments -Wl,-z,relro -Wl,-z,now -Wl,--build-id -Wl,--warn-shared-textrel -Wl,--fatal-warnings -Wl,--no-undefined -Wl,-z,noexecstack -Qunused-arguments -Wl,-z,relro -Wl,-z,now -shared -Wl,-soname,libnative-lib.so -o ../../../../build/intermediates/cmake/debug/obj/armeabi/libnative-lib.so CMakeFiles/native-lib.dir/src/main/cpp/native-lib.cpp.o  /home/tito/Android/Sdk/ndk-bundle/platforms/android-19/arch-arm/usr/lib/liblog.so ../../../../src/main/jniLibs/armeabi/libavutil-55.so ../../../../src/main/jniLibs/armeabi/libswscale-4.so ../../../../src/main/jniLibs/armeabi/libswresample-2.so ../../../../src/main/jniLibs/armeabi/libavcodec-57.so ../../../../src/main/jniLibs/armeabi/libavfilter-6.so ../../../../src/main/jniLibs/armeabi/libavformat-57.so ../../../../src/main/jniLibs/armeabi/libavdevice-57.so -lm "/home/tito/Android/Sdk/ndk-bundle/sources/cxx-stl/gnu-libstdc++/4.9/libs/armeabi/libgnustl_static.a" "-latomic" &amp;&amp; :
     /home/tito/AndroidStudioProjects/JNItest/app/src/main/cpp/native-lib.cpp:18: error: undefined reference to 'av_init_packet(AVPacket*)'
     clang++: error: linker command failed with exit code 1 (use -v to see invocation)
     ninja: build stopped: subcommand failed.


    * Try:
    Run with --info or --debug option to get more log output.

    * Exception is:
    org.gradle.api.tasks.TaskExecutionException: Execution failed for task ':app:externalNativeBuildDebug'.
       at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.executeActions(ExecuteActionsTaskExecuter.java:69)
       at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.execute(ExecuteActionsTaskExecuter.java:46)
       at org.gradle.api.internal.tasks.execution.PostExecutionAnalysisTaskExecuter.execute(PostExecutionAnalysisTaskExecuter.java:35)
       at org.gradle.api.internal.tasks.execution.SkipUpToDateTaskExecuter.execute(SkipUpToDateTaskExecuter.java:66)
       at org.gradle.api.internal.tasks.execution.ValidatingTaskExecuter.execute(ValidatingTaskExecuter.java:58)
       at org.gradle.api.internal.tasks.execution.SkipEmptySourceFilesTaskExecuter.execute(SkipEmptySourceFilesTaskExecuter.java:52)
       at org.gradle.api.internal.tasks.execution.SkipTaskWithNoActionsExecuter.execute(SkipTaskWithNoActionsExecuter.java:52)
       at org.gradle.api.internal.tasks.execution.SkipOnlyIfTaskExecuter.execute(SkipOnlyIfTaskExecuter.java:53)
       at org.gradle.api.internal.tasks.execution.ExecuteAtMostOnceTaskExecuter.execute(ExecuteAtMostOnceTaskExecuter.java:43)
       at org.gradle.execution.taskgraph.DefaultTaskGraphExecuter$EventFiringTaskWorker.execute(DefaultTaskGraphExecuter.java:203)
       at org.gradle.execution.taskgraph.DefaultTaskGraphExecuter$EventFiringTaskWorker.execute(DefaultTaskGraphExecuter.java:185)
       at org.gradle.execution.taskgraph.AbstractTaskPlanExecutor$TaskExecutorWorker.processTask(AbstractTaskPlanExecutor.java:66)
       at org.gradle.execution.taskgraph.AbstractTaskPlanExecutor$TaskExecutorWorker.run(AbstractTaskPlanExecutor.java:50)
       at org.gradle.execution.taskgraph.DefaultTaskPlanExecutor.process(DefaultTaskPlanExecutor.java:25)
       at org.gradle.execution.taskgraph.DefaultTaskGraphExecuter.execute(DefaultTaskGraphExecuter.java:110)
       at org.gradle.execution.SelectedTaskExecutionAction.execute(SelectedTaskExecutionAction.java:37)
       at org.gradle.execution.DefaultBuildExecuter.execute(DefaultBuildExecuter.java:37)
       at org.gradle.execution.DefaultBuildExecuter.access$000(DefaultBuildExecuter.java:23)
       at org.gradle.execution.DefaultBuildExecuter$1.proceed(DefaultBuildExecuter.java:43)
       at org.gradle.execution.DryRunBuildExecutionAction.execute(DryRunBuildExecutionAction.java:32)
       at org.gradle.execution.DefaultBuildExecuter.execute(DefaultBuildExecuter.java:37)
       at org.gradle.execution.DefaultBuildExecuter.execute(DefaultBuildExecuter.java:30)
       at org.gradle.initialization.DefaultGradleLauncher$4.run(DefaultGradleLauncher.java:153)
       at org.gradle.internal.Factories$1.create(Factories.java:22)
       at org.gradle.internal.progress.DefaultBuildOperationExecutor.run(DefaultBuildOperationExecutor.java:91)
       at org.gradle.internal.progress.DefaultBuildOperationExecutor.run(DefaultBuildOperationExecutor.java:53)
       at org.gradle.initialization.DefaultGradleLauncher.doBuildStages(DefaultGradleLauncher.java:150)
       at org.gradle.initialization.DefaultGradleLauncher.access$200(DefaultGradleLauncher.java:32)
       at org.gradle.initialization.DefaultGradleLauncher$1.create(DefaultGradleLauncher.java:98)
       at org.gradle.initialization.DefaultGradleLauncher$1.create(DefaultGradleLauncher.java:92)
       at org.gradle.internal.progress.DefaultBuildOperationExecutor.run(DefaultBuildOperationExecutor.java:91)
       at org.gradle.internal.progress.DefaultBuildOperationExecutor.run(DefaultBuildOperationExecutor.java:63)
       at org.gradle.initialization.DefaultGradleLauncher.doBuild(DefaultGradleLauncher.java:92)
       at org.gradle.initialization.DefaultGradleLauncher.run(DefaultGradleLauncher.java:83)
       at org.gradle.launcher.exec.InProcessBuildActionExecuter$DefaultBuildController.run(InProcessBuildActionExecuter.java:99)
       at org.gradle.tooling.internal.provider.runner.BuildModelActionRunner.run(BuildModelActionRunner.java:46)
       at org.gradle.launcher.exec.ChainingBuildActionRunner.run(ChainingBuildActionRunner.java:35)
       at org.gradle.tooling.internal.provider.runner.SubscribableBuildActionRunner.run(SubscribableBuildActionRunner.java:58)
       at org.gradle.launcher.exec.ChainingBuildActionRunner.run(ChainingBuildActionRunner.java:35)
       at org.gradle.launcher.exec.InProcessBuildActionExecuter.execute(InProcessBuildActionExecuter.java:48)
       at org.gradle.launcher.exec.InProcessBuildActionExecuter.execute(InProcessBuildActionExecuter.java:30)
       at org.gradle.launcher.exec.ContinuousBuildActionExecuter.execute(ContinuousBuildActionExecuter.java:81)
       at org.gradle.launcher.exec.ContinuousBuildActionExecuter.execute(ContinuousBuildActionExecuter.java:46)
       at org.gradle.launcher.daemon.server.exec.ExecuteBuild.doBuild(ExecuteBuild.java:52)
       at org.gradle.launcher.daemon.server.exec.BuildCommandOnly.execute(BuildCommandOnly.java:36)
       at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:120)
       at org.gradle.launcher.daemon.server.exec.WatchForDisconnection.execute(WatchForDisconnection.java:37)
       at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:120)
       at org.gradle.launcher.daemon.server.exec.ResetDeprecationLogger.execute(ResetDeprecationLogger.java:26)
       at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:120)
       at org.gradle.launcher.daemon.server.exec.RequestStopIfSingleUsedDaemon.execute(RequestStopIfSingleUsedDaemon.java:34)
       at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:120)
       at org.gradle.launcher.daemon.server.exec.ForwardClientInput$2.call(ForwardClientInput.java:74)
       at org.gradle.launcher.daemon.server.exec.ForwardClientInput$2.call(ForwardClientInput.java:72)
       at org.gradle.util.Swapper.swap(Swapper.java:38)
       at org.gradle.launcher.daemon.server.exec.ForwardClientInput.execute(ForwardClientInput.java:72)
       at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:120)
       at org.gradle.launcher.daemon.server.health.DaemonHealthTracker.execute(DaemonHealthTracker.java:47)
       at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:120)
       at org.gradle.launcher.daemon.server.exec.LogToClient.doBuild(LogToClient.java:60)
       at org.gradle.launcher.daemon.server.exec.BuildCommandOnly.execute(BuildCommandOnly.java:36)
       at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:120)
       at org.gradle.launcher.daemon.server.exec.EstablishBuildEnvironment.doBuild(EstablishBuildEnvironment.java:72)
       at org.gradle.launcher.daemon.server.exec.BuildCommandOnly.execute(BuildCommandOnly.java:36)
       at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:120)
       at org.gradle.launcher.daemon.server.health.HintGCAfterBuild.execute(HintGCAfterBuild.java:41)
       at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:120)
       at org.gradle.launcher.daemon.server.exec.StartBuildOrRespondWithBusy$1.run(StartBuildOrRespondWithBusy.java:50)
       at org.gradle.launcher.daemon.server.DaemonStateCoordinator$1.run(DaemonStateCoordinator.java:237)
       at org.gradle.internal.concurrent.ExecutorPolicy$CatchAndRecordFailures.onExecute(ExecutorPolicy.java:54)
       at org.gradle.internal.concurrent.StoppableExecutorImpl$1.run(StoppableExecutorImpl.java:40)
    Caused by: org.gradle.internal.UncheckedException: Build command failed.
    Error while executing '/home/tito/Android/Sdk/cmake/3.6.3155560/bin/cmake' with arguments {--build /home/tito/AndroidStudioProjects/JNItest/app/.externalNativeBuild/cmake/debug/armeabi --target native-lib}
    [1/2] Building CXX object CMakeFiles/native-lib.dir/src/main/cpp/native-lib.cpp.o
    [2/2] Linking CXX shared library ../../../../build/intermediates/cmake/debug/obj/armeabi/libnative-lib.so
    FAILED: : &amp;&amp; /home/tito/Android/Sdk/ndk-bundle/toolchains/llvm/prebuilt/linux-x86_64/bin/clang++  -target armv5te-none-linux-androideabi -gcc-toolchain /home/tito/Android/Sdk/ndk-bundle/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64 --sysroot=/home/tito/Android/Sdk/ndk-bundle/platforms/android-19/arch-arm -fPIC -g -DANDROID -ffunction-sections -funwind-tables -fstack-protector-strong -no-canonical-prefixes -march=armv5te -mtune=xscale -msoft-float -fno-integrated-as -mthumb -Wa,--noexecstack -Wformat -Werror=format-security -fno-exceptions -fno-rtti -g -DANDROID -ffunction-sections -funwind-tables -fstack-protector-strong -no-canonical-prefixes -march=armv5te -mtune=xscale -msoft-float -fno-integrated-as -mthumb -Wa,--noexecstack -Wformat -Werror=format-security -fno-exceptions -fno-rtti -frtti -fexceptions -O0 -fno-limit-debug-info -O0 -fno-limit-debug-info  -Wl,--build-id -Wl,--warn-shared-textrel -Wl,--fatal-warnings -Wl,--no-undefined -Wl,-z,noexecstack -Qunused-arguments -Wl,-z,relro -Wl,-z,now -Wl,--build-id -Wl,--warn-shared-textrel -Wl,--fatal-warnings -Wl,--no-undefined -Wl,-z,noexecstack -Qunused-arguments -Wl,-z,relro -Wl,-z,now -shared -Wl,-soname,libnative-lib.so -o ../../../../build/intermediates/cmake/debug/obj/armeabi/libnative-lib.so CMakeFiles/native-lib.dir/src/main/cpp/native-lib.cpp.o  /home/tito/Android/Sdk/ndk-bundle/platforms/android-19/arch-arm/usr/lib/liblog.so ../../../../src/main/jniLibs/armeabi/libavutil-55.so ../../../../src/main/jniLibs/armeabi/libswscale-4.so ../../../../src/main/jniLibs/armeabi/libswresample-2.so ../../../../src/main/jniLibs/armeabi/libavcodec-57.so ../../../../src/main/jniLibs/armeabi/libavfilter-6.so ../../../../src/main/jniLibs/armeabi/libavformat-57.so ../../../../src/main/jniLibs/armeabi/libavdevice-57.so -lm "/home/tito/Android/Sdk/ndk-bundle/sources/cxx-stl/gnu-libstdc++/4.9/libs/armeabi/libgnustl_static.a" "-latomic" &amp;&amp; :
    /home/tito/AndroidStudioProjects/JNItest/app/src/main/cpp/native-lib.cpp:18: error: undefined reference to 'av_init_packet(AVPacket*)'
    clang++: error: linker command failed with exit code 1 (use -v to see invocation)
    ninja: build stopped: subcommand failed.

       at org.gradle.internal.UncheckedException.throwAsUncheckedException(UncheckedException.java:45)
       at org.gradle.internal.reflect.JavaMethod.invoke(JavaMethod.java:78)
       at org.gradle.api.internal.project.taskfactory.AnnotationProcessingTaskFactory$StandardTaskAction.doExecute(AnnotationProcessingTaskFactory.java:228)
       at org.gradle.api.internal.project.taskfactory.AnnotationProcessingTaskFactory$StandardTaskAction.execute(AnnotationProcessingTaskFactory.java:221)
       at org.gradle.api.internal.project.taskfactory.AnnotationProcessingTaskFactory$StandardTaskAction.execute(AnnotationProcessingTaskFactory.java:210)
       at org.gradle.api.internal.AbstractTask$TaskActionWrapper.execute(AbstractTask.java:621)
       at org.gradle.api.internal.AbstractTask$TaskActionWrapper.execute(AbstractTask.java:604)
       at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.executeAction(ExecuteActionsTaskExecuter.java:80)
       at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.executeActions(ExecuteActionsTaskExecuter.java:61)
       ... 70 more
    Caused by: Build command failed.
    Error while executing '/home/tito/Android/Sdk/cmake/3.6.3155560/bin/cmake' with arguments {--build /home/tito/AndroidStudioProjects/JNItest/app/.externalNativeBuild/cmake/debug/armeabi --target native-lib}
    [1/2] Building CXX object CMakeFiles/native-lib.dir/src/main/cpp/native-lib.cpp.o
    [2/2] Linking CXX shared library ../../../../build/intermediates/cmake/debug/obj/armeabi/libnative-lib.so
    FAILED: : &amp;&amp; /home/tito/Android/Sdk/ndk-bundle/toolchains/llvm/prebuilt/linux-x86_64/bin/clang++  -target armv5te-none-linux-androideabi -gcc-toolchain /home/tito/Android/Sdk/ndk-bundle/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64 --sysroot=/home/tito/Android/Sdk/ndk-bundle/platforms/android-19/arch-arm -fPIC -g -DANDROID -ffunction-sections -funwind-tables -fstack-protector-strong -no-canonical-prefixes -march=armv5te -mtune=xscale -msoft-float -fno-integrated-as -mthumb -Wa,--noexecstack -Wformat -Werror=format-security -fno-exceptions -fno-rtti -g -DANDROID -ffunction-sections -funwind-tables -fstack-protector-strong -no-canonical-prefixes -march=armv5te -mtune=xscale -msoft-float -fno-integrated-as -mthumb -Wa,--noexecstack -Wformat -Werror=format-security -fno-exceptions -fno-rtti -frtti -fexceptions -O0 -fno-limit-debug-info -O0 -fno-limit-debug-info  -Wl,--build-id -Wl,--warn-shared-textrel -Wl,--fatal-warnings -Wl,--no-undefined -Wl,-z,noexecstack -Qunused-arguments -Wl,-z,relro -Wl,-z,now -Wl,--build-id -Wl,--warn-shared-textrel -Wl,--fatal-warnings -Wl,--no-undefined -Wl,-z,noexecstack -Qunused-arguments -Wl,-z,relro -Wl,-z,now -shared -Wl,-soname,libnative-lib.so -o ../../../../build/intermediates/cmake/debug/obj/armeabi/libnative-lib.so CMakeFiles/native-lib.dir/src/main/cpp/native-lib.cpp.o  /home/tito/Android/Sdk/ndk-bundle/platforms/android-19/arch-arm/usr/lib/liblog.so ../../../../src/main/jniLibs/armeabi/libavutil-55.so ../../../../src/main/jniLibs/armeabi/libswscale-4.so ../../../../src/main/jniLibs/armeabi/libswresample-2.so ../../../../src/main/jniLibs/armeabi/libavcodec-57.so ../../../../src/main/jniLibs/armeabi/libavfilter-6.so ../../../../src/main/jniLibs/armeabi/libavformat-57.so ../../../../src/main/jniLibs/armeabi/libavdevice-57.so -lm "/home/tito/Android/Sdk/ndk-bundle/sources/cxx-stl/gnu-libstdc++/4.9/libs/armeabi/libgnustl_static.a" "-latomic" &amp;&amp; :
    /home/tito/AndroidStudioProjects/JNItest/app/src/main/cpp/native-lib.cpp:18: error: undefined reference to 'av_init_packet(AVPacket*)'
    clang++: error: linker command failed with exit code 1 (use -v to see invocation)
    ninja: build stopped: subcommand failed.

       at com.android.build.gradle.tasks.ExternalNativeBuildTaskUtils.executeBuildProcessAndLogError(ExternalNativeBuildTaskUtils.java:233)
       at com.android.build.gradle.tasks.ExternalNativeBuildTask.executeProcessBatch(ExternalNativeBuildTask.java:231)
       at com.android.build.gradle.tasks.ExternalNativeBuildTask.build(ExternalNativeBuildTask.java:163)
       at org.gradle.internal.reflect.JavaMethod.invoke(JavaMethod.java:75)
       ... 77 more


    BUILD FAILED

    Total time: 0.723 secs

    Can anyone tell me what I’m doing wrong here ?

  • ffmpeg installation undefined reference to

    8 février 2017, par user1683302

    I used this official link to download ffmpeg and compile it. I know it creates a static library and I have to reference the library folder. When i try to compile this tutorial . i get this errors

    tutorial01.c: In function ‘main’:
    tutorial01.c:96:5: warning: ‘codec’ is deprecated [-Wdeprecated- declarations]
    if(pFormatCtx->streams[i]->codec->codec_type==AVMEDIA_TYPE_VIDEO) {
    ^
    In file included from tutorial01.c:27:0:
    /home/osboxes/ffmpeg_build/include/libavformat/avformat.h:893:21: note:  declared here
    AVCodecContext *codec;
                    ^
    tutorial01.c:104:3: warning: ‘codec’ is deprecated [-Wdeprecated-declarations]
    pCodecCtxOrig=pFormatCtx->streams[videoStream]->codec;
    ^
    In file included from tutorial01.c:27:0:
    /home/osboxes/ffmpeg_build/include/libavformat/avformat.h:893:21: note: declared here
    AVCodecContext *codec;
                    ^
    tutorial01.c:113:3: warning: ‘avcodec_copy_context’ is deprecated  [-Wdeprecated-declarations]
    if(avcodec_copy_context(pCodecCtx, pCodecCtxOrig) != 0) {
    ^
    In file included from tutorial01.c:26:0:
    /home/osboxes/ffmpeg_build/include/libavcodec/avcodec.h:4240:5: note: declared here
    int avcodec_copy_context(AVCodecContext *dest, const AVCodecContext *src);
    ^
    tutorial01.c:131:3: warning: ‘avpicture_get_size’ is deprecated   [-Wdeprecated-declarations]
    numBytes=avpicture_get_size(AV_PIX_FMT_RGB24, pCodecCtx->width,
    ^
    In file included from tutorial01.c:26:0:
    /home/osboxes/ffmpeg_build/include/libavcodec/avcodec.h:5467:5: note: declared here
    int avpicture_get_size(enum AVPixelFormat pix_fmt, int width, int height);
    ^
     tutorial01.c:138:3: warning: ‘avpicture_fill’ is deprecated [-Wdeprecated-declarations]
      avpicture_fill((AVPicture *)pFrameRGB, buffer, AV_PIX_FMT_RGB24,
      ^
     In file included from tutorial01.c:26:0:
     /home/osboxes/ffmpeg_build/include/libavcodec/avcodec.h:5452:5: note: declared here
     int avpicture_fill(AVPicture *picture, const uint8_t *ptr,
    ^
      tutorial01.c:160:7: warning: ‘avcodec_decode_video2’ is deprecated [-Wdeprecated-declarations]
          avcodec_decode_video2(pCodecCtx, pFrame, &amp;frameFinished, &amp;packet);
          ^
    In file included from tutorial01.c:26:0:
     /home/osboxes/ffmpeg_build/include/libavcodec/avcodec.h:4811:5: note: declared here
     int avcodec_decode_video2(AVCodecContext *avctx, AVFrame *picture,
    ^
     tutorial01.c:177:5: warning: ‘av_free_packet’ is deprecated [-Wdeprecated-declarations]
     av_free_packet(&amp;packet);
     ^
    In file included from tutorial01.c:26:0:
    /home/osboxes/ffmpeg_build/include/libavcodec/avcodec.h:4472:6: note: declared here
    void av_free_packet(AVPacket *pkt);
     ^
    /tmp/ccHYDd9j.o: In function `main':
    tutorial01.c:(.text+0x178): undefined reference to `av_register_all'
    tutorial01.c:(.text+0x19f): undefined reference to `avformat_open_input'
    tutorial01.c:(.text+0x1c1): undefined reference to `avformat_find_stream_info'
    tutorial01.c:(.text+0x1f6): undefined reference to `av_dump_format'
    tutorial01.c:(.text+0x2ab): undefined reference to `avcodec_find_decoder'
    tutorial01.c:(.text+0x2ea): undefined reference to `avcodec_alloc_context3'
    tutorial01.c:(.text+0x304): undefined reference to `avcodec_copy_context'
    tutorial01.c:(.text+0x348): undefined reference to `avcodec_open2'
    tutorial01.c:(.text+0x35b): undefined reference to `av_frame_alloc'
    tutorial01.c:(.text+0x367): undefined reference to `av_frame_alloc'
    tutorial01.c:(.text+0x3a4): undefined reference to `avpicture_get_size'
    tutorial01.c:(.text+0x3ba): undefined reference to `av_malloc'
    tutorial01.c:(.text+0x3ef): undefined reference to `avpicture_fill'
    tutorial01.c:(.text+0x439): undefined reference to `sws_getContext'
    tutorial01.c:(.text+0x47d): undefined reference to `avcodec_decode_video2'
    tutorial01.c:(.text+0x4de): undefined reference to `sws_scale'
    tutorial01.c:(.text+0x527): undefined reference to `av_free_packet'
    tutorial01.c:(.text+0x53d): undefined reference to `av_read_frame'
    tutorial01.c:(.text+0x551): undefined reference to `av_free'
    tutorial01.c:(.text+0x560): undefined reference to `av_frame_free'
    tutorial01.c:(.text+0x56f): undefined reference to `av_frame_free'
    tutorial01.c:(.text+0x57b): undefined reference to `avcodec_close'
    tutorial01.c:(.text+0x58a): undefined reference to `avcodec_close'
    tutorial01.c:(.text+0x599): undefined reference to `avformat_close_input'
    collect2: error: ld returned 1 exit status

    i used this sudo gcc -I /home/osboxes/ffmpeg_build/include -L /home/osboxes/ffmpeg_build/lib -lavcode -lavformat -lavutil -lswscale -lz -lm tutorial01.c

    my ffmpeg is

    ffmpeg version N-82113-g490c6bd Copyright (c) 2000-2016 the FFmpeg developers
      built with gcc 5.4.0 (Ubuntu 5.4.0-6ubuntu1~16.04.2) 20160609
      configuration: --prefix=/home/osboxes/ffmpeg_build --pkg-config-flags=--static --extra-cflags=-I/home/osboxes/ffmpeg_build/include --extra-ldflags=- L/home/osboxes/ffmpeg_build/lib --bindir=/home/osboxes/bin --enable-gpl --enable-libass --enable-libfdk-aac --enable-libfreetype --enable-libopus --enable-libx264 --enable-nonfree
     libavutil      55. 33.100 / 55. 33.100
     libavcodec     57. 63.103 / 57. 63.103
     libavformat    57. 55.100 / 57. 55.100
     libavdevice    57.  0.103 / 57.  0.103
     libavfilter     6. 64.100 /  6. 64.100
     libswscale      4.  1.100 /  4.  1.100
     libswresample   2.  2.100 /  2.  2.100
     libpostproc    54.  0.100 / 54.  0.100
    Hyper fast Audio and Video encoder
    usage: ffmpeg [options] [[infile options] -i infile]... {[outfile options] outfile}...

    the tutorial code was update to work on new ffmpeg versions.I’m using VM Ubuntu 16.0.4 64 bit fresh install on windows 10 host.

    so why I’m having all of these errors ?

    Update :
    I moved to Ubuntu 12.04 VM and ffmpeg 0.11, I instilled it with opencv 2.4.2 here is the link . This should work yet i don’t why I’m having hard time compiling such small program.

    ffmpeg version 0.11.1 Copyright (c) 2000-2012 the FFmpeg developers
    built on Oct 25 2016 13:39:37 with gcc 4.6.3
     configuration: --enable-gpl --enable-libfaac --enable-libmp3lame    --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-libtheora --enable-libvorbis --enable-libx264 --enable-libxvid --enable-nonfree --enable-postproc --enable-version3 --enable-x11grab --enable-shared --enable-pic
    libavutil      51. 54.100 / 51. 54.100
    libavcodec     54. 23.100 / 54. 23.100
    libavformat    54.  6.100 / 54.  6.100
    libavdevice    54.  0.100 / 54.  0.100
    libavfilter     2. 77.100 /  2. 77.100
    libswscale      2.  1.100 /  2.  1.100
    libswresample   0. 15.100 /  0. 15.100
    libpostproc    52.  0.100 / 52.  0.100
    Hyper fast Audio and Video encoder
    usage: ffmpeg [options] [[infile options] -i infile]... {[outfile options] outfile}...

    yet i still have the problem but it is less sever

    gcc -o tutorial01 tutorial01.c -Wl,--start-group -lavcodec -lavformat  -lswscale -lavutil -lz -lm -Wl,--end-group    
     /tmp/ccnFfu84.o: In function `main':
     tutorial01.c:(.text+0x500): undefined reference to `avcodec_free_frame'
     tutorial01.c:(.text+0x511): undefined reference to `avcodec_free_frame'
     collect2: ld returned 1 exit status

    i tried this ldconfig -p | grep av

     libxklavier.so.16 (libc6,x86-64) => /usr/lib/libxklavier.so.16
     libwavpack.so.1 (libc6,x86-64) => /usr/lib/x86_64-linux gnu/libwavpack.so.1
    libjavascriptcoregtk-3.0.so.0 (libc6,x86-64) => /usr/lib/libjavascriptcoregtk-3.0.so.0
    libdvdnavmini.so.4 (libc6,x86-64) => /usr/lib/libdvdnavmini.so.4
    libdvdnav.so.4 (libc6,x86-64) => /usr/lib/libdvdnav.so.4
    libavutil.so.51 (libc6,x86-64) => /usr/local/lib/libavutil.so.51
    libavutil.so.51 (libc6,x86-64) => /usr/lib/x86_64-linux-gnu/libavutil.so.51
    libavutil.so (libc6,x86-64) => /usr/local/lib/libavutil.so
    libavformat.so.54 (libc6,x86-64) => /usr/local/lib/libavformat.so.54
    libavformat.so.53 (libc6,x86-64) => /usr/lib/x86_64-linux-gnu/libavformat.so.53
    libavformat.so (libc6,x86-64) => /usr/local/lib/libavformat.so
    libavfilter.so.2 (libc6,x86-64) => /usr/local/lib/libavfilter.so.2
    libavfilter.so (libc6,x86-64) => /usr/local/lib/libavfilter.so
    libavdevice.so.54 (libc6,x86-64) => /usr/local/lib/libavdevice.so.54
    libavdevice.so (libc6,x86-64) => /usr/local/lib/libavdevice.so
    libavc1394.so.0 (libc6,x86-64) => /usr/lib/x86_64-linux-gnu/libavc1394.so.0
    libavcodec.so.54 (libc6,x86-64) => /usr/local/lib/libavcodec.so.54
    libavcodec.so.53 (libc6,x86-64) => /usr/lib/x86_64-linux-gnu/libavcodec.so.53
    libavcodec.so (libc6,x86-64) => /usr/local/lib/libavcodec.so
    libavahi-ui-gtk3.so.0 (libc6,x86-64) => /usr/lib/x86_64-linux-gnu/libavahi-ui-gtk3.so.0
    libavahi-gobject.so.0 (libc6,x86-64) => /usr/lib/x86_64-linux-gnu/libavahi-gobject.so.0
    libavahi-glib.so.1 (libc6,x86-64) => /usr/lib/x86_64-linux-gnu/libavahi-glib.so.1
    libavahi-core.so.7 (libc6,x86-64) => /usr/lib/x86_64-linux-gnu/libavahi-core.so.7
    libavahi-common.so.3 (libc6,x86-64) => /usr/lib/x86_64-linux-gnu/libavahi-common.so.3
    libavahi-common.so (libc6,x86-64) => /usr/lib/x86_64-linux-gnu/libavahi-common.so
    libavahi-client.so.3 (libc6,x86-64) => /usr/lib/x86_64-linux-gnu/libavahi-client.so.3
    libavahi-client.so (libc6,x86-64) => /usr/lib/x86_64-linux-gnu/libavahi-client.so

    Update2

    I changged avcodec_free_frame to av_free and the file complied

    Dranger code is old

    Update 3
    i downloaded ffmpeg 1.0.10 which has the same library version that is the tutorial tested on. Everything complied without any problem now.

  • Subtitling Sierra VMD Files

    1er juin 2016, par Multimedia Mike — Game Hacking

    I was contacted by a game translation hobbyist from Spain (henceforth known as The Translator). He had set his sights on Sierra’s 7-CD Phantasmagoria. This mammoth game was driven by a lot of FMV files and animations that have speech. These require language translation in the form of video subtitling. He’s lucky that he found possibly the one person on the whole internet who has just the right combination of skill, time, and interest to pull this off. And why would I care about helping ? I guess I share a certain camaraderie with game hackers. Don’t act so surprised. You know what kind of stuff I like to work on.

    The FMV format used in this game is VMD, which makes an appearance in numerous Sierra titles. FFmpeg already supports decoding this format. FFmpeg also supports subtitling video. So, ideally, all that’s necessary to support this goal is to add a muxer for the VMD format which can encode raw video and audio, which the format supports. Implement video compression as extra credit.

    The pipeline that I envisioned looks like this :


    VMD Subtitling Process

    VMD Subtitling Process


    “Trivial !” I surmised. I just never learn, do I ?

    The Plan
    So here’s my initial pitch, outlining the work I estimated that I would need to do towards the stated goal :

    1. Create a new file muxer that produces a syntactically valid VMD file with bogus video and audio data. Make sure it works with both FFmpeg’s playback system as well as the proper Phantasmagoria engine.
    2. Create a new video encoder that essentially operates in pass-through mode while correctly building a palette.
    3. Create a new basic encoder for the video frames.

    A big unknown for me was exactly how subtitle handling operates in FFmpeg. Thanks to this project, I now know. I was concerned because I was pretty sure that font rendering entails anti-aliasing which bodes poorly for keeping the palette count under 256 unique colors.

    Computer Science Puzzle
    When pondering how to process the palette, I was excited for the opportunity to exercise actual computer science. FFmpeg converts frames from paletted frames to full RGB frames. Then it needs to convert them back to paletted frames. I had a vague recollection of solving this problem once before when I was experimenting with a new paletted video codec. I seem to recall that I did the palette conversion in a very naive manner. I just used a static 256-element array and processed each RGB pixel of the frame, seeing if the value already occurred in the table (O(n) lookup) and adding it otherwise.

    There are more efficient algorithms, however, such as hash tables and trees. Somewhere along the line, FFmpeg helpfully acquired a rarely-used tree data structure, which was perfect for this project.

    So I was pretty pleased with this optimization. Too bad this wouldn’t survive to the end of the effort.

    Another palette-related challenge was the fact that a group of pictures would be accumulating a new palette but that palette needed to be recorded before the group. Thus, the muxer needed to have extra logic to rewind the file when the video encoder transmitted a palette change.

    Video Compression
    VMD has a few methods in its compression toolbox. It can use interframe differencing, it has some RLE, or it can code a frame raw. It can also use a custom LZ-like format on top of these. For early prototypes, I elected to leave each frame coded raw. After the concept was proved, I implemented the frame differencing.


    VMD frame #1

    VMD frame #2

    VMD frame difference
    Top frame compared with the middle frame yields the bottom frame : red pixels indicate changes

    Encoding only those red dots in between vast runs of unchanged pixels yielded a vast measurable improvement. The next step was to try wiring up FFmpeg’s existing LZ compression facilities to the encoder. This turned out to be implausible since VMD’s LZ variant has nothing to do with anything FFmpeg already provides. Fortunately, the LZ piece is not absolutely required and the frame differencing + RLE provides plenty of compression.

    Subtitling
    I’ve never done anything, multimedia programming-wise, concerning subtitles. I guess all the entertainment I care about has always been in my native tongue. What a good excuse to program outside of my comfort zone !

    First, I needed to know how to access FFmpeg’s subtitling facilities. Fortunately, The Translator did the legwork on this matter so I didn’t have to figure it out.

    However, I intuitively had misgivings about this phase. I had heard that the subtitling process performs anti-aliasing. That means that the image would need to be promoted to a higher colorspace for this phase and that the anti-aliasing process would likely push the color count way past 256. Some quick tests revealed this to be the case, as the running color count would leap by several hundred colors as soon as the palette accounting algorithm encountered a subtitle.

    So I dug into the subtitle subsystem. I discovered that the subtitle library operates by creating a linked list of subtitle bitmaps that the client app must render. The bitmaps are comprised of 8-bit alpha transparency values that must be composited onto the target frame (i.e., 0 = transparent, 255 = 100% opaque). For example, the letter ‘H’ :

                                      (with 00s removed)
    13 F8 41 00 00 00 00 68 E4  |  13 F8 41             68 E4    
    14 FF 44 00 00 00 00 6C EC  |  14 FF 44             6C EC
    14 FF 44 00 00 00 00 6C EC  |  14 FF 44             6C EC
    14 FF 44 00 00 00 00 6C EC  |  14 FF 44             6C EC
    14 FF DC D0 D0 D0 D0 E4 EC  |  14 FF DC D0 D0 D0 D0 E4 EC
    14 FF 7E 50 50 50 50 9A EC  |  14 FF 7E 50 50 50 50 9A EC
    14 FF 44 00 00 00 00 6C EC  |  14 FF 44             6C EC
    14 FF 44 00 00 00 00 6C EC  |  14 FF 44             6C EC
    14 FF 44 00 00 00 00 6C EC  |  14 FF 44             6C EC
    11 E0 3B 00 00 00 00 5E CE  |  11 E0 3B             5E CE
    

    To get around the color explosion problem, I chose a threshold value and quantized values above and below to 255 and 0, respectively. Further, the process chooses an appropriate color from the existing palette rather than introducing any new colors.

    Muxing Matters
    In order to force VMD into a general purpose media framework, a lot of special information needs to be passed around. Like many paletted codecs, the palette needs to be transmitted from the file demuxer to the video decoder via some side channel. For re-encoding, this also implies that the palette needs to make the trip from the video encoder to the file muxer. As if this wasn’t enough, individual VMD frames have even more data that needs to be ferried between the muxer and codec levels, including frame change boundaries. FFmpeg provides methods to do these things, but I could not always rely on the systems to relay the data in all cases. I was probably doing something wrong ; I accept that. Instead, I just packed all the information at the front of an encoded frame and split it apart in the muxer.

    I could not quite figure out how to get the audio and video muxed correctly. As a result, neither FFmpeg nor the Phantasmagoria engine could replay the files correctly.

    Plan B
    Since I was having so much trouble creating an entirely new VMD file, likely due to numerous unknown bits of the file format, I thought of another angle : re-use the existing VMD file. For this approach, I kept the video encoder and file muxer that I created in the initial phase, but modified the file muxer to emit a special intermediate file. Then, I created a Python tool to repackage the original VMD file using compressed video data in the intermediate file.

    For this phase, I also implemented a command line switch for FFmpeg to disable subtitle blending, to make the feature feel like less of an unofficial hack, as though this nonsense would ever have a chance of being incorporated upstream.

    At this point, I was seeing some success with the complete, albeit roundabout, subtitling process. I constructed a subtitle file using “Spanish I Learned From Mexican Telenovelas” and the frames turned out fairly readable :


    Le puso los cuernos a él

    “she cheated on him”


    es un desgraciado

    “he’s a scumbag” … these random subtitles could fit surprisingly well !


    The few files that I tested appeared to work fine. But then I handed off my work to The Translator and he immediately found a bunch of problems. According to my notes, the problems mostly took the form of flashing, solid color frames. Further, I found tiny, mostly imperceptible flaws in my RLE compressor, usually only detectable by running strict comparison tools ; but I wasn’t satisfied.

    At this point, I think I attempted to just encode the entire palette at the front of each frame, as allowed by the format, but that did not seem to fix any problems. My notes are not completely clear on this matter (likely because I was still trying to figure out the exact problem), but I think it had to do with FFmpeg inserting extra video frames in order to even out gaps in the video framerate.

    Sigh, Plan C
    At this point, I was getting tired of trying to force FFmpeg to do this. So I decided to minimize its involvement using lessons learned up to this point.

    The next pitch :

    1. Create a new C program that can open an existing VMD file and output an identical VMD file. I know this sounds easy, but the specific method of copying entails interpreting individual parts of the file and writing those individual parts to the new file. This is in preparation for…
    2. Import the VMD video decoder functions directly into the program to decode the individual video frames and re-encode them, replacing the video frames as the file is rewritten.
    3. Wire up the subtitle system. During the adventure to disable subtitle blending, I accidentally learned enough about interfacing to the subtitle library to just invoke it directly.
    4. Rewrite the RLE method so that it is 100% correct.

    Off to work I went. That part about lifting the existing VMD decoder functions out of their libavcodec nest turned out to not be that straightforward. As an alternative, I modified the decoder to dump the raw frames to an intermediate file. In doing so, I think I was able to avoid the issue of the duplicated frames that plagued the previous efforts.

    Also, remember how I was really pleased with the palette conversion technique in which I was able to leverage computer science big-O theory ? By this stage, I had no reason to convert the paletted video to RGB in the first place ; all of the decoding, subtitling and re-encoding operates in the paletted colorspace.

    This approach seemed to work pretty well. The final program is subtitle-vmd.c. The process is still a little weird. The modifications in my own FFmpeg fork are necessary to create an intermediate file that the new C tool can operate with.

    Next Steps
    The Translator has found some assorted bugs and corner cases that still need to be ironed out. Further, for extra credit, I need find the change windows for each frame to improve compression just a little more. I don’t think I will be trying for LZ compression, though.

    However, almost as soon as I had this whole system working, The Translator informed me that there is another, different movie format in play in the Phantasmagoria engine called ROBOT, with an extension of RBT. Fortunately, enough of the algorithms have been reverse engineered and re-implemented in ScummVM that I was able to sort out enough details for another subtitling project. That will be the subject of a future post.

    See Also :

    The post Subtitling Sierra VMD Files first appeared on Breaking Eggs And Making Omelettes.