changeset 10820:3361ad25093b

8191446: [Linux] Build and deliver the libav media stubs for openjfx build Reviewed-by: kcr
author almatvee
date Thu, 25 Jan 2018 14:40:55 -0800
parents e93e46dabb83
children 305d127c6ed5
files build.gradle gradle.properties.template
diffstat 2 files changed, 342 insertions(+), 4 deletions(-) [+]
line wrap: on
line diff
--- a/build.gradle	Thu Jan 25 11:44:19 2018 -0800
+++ b/build.gradle	Thu Jan 25 14:40:55 2018 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -341,6 +341,9 @@
 defineProperty("javaVersion", javaVersionInfo[0])
 defineProperty("javaBuildNumber", javaVersionInfo[1])
 
+defineProperty("libAVRepositoryURL", "https://libav.org/releases/")
+defineProperty("FFmpegRepositoryURL", "https://www.ffmpeg.org/releases/")
+
 loadProperties("$projectDir/build.properties")
 
 // Look for stub runtime in either JDK or modular-sdk dir layout
@@ -386,6 +389,15 @@
 defineProperty("COMPILE_MEDIA", "false")
 ext.IS_COMPILE_MEDIA = Boolean.parseBoolean(COMPILE_MEDIA)
 
+// BUILD_LIBAV_STUBS specifies whether to download and build libav/ffmpeg libraries
+defineProperty("BUILD_LIBAV_STUBS", "false")
+ext.IS_BUILD_LIBAV_STUBS = IS_LINUX ? Boolean.parseBoolean(BUILD_LIBAV_STUBS) : false
+
+// BUILD_WORKING_LIBAV specifies whether to build libav/ffmpeg libraries with
+// decoder, demuxer, etc. required to run media. Valid only if BUILD_LIBAV_STUBS is true.
+defineProperty("BUILD_WORKING_LIBAV", "false")
+ext.IS_BUILD_WORKING_LIBAV = IS_LINUX ? Boolean.parseBoolean(BUILD_WORKING_LIBAV) : false
+
 // COMPILE_PANGO specifies whether to build javafx_font_pango.
 defineProperty("COMPILE_PANGO", "${IS_LINUX}")
 ext.IS_COMPILE_PANGO = Boolean.parseBoolean(COMPILE_PANGO)
@@ -1493,6 +1505,23 @@
         }
     }
 
+    if (!BUILD_CLOSED && IS_BUILD_LIBAV_STUBS) {
+        repositories {
+            ivy {
+                url libAVRepositoryURL
+                layout "pattern", {
+                    artifact "[artifact].[ext]"
+                }
+            }
+            ivy {
+                url FFmpegRepositoryURL
+                layout "pattern", {
+                    artifact "[artifact].[ext]"
+                }
+            }
+        }
+    }
+
     // We want to configure all projects as java projects and use the same compile settings
     // etc, except for the root project which we just want to ignore (and for now media)
     if (project == rootProject) {
@@ -2934,6 +2963,14 @@
     commonModuleSetup(project, [ 'base', 'graphics', 'media' ])
 
     dependencies {
+        if (IS_BUILD_LIBAV_STUBS) {
+            media name: "libav-0.7.3", ext: "tar.gz"
+            media name: "libav-9.14", ext: "tar.gz"
+            media name: "libav-10.7", ext: "tar.gz"
+            media name: "libav-11.4", ext: "tar.gz"
+            media name: "libav-12.1", ext: "tar.gz"
+            media name: "ffmpeg-3.3.3", ext: "tar.gz"
+        }
     }
 
     compileJava.dependsOn updateCacheIfNeeded
@@ -3071,11 +3108,286 @@
             buildNative.dependsOn buildPlugins
 
             if (t.name == "linux") {
-                def buildAVPlugin = task( "buildAVPlugin", dependsOn: [buildPlugins]) {
+                // Pre-defined command line arguments
+                def cfgCMDArgs = ["sh", "configure"]
+                def commonCfgArgs = ["--enable-shared", "--disable-debug", "--disable-static", "--disable-yasm", "--disable-doc", "--disable-programs", "--disable-everything"]
+                def codecsCfgArgs = ["--enable-decoder=aac,mp3,mp3float,h264", "--enable-parser=aac,h264", "--enable-demuxer=aac,h264,mpegts,mpegtsraw"]
+
+                def copyLibAVStubs = {String fromDir, String toDir ->
+                    FileCollection config = files("config.h")
+                    FileCollection libavcodec = files("avcodec.h", "avfft.h", "dxva2.h", "vaapi.h", "vda.h",
+                                                      "vdpau.h", "version.h", "xvmc.h", "old_codec_ids.h")
+                    FileCollection libavdevice = files("avdevice.h", "version.h")
+                    FileCollection libavfilter = files("avfiltergraph.h", "avfilter.h", "buffersink.h", "buffersrc.h", "version.h");
+                    FileCollection libavformat = files("avformat.h", "avio.h", "version.h")
+                    FileCollection libavresample = files("avresample.h", "version.h")
+                    FileCollection libavutil = files("adler32.h", "blowfish.h", "error.h", "log.h", "pixfmt.h",
+                                                     "aes.h", "bswap.h", "eval.h", "lzo.h", "random_seed.h",
+                                                     "attributes.h", "buffer.h", "fifo.h", "macros.h", "rational.h",
+                                                     "audio_fifo.h", "channel_layout.h", "file.h", "mathematics.h", "samplefmt.h",
+                                                     "avassert.h", "common.h", "frame.h", "md5.h", "sha.h",
+                                                     "avconfig.h", "imgutils.h", "mem.h", "time.h", "avstring.h",
+                                                     "cpu_internal.h", "intfloat.h", "opt.h", "version.h", "avutil.h",
+                                                     "crc.h", "intreadwrite.h", "parseutils.h", "xtea.h", "base64.h",
+                                                     "dict.h", "lfg.h", "pixdesc.h", "intfloat_readwrite.h", "old_pix_fmts.h", "audioconvert.h",
+                                                     "cpu.h")
+                    FileCollection libavutil_x86 = files("cpu.h") // Use cpu.h from x86 instead of libavutil root if exist
+                    FileCollection libswscale = files("swscale.h", "version.h")
+
+                    def copyLibAVFiles = {FileCollection files, String fDir, String tDir ->
+                        File dir = file(tDir)
+                        dir.mkdirs()
+
+                        files.each { File file ->
+                            copy {
+                                from fDir
+                                into tDir
+                                include file.name
+                            }
+                        }
+                    }
+
+                    copyLibAVFiles(config, fromDir, "${toDir}/include")
+                    copyLibAVFiles(libavcodec, "${fromDir}/libavcodec", "${toDir}/include/libavcodec")
+                    copyLibAVFiles(libavdevice, "${fromDir}/libavdevice", "${toDir}/include/libavdevice")
+                    copyLibAVFiles(libavfilter, "${fromDir}/libavfilter", "${toDir}/include/libavfilter")
+                    copyLibAVFiles(libavformat, "${fromDir}/libavformat", "${toDir}/include/libavformat")
+                    copyLibAVFiles(libavresample, "${fromDir}/libavresample", "${toDir}/include/libavresample")
+                    copyLibAVFiles(libavutil, "${fromDir}/libavutil", "${toDir}/include/libavutil")
+                    copyLibAVFiles(libavutil_x86, "${fromDir}/libavutil/x86", "${toDir}/include/libavutil")
+                    copyLibAVFiles(libswscale, "${fromDir}/libswscale", "${toDir}/include/libswscale")
+
+                    // Copy libs
+                    FileTree libs = fileTree(dir: "${fromDir}", include: "**/*.so*")
+                    libs.each {File file ->
+                        copy {
+                            from file
+                            into "${toDir}/lib"
+                        }
+                    }
+                }
+
+                def buildLibAVStubs = task("buildLibAVStubs", dependsOn: []) {
+                    enabled = IS_BUILD_LIBAV_STUBS
+
+                    doLast {
+                        project.ext.libav = [:]
+                        project.ext.libav.basedir = "${buildDir}/native/linux/libav"
+                        project.ext.libav.versions = [ "0.7.3", "9.14", "10.7", "11.4", "12.1" ]
+                        project.ext.libav.versionmap = [ "0.7.3" : "53", "9.14" : "54", "10.7" : "55", "11.4" : "56", "12.1" : "57" ]
+
+                        libav.versions.each { version ->
+                            def libavDir = "${libav.basedir}/libav-${version}"
+                            for (File f : configurations.media.files) {
+                                if (f.name.startsWith("libav-${version}")) {
+                                    File dir = file(libavDir)
+                                    dir.mkdirs()
+                                    def libavTar = "${libav.basedir}/libav-${version}.tar"
+                                    ant.gunzip(src: f, dest: libavTar)
+                                    ant.untar(src: libavTar, dest: libav.basedir)
+                                }
+                            }
+                        }
+
+                        libav.versions.each { version ->
+                            def libavDir = "${libav.basedir}/libav-${version}"
+                            File dir = file(libavDir)
+                            if (dir.exists()) {
+                                def configFile = "${libav.basedir}/libav-${version}/config.h"
+                                File cfgFile = file(configFile)
+                                if (!cfgFile.exists()) {
+                                    // Add execute permissions to version.sh, otherwise build fails
+                                    exec {
+                                        workingDir("$libavDir")
+                                        commandLine("chmod", "+x", "version.sh")
+                                    }
+                                    exec {
+                                        workingDir("$libavDir")
+                                        if (version.equals("0.7.3")) {
+                                            if (IS_BUILD_WORKING_LIBAV) {
+                                                commandLine("sh", "configure", "--enable-shared", "--disable-debug", "--disable-static", "--disable-yasm", "--disable-doc", "--disable-everything", "--disable-mmx", "--disable-mmx2", "--enable-decoder=aac,mp3,mp3float,h264", "--enable-parser=aac,h264", "--enable-demuxer=aac,h264,mpegts,mpegtsraw")
+                                            } else {
+                                                commandLine("sh", "configure", "--enable-shared", "--disable-debug", "--disable-static", "--disable-yasm", "--disable-doc", "--disable-everything", "--disable-mmx", "--disable-mmx2")
+                                            }
+                                        } else {
+                                            if (IS_BUILD_WORKING_LIBAV) {
+                                                commandLine(cfgCMDArgs + commonCfgArgs + codecsCfgArgs)
+                                            } else {
+                                                commandLine(cfgCMDArgs + commonCfgArgs)
+                                            }
+                                        }
+                                    }
+                                }
+                                exec {
+                                    workingDir("$libavDir")
+                                    commandLine("make")
+                                }
+                            }
+                        }
+
+                        libav.versions.each { version ->
+                            def fromDir = "${libav.basedir}/libav-${version}"
+                            def majorVersion = libav.versionmap[version]
+                            def toDir = "${libav.basedir}/libav-${majorVersion}"
+                            copyLibAVStubs(fromDir, toDir)
+                        }
+                    }
+                }
+
+                def buildLibAVFFmpegStubs = task("buildLibAVFFmpegStubs", dependsOn: []) {
+                    enabled = IS_BUILD_LIBAV_STUBS
+
+                    def extraCfgArgs = ["--build-suffix=-ffmpeg"]
+
+                    doLast {
+                        project.ext.libav = [:]
+                        project.ext.libav.basedir = "${buildDir}/native/linux/libavffmpeg"
+                        project.ext.libav.versions = [ "11.4" ]
+                        project.ext.libav.versionmap = [ "11.4" : "56" ]
+
+                        libav.versions.each { version ->
+                            def libavDir = "${libav.basedir}/libav-${version}"
+                            for (File f : configurations.media.files) {
+                                if (f.name.startsWith("libav-${version}")) {
+                                    File dir = file(libavDir)
+                                    dir.mkdirs()
+                                    def libavTar = "${libav.basedir}/libav-${version}.tar"
+                                    ant.gunzip(src: f, dest: libavTar)
+                                    ant.untar(src: libavTar, dest: libav.basedir)
+                                }
+                            }
+                        }
+
+                        libav.versions.each { version ->
+                            def libavDir = "${libav.basedir}/libav-${version}"
+                            File dir = file(libavDir)
+                            if (dir.exists()) {
+                                def configFile = "${libav.basedir}/libav-${version}/config.h"
+                                File cfgFile = file(configFile)
+                                if (!cfgFile.exists()) {
+                                    // Patch *.v files, so we have *_FFMPEG_$MAJOR instead of *_$MAJOR, otherwise library will not be loaded
+                                    FileTree vfiles = fileTree(dir: "${libavDir}", include: "**/*.v")
+                                    vfiles.each {File file ->
+                                        String data = file.getText("UTF-8")
+                                        data = data.replace("_\$MAJOR", "_FFMPEG_\$MAJOR")
+                                        file.write(data, "UTF-8")
+                                    }
+                                    // Add execute permissions to version.sh, otherwise build fails
+                                    exec {
+                                        workingDir("$libavDir")
+                                        commandLine("chmod", "+x", "version.sh")
+                                    }
+                                    exec {
+                                        workingDir("$libavDir")
+                                        if (IS_BUILD_WORKING_LIBAV) {
+                                            commandLine(cfgCMDArgs + commonCfgArgs + codecsCfgArgs + extraCfgArgs)
+                                        } else {
+                                            commandLine(cfgCMDArgs + commonCfgArgs + extraCfgArgs)
+                                        }
+                                    }
+                                }
+                                exec {
+                                    workingDir("$libavDir")
+                                    commandLine("make")
+                                }
+                            }
+                        }
+
+                        libav.versions.each { version ->
+                            def fromDir = "${libav.basedir}/libav-${version}"
+                            def majorVersion = libav.versionmap[version]
+                            def toDir = "${libav.basedir}/libav-${majorVersion}"
+                            copyLibAVStubs(fromDir, toDir)
+
+                            // Special case to copy *-ffmpeg.so to *.so
+                            FileTree libs = fileTree(dir: "${fromDir}", include: "**/*-ffmpeg.so")
+                            libs.each {File file ->
+                                copy {
+                                    from file
+                                    into "${toDir}/lib"
+                                    rename { String fileName ->
+                                        fileName.replace("-ffmpeg", "")
+                                    }
+                                }
+                            }
+                        }
+                    }
+                }
+
+                def buildFFmpegStubs = task("buildFFmpegStubs", dependsOn: []) {
+                    enabled = IS_BUILD_LIBAV_STUBS
+
+                    doLast {
+                        project.ext.libav = [:]
+                        project.ext.libav.basedir = "${buildDir}/native/linux/ffmpeg"
+                        project.ext.libav.versions = [ "3.3.3" ]
+                        project.ext.libav.versionmap = [ "3.3.3" : "57" ]
+
+                        libav.versions.each { version ->
+                            def libavDir = "${libav.basedir}/ffmpeg-${version}"
+                            for (File f : configurations.media.files) {
+                                if (f.name.startsWith("ffmpeg-${version}")) {
+                                    File dir = file(libavDir)
+                                    dir.mkdirs()
+                                    def libavTar = "${libav.basedir}/ffmpeg-${version}.tar"
+                                    ant.gunzip(src: f, dest: libavTar)
+                                    ant.untar(src: libavTar, dest: libav.basedir)
+                                }
+                            }
+                        }
+
+                        libav.versions.each { version ->
+                            def libavDir = "${libav.basedir}/ffmpeg-${version}"
+                            File dir = file(libavDir)
+                            if (dir.exists()) {
+                                def configFile = "${libav.basedir}/ffmpeg-${version}/config.h"
+                                File cfgFile = file(configFile)
+                                if (!cfgFile.exists()) {
+                                    // Add execute permissions to version.sh, otherwise build fails
+                                    exec {
+                                        workingDir("$libavDir")
+                                        commandLine("chmod", "+x", "version.sh")
+                                    }
+                                    exec {
+                                        workingDir("$libavDir")
+                                        if (IS_BUILD_WORKING_LIBAV) {
+                                            commandLine(cfgCMDArgs + commonCfgArgs + codecsCfgArgs)
+                                        } else {
+                                            commandLine(cfgCMDArgs + commonCfgArgs)
+                                        }
+                                    }
+                                }
+                                exec {
+                                    workingDir("$libavDir")
+                                    commandLine("make")
+                                }
+                            }
+                        }
+
+                        libav.versions.each { version ->
+                            def fromDir = "${libav.basedir}/ffmpeg-${version}"
+                            def majorVersion = libav.versionmap[version]
+                            def toDir = "${libav.basedir}/ffmpeg-${majorVersion}"
+                            copyLibAVStubs(fromDir, toDir)
+                        }
+                    }
+                }
+
+                def buildAVPlugin = task( "buildAVPlugin", dependsOn: [buildPlugins, buildLibAVStubs, buildLibAVFFmpegStubs, buildFFmpegStubs]) {
                     enabled = IS_COMPILE_MEDIA
 
                     doLast {
-                        if (project.ext.properties.containsKey("libav")) {
+                        if (IS_BUILD_LIBAV_STUBS) {
+                            project.ext.libav = [:]
+                            project.ext.libav.basedir = "${buildDir}/native/linux/libav/libav"
+                            project.ext.libav.versions = [ "53", "54", "55", "56", "57" ]
+                            project.ext.libav.libavffmpeg = [:]
+                            project.ext.libav.libavffmpeg.basedir = "${buildDir}/native/linux/libavffmpeg/libav"
+                            project.ext.libav.libavffmpeg.versions = [ "56" ]
+                            project.ext.libav.ffmpeg = [:]
+                            project.ext.libav.ffmpeg.basedir = "${buildDir}/native/linux/ffmpeg/ffmpeg"
+                            project.ext.libav.ffmpeg.versions = [ "57" ]
+
                             project.ext.libav.versions.each { version ->
                                 def libavDir = "${project.ext.libav.basedir}-${version}"
                                 File dir = file(libavDir)
@@ -3090,6 +3402,20 @@
                                 }
                             }
 
+                            project.ext.libav.libavffmpeg.versions.each { version ->
+                                def libavDir = "${project.ext.libav.libavffmpeg.basedir}-${version}"
+                                File dir = file(libavDir)
+                                if (dir.exists()) {
+                                    exec {
+                                        commandLine ("make", "${makeJobsFlag}", "-C", "${nativeSrcDir}/gstreamer/projects/linux/avplugin")
+                                        args("CC=${mediaProperties.compiler}", "LINKER=${mediaProperties.linker}",
+                                             "OUTPUT_DIR=${nativeOutputDir}", "BUILD_TYPE=${buildType}",
+                                             "BASE_NAME=avplugin", "VERSION=${version}", "LIBAV_DIR=${libavDir}",
+                                             "SUFFIX=-ffmpeg", IS_64 ? "ARCH=x64" : "ARCH=x32")
+                                    }
+                                }
+                            }
+
                             project.ext.libav.ffmpeg.versions.each { version ->
                                 def libavDir = "${project.ext.libav.ffmpeg.basedir}-${version}"
                                 File dir = file(libavDir)
--- a/gradle.properties.template	Thu Jan 25 11:44:19 2018 -0800
+++ b/gradle.properties.template	Thu Jan 25 14:40:55 2018 -0800
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2013, 2017, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved.
 # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 #
 # This code is free software; you can redistribute it and/or modify it
@@ -45,6 +45,18 @@
 #COMPILE_WEBKIT = true
 #COMPILE_MEDIA = true
 
+# These properties can be used to support building the libav stubs in support of
+# running on multiple Linux systems. BUILD_LIBAV_STUBS is intended to build a
+# distribution that will run on multiple versions of Linux. BUILD_WORKING_LIBAV
+# is only intended for developers to test their code locally without needing an
+# installed libav; most developers will not ever need to use this option.
+# BUILD_LIBAV_STUBS is valid with COMPILE_MEDIA = true and BUILD_WORKING_LIBAV
+# is valid with COMPILE_MEDIA = true and BUILD_LIBAV_STUBS = true on Linux
+# platforms only.
+
+# BUILD_LIBAV_STUBS = true
+# BUILD_WORKING_LIBAV = true
+
 # Specifies whether to include the Null3D pipeline, which can be used for
 # performance debugging.
 # Uncomment this flag in order to include the Null3D pipeline in the build.