From: Not Zed Date: Fri, 17 Jun 2022 09:44:29 +0000 (+0930) Subject: Initial cut of jdk.foreign implementation. X-Git-Url: https://code.zedzone.au/cvs?a=commitdiff_plain;h=9e51acd2baa89753b3206358fa811cec8fa0bc66;p=jjmpeg Initial cut of jdk.foreign implementation. --- diff --git a/Makefile b/Makefile index cbaada0..562a130 100644 --- a/Makefile +++ b/Makefile @@ -10,7 +10,7 @@ dist_EXTRA=README TODO \ include config.make -java_MODULES=notzed.jjmpeg notzed.jjmpeg.fx notzed.jjmpeg.awt notzed.jjmpeg.demo +java_MODULES=notzed.jjmpeg #notzed.jjmpeg.fx notzed.jjmpeg.awt notzed.jjmpeg.demo notzed.jjmpeg.awt_JDEPMOD=notzed.jjmpeg notzed.jjmpeg.fx_JDEPMOD=notzed.jjmpeg diff --git a/java.make b/java.make index ee876b1..c3b9030 100644 --- a/java.make +++ b/java.make @@ -1,5 +1,5 @@ # -# Copyright (C) 2019 Michael Zucchi +# Copyright (C) 2019,2022 Michael Zucchi # # This is the copyright for java.make # @@ -31,6 +31,9 @@ # generators must exist in src//gen. Native # libraries must exist in src//jni. +# native_MODULES list of native-only "modules". + + # Global variables # JAVA_HOME location of jdk. @@ -40,6 +43,7 @@ # JARFLAGS jar flags # JMOD jmod command. # JMODFLAGS jmod flags. +# JAVAFLAGS java flags for run targets # Module specific variables @@ -49,9 +53,12 @@ # _JARFLAGS # _JMODFLAGS +# all paths are relative to the root package name + # _JAVA Java sources. If not set it is found from src//classes/(*.java) # _RESOURCES .jar resources. If not set it is found from src//classes/(not *.java) -# _JAVA_GENERATED Java generated sources. These must be relative to the package name. +# _JAVA_GENERATED Java generated sources. +# _RESOURCES_GENERATED Java generated sources. # Variables for use in fragments @@ -59,7 +66,6 @@ # _gendir Location for files used in Java generation process (per project). # _genjavadir Location where _JAVA_GENERATED .java files will be created (per project). -# _jnidir Location for jni generated files (per target). # _objdir Location for c objects (per target). # _incdir Location for output includes, .jmod staging. # _libdir Location for output libraries, .jmod staging. May point to _bindir. @@ -73,7 +79,7 @@ # These are compiled after the java sources have been compiled as that # process also generates any native binding headers. -# _JNI_LIBRARIES list of libraries to build. +# _NATIVE_LIBRARIES list of libraries to build. # library names match System.loadLibrary(). # Global variables @@ -82,6 +88,9 @@ # _LDLIBS # _CPPFLAGS # _CFLAGS +# _CC +# _CXXFLAGS +# _CXX # SO shared library suffix # LIB shared library prefix @@ -91,22 +100,21 @@ # Per library variables. -# _SOURCES .c, .cc, .C - source files for library. Paths are relative to src//jni. -# _HEADERS header files for jmod -# _COMMANDS commands/bin/scripts for jmod +# _SOURCES .c source files for library. Paths are relative to src//native. +# _CXXSOURCES .c source files for library. Paths are relative to src//native. +# _HEADERS header files for install/jmod +# _COMMANDS commands/bin/scripts for install/jmod # _LDFLAGS link flags # _LIBADD extra objects to add to link line # _LDLIBS link libraries -# _CPPFLAGS c pre-processor flags. "-Isrc//jni -Ibin/include/" is implicit. +# _CPPFLAGS c and c++ pre-processor flags. "-Isrc//jni -Ibin/include/" is implicit. # _CCFLAGS c compiler flags +# _CXXFLAGS c++ compiler flags # _DEPENDENCIES A list of other objects on which this library depends before linking. -# _DEFS A list of .def files for nativez-gen. -# _DEFSFLAGS Flags for nativez-gen invocation. - -# .c files have dependencies automatically generated +# .c and .cc files have dependencies automatically generated # Targets # ------- @@ -115,7 +123,6 @@ # make clean rm -rf bin # make dist create dist tar in bin/ # make | make jar make all jars and jmods -# make bin make everything but jars and mods # Outputs # ------- @@ -146,30 +153,29 @@ # ###################################################################### +all_MODULES = $(java_MODULES) $(native_MODULES) + E:= S:=$(E) $(E) - -# All modules with native code -java_JMODS=$(foreach module,$(java_MODULES),$(if $(wildcard src/$(module)/jni/jni.make),$(module))) -# Only modules with no native code -java_JARS=$(foreach module,$(java_MODULES),$(if $(wildcard src/$(module)/jni/jni.make),,$(module))) -# Modules with generated java source -java_JGEN=$(foreach module,$(java_MODULES),$(if $(wildcard src/$(module)/gen/gen.make),$(module))) +SO=$($(TARGET)_SO) +LIB=$($(TARGET)_LIB) # Define some useful variables before including fragments +define common_variables= +$1_gendir:=bin/gen/$1/gen +$1_genjavadir:=bin/gen/$1/classes +$1_objdir:=bin/$1/$(TARGET)/obj +$1_incdir:=bin/$1/$(TARGET)/include +$1_libdir:=$$(if $$(filter windows-%,$(TARGET)),bin/$1/$(TARGET)/bin,bin/$1/$(TARGET)/lib) +$1_bindir:=bin/$1/$(TARGET)/bin +endef + define java_variables= -$(1)_gendir:=bin/gen/$(1)/gen -$(1)_genjavadir:=bin/gen/$(1)/classes -$(1)_jnidir:=bin/$(1)/$(TARGET)/jni -$(1)_objdir:=bin/$(1)/$(TARGET)/obj -$(1)_incdir:=bin/$(1)/$(TARGET)/include -$(1)_libdir:=$$(if $$(filter windows-%,$(TARGET)),bin/$(1)/$(TARGET)/bin,bin/$(1)/$(TARGET)/lib) -$(1)_bindir:=bin/$(1)/$(TARGET)/bin -ifndef $(1)_JAVA -$(1)_JAVA := $$(shell find src/$(1)/classes -type f -name '*.java') +ifndef $1_JAVA +$1_JAVA := $$(shell cd src/$1/classes && find * -type f -name '*.java') endif -ifndef $(1)_RESOURCES -$(1)_RESOURCES := $$(shell find src/$(1)/classes -type f \! -name '*.java') +ifndef $1_RESOURCES +$1_RESOURCES := $$(shell cd src/$1/classes && find * -type f \! -name '*.java') endif endef @@ -179,45 +185,117 @@ java_jardir:=bin/$(TARGET)/lib java_incdir:=bin/$(TARGET)/include java_jmoddir:=bin/$(TARGET)/jmods +$(foreach module,$(java_MODULES) $(native_MODULES),$(eval $(call common_variables,$(module)))) $(foreach module,$(java_MODULES),$(eval $(call java_variables,$(module)))) # ###################################################################### -all: jar -bin: +all: +jar: gen: -.PHONY: all clean jar bin gen +.PHONY: all clean jar gen $(java_MODULES) clean: rm -rf bin -include $(patsubst %,src/%/gen/gen.make,$(java_JGEN)) -include $(patsubst %,src/%/jni/jni.make,$(java_JMODS)) +# Gen is things that go into the jar (sources and resources) +include $(wildcard $(all_MODULES:%=src/%/gen/gen.make)) +# Native is things that go into the sdk/jmod +include $(wildcard $(all_MODULES:%=src/%/native/native.make)) + +# ###################################################################### + +# create module depencies +# variables: +# _sdk is the target location of an expanded 'sdk' for this module +# it resides in a common location bin// +# _jmod is the target location of a staging area for jmod files +# is resides in a per-module lcoation bin/// +# _java is all the targets that will cause the invocation of javac +# it includes the module source, generated sources, and sentinals for generated sources + +# targets: +# bin/status/.depjava marks all source/generated sources are ready/updated +# bin/status/.depjar all compiled class files and resources are ready/updated +# bin/status/.sdk all files are available in bin/ as if it was an installed image + +define module_vars= +$1_sdk := $(addprefix $(java_bindir)/,$($1_COMMANDS)) $(addprefix $(java_libdir)/,$($1_LIBRARIES)) $($1_NATIVE_LIBRARIES:%=$(java_libdir)/lib%.so) +$1_jmod := $(addprefix $($1_bindir)/,$($1_COMMANDS)) $(addprefix $($1_libdir)/,$($1_LIBRARIES)) $($1_NATIVE_LIBRARIES:%=$($1_libdir)/lib%.so) +$1_java :=$($1_JAVA:%=src/$1/classes/%) $($1_JAVA_GENERATED:%=$($1_genjavadir)/%) +$1_resources:= $($1_RESOURCES:%=src/$1/classes/%) $($1_RESOURCES_GENERATED:%=$($1_genjavadir)/%) +$1_depjava := $($1_API:%=bin/status/$1-%.export) $(patsubst %,bin/status/%.classes, $(filter $($1_JDEPMOD),$(java_MODULES))) + +ifneq ("$$(strip $$($1_java) $$($1_depjava))", "") +bin/status/$1.depjava: $$($1_java) $$($1_depjava) + @install -d $$(@D) + touch $$@ +bin/status/$1.depjar: bin/status/$1.classes $$($1_resources) + @install -d $$(@D) + touch $$@ +bin/status/$1.depmod: bin/status/$1.classes $$($1_resources) $$($1_jmod) + @install -d $$(@D) + touch $$@ +bin/status/$1.sdk: $(java_jardir)/$1.jar +jar: $(java_jardir)/$1.jar +gen: bin/status/$1.depjava +$1 all: $(java_jardir)/$1.jar $(java_jmoddir)/$1.jmod +else +# acutally not sure here? +$1 all: bin/status/$1.sdk +endif + +$1-sdk sdk: bin/status/$1.sdk + +bin/status/$1.sdk: $$($1_sdk) $$($1_jmod) + @install -d $$(@D) + touch $$@ + +endef + +#$(foreach m,$(all_MODULES),$(info $(call module_vars,$m))) +$(foreach m,$(all_MODULES),$(eval $(call module_vars,$m))) + +# ###################################################################### +# notzed.nativez export-api +# ###################################################################### + +define api_targets= +bin/status/$1-$2.export: src/$1/gen/$2.api src/$1/gen/$2.h +bin/status/$1-$2.export: + mkdir -p bin/gen/$1/gen bin/status + $(NATIVEZ_HOME)/bin/export-api \ + -w bin/gen/$1/gen -d bin/gen/$1/classes $($1_APIFLAGS) $($1_$2_APIFLAGS) src/$1/gen/$2.api + touch $$@ + +bin/status/$1-$2.export.d: + @$(NATIVEZ_HOME)/bin/export-api -M -MT "$$(@:.d=) $$@" -MF $$@ \ + -w bin/gen/$1/gen -d bin/gen/$1/classes $($1_APIFLAGS) $($1_$2_APIFLAGS) src/$1/gen/$2.api 2>/dev/null + +$(if $(filter clean dist gen,$(MAKECMDGOALS)),,-include bin/status/$1-$2.export.d) +endef + +$(foreach m,$(all_MODULES),$(foreach a,$($m_API),$(eval $(call api_targets,$m,$a)))) # ###################################################################### # Java # ###################################################################### +# Build targets for java modules + define java_targets= -# Rules for module $(1) -$(1)_JAVA_generated = $$(addprefix $$($(1)_genjavadir)/,$$($(1)_JAVA_GENERATED)) - -bin/status/$(1).data: $$($(1)_RESOURCES) -bin/status/$(1).classes: $(patsubst %,bin/status/%.classes,$($(1)_JDEPMOD)) $$($(1)_JAVA) $$($(1)_JAVA_generated) -jar $(1): $(java_jardir)/$(1).jar $(java_jmoddir)/$(1).jmod -bin: bin/status/$(1).classes bin/status/$(1).data -sources: $(java_jardir)/$(1)-sources.zip -gen: $$($(1)_JAVA_generated) - -# Create modular jar -$(java_jardir)/$(1).jar: bin/status/$(1).classes bin/status/$(1).data + +# Create (modular) jar +$(java_jardir)/$1.jar: bin/status/$1.depjar @install -d $$(@D) $(JAR) cf $$@ \ $(JARFLAGS) $$($(1)_JARFLAGS) \ - -C bin/modules/$(1) . + -C bin/modules/$(1) . \ + $(if $($1_RESOURCES),$($1_RESOURCES:%=-C src/$1/classes %)) \ + $(if $($1_RESOURCES_GENERATED),$($1_RESOURCES_GENERATED:%=-C bin/gen/$1/classes %)) # Create a jmod -$(java_jmoddir)/$(1).jmod: bin/status/$(1).classes bin/status/$(1).data +$(java_jmoddir)/$1.jmod: bin/status/$1.depmod rm -f $$@ @install -d $$(@D) $$(JMOD) create \ @@ -231,113 +309,108 @@ $(java_jmoddir)/$(1).jmod: bin/status/$(1).classes bin/status/$(1).data $$@ # Create an IDE source zip, paths have to match --module-source-path -$(java_jardir)/$(1)-sources.zip: bin/status/$(1).classes +$(java_jardir)/$1-sources.zip: bin/status/$1.depjar @install -d $$(@D) - jar -c -f $$@ -M \ - $$(patsubst src/$(1)/classes/%,-C src/$(1)/classes %,$$(filter src/$(1)/classes/%,$$($(1)_JAVA))) \ - $$(patsubst bin/gen/$(1)/classes/%,-C bin/gen/$(1)/classes %,$$(filter bin/gen/$(1)/classes/%,$$($(1)_JAVA))) - -endef + $(JAR) -c -f $$@ -M \ + $$($1_JAVA:%=-C src/$1/classes %) \ + $$($1_JAVA_GENERATED:%=-C bin/gen/$1/classes %) -#$(foreach module,$(java_MODULES),$(info $(call java_targets,$(module)))) -$(foreach module,$(java_MODULES),$(eval $(call java_targets,$(module)))) +# resources +bin/modules/$1/%: src/$1/classes/% + install -vD $$< $$@ -# ###################################################################### -# Global pattern rules - -# Stage resources -bin/status/%.data: - @install -d $(@D) - for data in $(patsubst src/$*/classes/%,"%",$($*_RESOURCES)) ; do \ - install -vDC "src/$*/classes/$$data" "bin/modules/$*/$$data" || exit 1 ; \ - done - touch $@ - -# Compile one module. This only updates (javac -h) headers if they changed. -bin/status/%.classes: - @install -d $(@D) +# Compile module. +bin/status/$1.classes: bin/status/$1.depjava + @install -d $$(@D) $(JAVAC) \ --module-source-path "src/*/classes:bin/gen/*/classes" \ $(if $(JAVAMODPATH),--module-path $(subst $(S),:,$(JAVAMODPATH))) \ - $(JAVACFLAGS) $($*_JAVACFLAGS) \ - -h bin/inc \ + $(JAVACFLAGS) $($1_JAVACFLAGS) \ -d bin/modules \ - -m $* \ - $($*_JAVA) $($*_JAVA_generated) - if [ -d bin/inc/$* ] ; then \ - install -DC -t bin/include/$* bin/inc/$*/*.h ; \ - fi - touch $@ + -m $1 \ + $$($1_JAVA:%=src/$1/classes/%) \ + $$($1_JAVA_GENERATED:%=bin/gen/$1/classes/%) + touch $$@ +endef + +#$(foreach module,$(java_MODULES),$(info $(call java_targets,$(module)))) +$(foreach module,$(java_MODULES),$(eval $(call java_targets,$(module)))) -# ###################################################################### -# C stuff # ###################################################################### -SUFFIXES=.c .C .cc -SO=$($(TARGET)_SO) -LIB=$($(TARGET)_LIB) +# setup run-* targets +define run_targets= +run-$1/$2: bin/status/$1.sdk $($1_JDEPMOD:%=bin/status/%.sdk) + LD_LIBRARY_PATH=$(FFMPEG_HOME)/lib \ + $(JAVA) \ + $(if $(strip $(JAVAMODPATH) $($1_JAVAMODPATH)),--module-path $(subst $(S),:,$(strip $(JAVAMODPATH) $($1_JAVAMODPATH)))) \ + $(JMAINFLAGS) $($1_JMAINFLAGS) \ + -m $1/$2 \ + $(ARGV) +.PHONY: run-$1/$2 +endef -# functions to find cross-module stuff $(call library-path,modname,libname) -library-path=$($(1)_libdir)/$(LIB)$(2)$(SO) -library-dir=$($(1)_libdir)/ +#$(foreach module,$(java_MODULES),$(foreach main,$($(module)_JMAIN),$(info $(call run_targets,$(module),$(main))))) +$(foreach module,$(java_MODULES),$(foreach main,$($(module)_JMAIN),$(eval $(call run_targets,$(module),$(main))))) -define jni_library= -# Rule for library $(2) in module $(1) -$(2)_OBJS = $(foreach sx,$(SUFFIXES),$(patsubst %$(sx), $($(1)_objdir)/%.o, $(filter %$(sx),$($(2)_SOURCES)))) -$(2)_SRCS = $(addprefix src/$(1)/jni/,$($(2)_SOURCES)) -$(2)_SO = $($(1)_libdir)/$(LIB)$(2)$(SO) +# ###################################################################### +# C and c++ native library support +# ###################################################################### -$($(1)_libdir)/$(LIB)$(2)$(SO): $$($(2)_OBJS) $($(2)_LIBADD) $($(2)_DEPENDENCIES) - @install -d $$(@D) - $($(TARGET)_CC) -o $$@ -shared \ - $($(TARGET)_LDFLAGS) $($(2)_LDFLAGS) $$($(2)_OBJS) $($(2)_LIBADD) $($(TARGET)_LDLIBS) $($(2)_LDLIBS) +define native_library= +# Rule for library $$2 in module $$1 +$2_OBJS = $(patsubst %.c, $($1_objdir)/%.o, $($2_SOURCES)) \ + $(patsubst %.cc, $($1_objdir)/%.o, $($2_CXXSOURCES)) +$2_SRCS = $(addprefix src/$1/native/,$($2_SOURCES)) +$2_SO = $($1_libdir)/$(LIB)$2$(SO) +# Copy anything from staging area for jmods bin/module//* to sdk area bin//* $(java_libdir)/%: $($(1)_libdir)/% - install -DC $$< $$@ + @install -d $$(@D) + ln -fs $$(abspath $$<) $$@ $(java_bindir)/%: $($(1)_bindir)/% - install -DC $$< $$@ + @install -d $$(@D) + ln -fs $$(abspath $$<) $$@ $(java_incdir)/%: $($(1)_incdir)/% - install -DC $$< $$@ + @install -d $$(@D) + ln -fs $$(abspath $$<) $$@ -$($(1)_objdir)/%.o: src/$(1)/jni/%.c +$($1_libdir)/$(LIB)$2$(SO): $$($2_OBJS) $($2_LIBADD) $($2_DEPENDENCIES) @install -d $$(@D) - $($(TARGET)_CC) -Isrc/$(1)/jni -Ibin/include/$(1) -I$($(1)_jnidir) \ - $($(TARGET)_CPPFLAGS) $($(2)_CPPFLAGS) \ - $($(TARGET)_CFLAGS) $($(2)_CFLAGS) -c -o $$@ $$< + $($(TARGET)_CC) -o $$@ -shared \ + $($(TARGET)_LDFLAGS) $($2_LDFLAGS) $$($2_OBJS) $($2_LIBADD) $($(TARGET)_LDLIBS) $($2_LDLIBS) -$($(1)_incdir)/%.h: src/$(1)/jni/%.h - install -DC $$< $$@ +$($1_objdir)/%.o: src/$1/native/%.c + @install -d $$(@D) + $($(TARGET)_CC) -Isrc/$1/native -Ibin/include/$1 \ + $($(TARGET)_CPPFLAGS) $($2_CPPFLAGS) \ + $($(TARGET)_CFLAGS) $($2_CFLAGS) -c -o $$@ $$< + +$($1_objdir)/%.o: src/$1/native/%.cc + @install -d $$(@D) + $($(TARGET)_CXX) -Isrc/$1/native -Ibin/include/$1 \ + $($(TARGET)_CPPFLAGS) $($2_CPPFLAGS) \ + $($(TARGET)_CXXFLAGS) $($2_CXXFLAGS) -c -o $$@ $$< # auto-dependencies for c files -$($(1)_objdir)/%.d: src/$(1)/jni/%.c bin/status/$(1).classes +$($1_objdir)/%.d: src/$1/native/%.c @install -d $$(@D) @rm -f $$@ - @$($(TARGET)_CC) -MM -MT "bin/$(1)/$(TARGET)/obj/$$*.o" -Isrc/$(1)/jni -Ibin/include/$(1) \ - $($(TARGET)_CPPFLAGS) $($(2)_CPPFLAGS) $$< -o $$@.d 2>/dev/null - @sed 's,\($$*\.o\) *:,\1 $$@ : ,g' $$@.d > $$@ ; rm $$@.d + @$($(TARGET)_CC) -MM -MT "$$(@:.d=.o) $$@" -Isrc/$1/jni -Ibin/include/$1 \ + $($(TARGET)_CPPFLAGS) $($2_CPPFLAGS) $$< -o $$@ 2>/dev/null -# .def files for nativez mapping -$($(1)_jnidir)/%.h: src/$(1)/jni/%.def +# auto-dependencies for c++ files +$($1_objdir)/%.d: src/$1/native/%.cc @install -d $$(@D) - $(NATIVEZ_HOME)/bin/nativez-gen -J $($(2)_DEFSFLAGS) $$< > $$@ || ( rm $$@ ; exit 1) - -bin jni $(1) $(java_jmoddir)/$(1).jmod: \ - $($(1)_libdir)/$(LIB)$(2)$(SO) \ - $(java_libdir)/$(LIB)$(2)$(SO) \ - $(addprefix $($(1)_incdir)/,$($(2)_HEADERS)) \ - $(addprefix $(java_incdir)/,$($(2)_HEADERS)) \ - $(addprefix $($(1)_bindir)/,$($(2)_COMMANDS)) \ - $(addprefix $(java_bindir)/,$($(2)_COMMANDS)) \ - $(addprefix $($(1)_libdir)/,$($(2)_LIBRARIES)) - -$(if $(filter clean dist gen,$(MAKECMDGOALS)),,-include $$($(2)_OBJS:.o=.d)) -endef + @rm -f $$@ + @$($(TARGET)_CXX) -MM -MT "$$(@:.d=.o) $$@" -Isrc/$1/jni -Ibin/include/$1 \ + $($(TARGET)_CPPFLAGS) $($2_CPPFLAGS) $$< -o $$@ 2>/dev/null -#$(foreach module,$(java_JMODS),$(foreach library,$($(module)_JNI_LIBRARIES),$(info $(call jni_library,$(module),$(library))))) -$(foreach module,$(java_JMODS),$(foreach library,$($(module)_JNI_LIBRARIES),$(eval $(call jni_library,$(module),$(library))))) +$(if $(filter clean dist gen,$(MAKECMDGOALS)),,-include $$($2_OBJS:.o=.d)) +endef -#$(foreach module,$(java_JMODS),$(foreach library,$($(module)_JNI_LIBRARIES),$(foreach def,$($(library)_DEFS),$(info $($(module)_objdir)/$(def:.def=.o): $($(module)_jnidir)/$(def:.def=.h))))) -$(foreach module,$(java_JMODS),$(foreach library,$($(module)_JNI_LIBRARIES),$(foreach def,$($(library)_DEFS),$(eval $($(module)_objdir)/$(def:.def=.o): $($(module)_jnidir)/$(def:.def=.h))))) +#$(foreach module,$(all_MODULES),$(foreach library,$($(module)_NATIVE_LIBRARIES),$(info $(call native_library,$(module),$(library))))) +$(foreach module,$(all_MODULES),$(foreach library,$($(module)_NATIVE_LIBRARIES),$(eval $(call native_library,$(module),$(library))))) # ###################################################################### @@ -345,6 +418,5 @@ dist: @install -d bin tar cfz bin/$(dist_NAME)-$(dist_VERSION).tar.gz \ --transform=s,^,$(dist_NAME)-$(dist_VERSION)/, \ - config.make java.make Makefile src \ + config.make.in java.make Makefile src \ $(dist_EXTRA) - diff --git a/nbproject/project.properties b/nbproject/project.properties index 03af6c8..85cea14 100644 --- a/nbproject/project.properties +++ b/nbproject/project.properties @@ -49,8 +49,8 @@ javac.modulepath=\ javac.processormodulepath= javac.processorpath=\ ${javac.classpath} -javac.source=13 -javac.target=13 +javac.source=18 +javac.target=18 javac.test.classpath=\ ${javac.classpath} javac.test.modulepath=\ @@ -77,13 +77,14 @@ jlink.additionalparam= jlink.launcher=true jlink.launcher.name=notzed.jjmpeg platform.active=default_platform +project.license=gpl3-notzed project.notzed_nativez=../nativez reference.notzed_nativez.notzed_nativez_jar=${project.notzed_nativez}/dist/notzed.nativez.jar run.classpath= # Space-separated list of JVM arguments used when running the project. # You may also define separate properties like run-sys-prop.name=value instead of -Dname=value. # To set system properties for unit tests define test-sys-prop.name=value: -run.jvmargs=-Djava.library.path=bin/notzed.jjmpeg/linux-amd64/lib:../nativez/bin/notzed.nativez/linux-amd64/lib +run.jvmargs=--enable-native-access notzed.nativez,notzed.jjmpeg run.modulepath=\ ${javac.modulepath}:\ ${build.modules.dir} diff --git a/src/notzed.jjmpeg.awt/classes/au/notzed/jjmpeg/awt/JavaPixelReader.java b/src/notzed.jjmpeg.awt/classes/au/notzed/jjmpeg/awt/JavaPixelReader.java index 0f7c470..8912e39 100644 --- a/src/notzed.jjmpeg.awt/classes/au/notzed/jjmpeg/awt/JavaPixelReader.java +++ b/src/notzed.jjmpeg.awt/classes/au/notzed/jjmpeg/awt/JavaPixelReader.java @@ -47,7 +47,7 @@ public class JavaPixelReader implements AVPixelReader { case BufferedImage.TYPE_BYTE_GRAY: return AVPixelFormat.AV_PIX_FMT_GRAY8; case BufferedImage.TYPE_USHORT_GRAY: - return AVPixelFormat.AV_PIX_FMT_GRAY16; + return AVPixelFormat.AV_PIX_FMT_GRAY16LE; case BufferedImage.TYPE_INT_BGR: return AVPixelFormat.AV_PIX_FMT_RGBA; case BufferedImage.TYPE_INT_ARGB: diff --git a/src/notzed.jjmpeg.awt/classes/au/notzed/jjmpeg/awt/JavaPixelWriter.java b/src/notzed.jjmpeg.awt/classes/au/notzed/jjmpeg/awt/JavaPixelWriter.java index 97fd45b..bda8ff6 100644 --- a/src/notzed.jjmpeg.awt/classes/au/notzed/jjmpeg/awt/JavaPixelWriter.java +++ b/src/notzed.jjmpeg.awt/classes/au/notzed/jjmpeg/awt/JavaPixelWriter.java @@ -44,7 +44,7 @@ public class JavaPixelWriter implements AVPixelWriter { case BufferedImage.TYPE_BYTE_GRAY: return AVPixelFormat.AV_PIX_FMT_GRAY8; case BufferedImage.TYPE_USHORT_GRAY: - return AVPixelFormat.AV_PIX_FMT_GRAY16; + return AVPixelFormat.AV_PIX_FMT_GRAY16LE; case BufferedImage.TYPE_INT_BGR: return AVPixelFormat.AV_PIX_FMT_RGBA; case BufferedImage.TYPE_INT_ARGB: diff --git a/src/notzed.jjmpeg.demo/classes/au/notzed/jjmpeg/demo/audio/AudioPlay.java b/src/notzed.jjmpeg.demo/classes/au/notzed/jjmpeg/demo/audio/AudioPlay.java index 6c315a5..4dde1ab 100644 --- a/src/notzed.jjmpeg.demo/classes/au/notzed/jjmpeg/demo/audio/AudioPlay.java +++ b/src/notzed.jjmpeg.demo/classes/au/notzed/jjmpeg/demo/audio/AudioPlay.java @@ -30,6 +30,7 @@ import javax.sound.sampled.AudioFormat; import javax.sound.sampled.AudioSystem; import javax.sound.sampled.LineUnavailableException; import javax.sound.sampled.SourceDataLine; +import jdk.incubator.foreign.ResourceScope; /** * Plays audio files. @@ -102,7 +103,8 @@ public class AudioPlay { return; } - try (JJMediaReader mr = new JJMediaReader(path)) { + try (ResourceScope scope = ResourceScope.newConfinedScope(); + JJMediaReader mr = new JJMediaReader(path, scope)) { JJMediaReader.JJReaderAudio as = mr.openDefaultStream(JJMediaReader.TYPE_AUDIO); if (as == null) @@ -118,7 +120,7 @@ public class AudioPlay { int dstChannels = AVChannelLayout.getNumChannels(dstLayout); int dstSampleSize = ((outputBits + 7) >> 3) * dstChannels; - AVSampleReader sampleReader = as.getFrame().getSampleReader( + AVSampleReader sampleReader = as.getFrame().createSampleReader( dstLayout, dstFormat, dstRate); AudioFormat format = new AudioFormat( dstEncoding, dstRate, outputBits, dstChannels, dstSampleSize, dstRate, false); diff --git a/src/notzed.jjmpeg.demo/classes/au/notzed/jjmpeg/demo/video/VideoExport.java b/src/notzed.jjmpeg.demo/classes/au/notzed/jjmpeg/demo/video/VideoExport.java index a65705a..6da1a07 100644 --- a/src/notzed.jjmpeg.demo/classes/au/notzed/jjmpeg/demo/video/VideoExport.java +++ b/src/notzed.jjmpeg.demo/classes/au/notzed/jjmpeg/demo/video/VideoExport.java @@ -26,6 +26,7 @@ import java.io.File; import java.io.IOException; import java.util.IllegalFormatException; import javax.imageio.ImageIO; +import jdk.incubator.foreign.ResourceScope; /** * Export a video as frames. @@ -68,13 +69,14 @@ public class VideoExport { System.err.println("Format invalid"); System.exit(1); } - + int dot = format.lastIndexOf('.'); if (dot == -1) System.err.println("Unknown extension"); type = format.substring(dot + 1).toLowerCase(); - try (JJMediaReader mr = new JJMediaReader(path)) { + try (ResourceScope scope = ResourceScope.newConfinedScope(); + JJMediaReader mr = new JJMediaReader(path, scope)) { int index = 0; JJMediaReader.JJReaderVideo vs = mr.openDefaultStream(JJMediaReader.TYPE_VIDEO); @@ -84,17 +86,17 @@ public class VideoExport { int width = vs.getWidth(); int height = vs.getHeight(); BufferedImage image; - JavaPixelReader frameReader = new JavaPixelReader(vs.getFrame().getPixelReader(width, height, 0)); + JavaPixelReader frameReader = new JavaPixelReader(vs.getFrame().createPixelReader(width, height, 0)); // Handle greyscale and high-bit greyscale specifically. switch (vs.getPixelFormat()) { case AVPixelFormat.AV_PIX_FMT_GRAY8: image = new BufferedImage(width, height, BufferedImage.TYPE_BYTE_GRAY); break; - case AVPixelFormat.AV_PIX_FMT_GRAY16: - case AVPixelFormat.AV_PIX_FMT_GRAY9: - case AVPixelFormat.AV_PIX_FMT_GRAY10: - case AVPixelFormat.AV_PIX_FMT_GRAY12: + case AVPixelFormat.AV_PIX_FMT_GRAY16LE: + case AVPixelFormat.AV_PIX_FMT_GRAY9LE: + case AVPixelFormat.AV_PIX_FMT_GRAY10LE: + case AVPixelFormat.AV_PIX_FMT_GRAY12LE: image = new BufferedImage(width, height, BufferedImage.TYPE_USHORT_GRAY); break; default: diff --git a/src/notzed.jjmpeg.demo/classes/au/notzed/jjmpeg/demo/video/VideoPlay.java b/src/notzed.jjmpeg.demo/classes/au/notzed/jjmpeg/demo/video/VideoPlay.java index 026f536..0a7e416 100644 --- a/src/notzed.jjmpeg.demo/classes/au/notzed/jjmpeg/demo/video/VideoPlay.java +++ b/src/notzed.jjmpeg.demo/classes/au/notzed/jjmpeg/demo/video/VideoPlay.java @@ -19,6 +19,7 @@ package au.notzed.jjmpeg.demo.video; import au.notzed.jjmpeg.AVIOException; +import au.notzed.jjmpeg.AVObject; import au.notzed.jjmpeg.fx.FXPixelReader; import au.notzed.jjmpeg.io.JJMediaReader; import java.io.File; @@ -56,6 +57,7 @@ import javafx.scene.transform.Translate; import javafx.stage.FileChooser; import javafx.stage.Screen; import javafx.stage.Stage; +import jdk.incubator.foreign.ResourceScope; /** * A simple JavaFX demo which plays a video. @@ -111,7 +113,7 @@ public class VideoPlay extends Application { void videoReady(JJMediaReader.JJReaderVideo vs) { width = vs.getWidth(); height = vs.getHeight(); - frameReader = new FXPixelReader(vs.getFrame().getPixelReader(width, height, 0)); + frameReader = new FXPixelReader(vs.getFrame().createPixelReader(width, height, 0)); time = DateTimeFormatter.ofPattern("HH:mm:ss.SSS"); @@ -176,7 +178,7 @@ public class VideoPlay extends Application { ap.heightProperty().addListener(fitVideo); fitVideo.invalidated(null); - scene.getAccelerators().put(new KeyCodeCombination(KeyCode.Q), () -> { + scene.getAccelerators().put(new KeyCodeCombination(KeyCode.ESCAPE), () -> { cancel = true; stage.close(); }); @@ -250,7 +252,8 @@ public class VideoPlay extends Application { * @param path */ void reader(String path) { - try (JJMediaReader mr = new JJMediaReader(path)) { + try (ResourceScope scope = ResourceScope.newConfinedScope(); + JJMediaReader mr = new JJMediaReader(path, scope)) { JJMediaReader.JJReaderVideo vs = mr.openDefaultStream(JJMediaReader.TYPE_VIDEO); if (vs != null) { @@ -266,10 +269,14 @@ public class VideoPlay extends Application { } catch (AVIOException | FileNotFoundException ex) { ex.printStackTrace(); videoError(ex); + } catch (Throwable t) { + t.printStackTrace(); + Platform.exit(); } } public static void main(String[] args) { + AVObject.init(); launch(args); } } diff --git a/src/notzed.jjmpeg.demo/classes/au/notzed/jjmpeg/demo/video/VideoScan.java b/src/notzed.jjmpeg.demo/classes/au/notzed/jjmpeg/demo/video/VideoScan.java index f518b03..82e78fe 100644 --- a/src/notzed.jjmpeg.demo/classes/au/notzed/jjmpeg/demo/video/VideoScan.java +++ b/src/notzed.jjmpeg.demo/classes/au/notzed/jjmpeg/demo/video/VideoScan.java @@ -21,6 +21,7 @@ package au.notzed.jjmpeg.demo.video; import au.notzed.jjmpeg.AVPixelFormat; import au.notzed.jjmpeg.io.JJMediaReader; import java.io.IOException; +import jdk.incubator.foreign.ResourceScope; /** * A simple video scanner. @@ -38,7 +39,8 @@ public class VideoScan { String path = args[0]; - try (JJMediaReader mr = new JJMediaReader(path)) { + try (ResourceScope scope = ResourceScope.newConfinedScope(); + JJMediaReader mr = new JJMediaReader(path, scope)) { int count = 0; JJMediaReader.JJReaderVideo vs = mr.openDefaultStream(JJMediaReader.TYPE_VIDEO); diff --git a/src/notzed.jjmpeg.fx/classes/au/notzed/jjmpeg/fx/FXPixelReader.java b/src/notzed.jjmpeg.fx/classes/au/notzed/jjmpeg/fx/FXPixelReader.java index dddf359..3d53784 100644 --- a/src/notzed.jjmpeg.fx/classes/au/notzed/jjmpeg/fx/FXPixelReader.java +++ b/src/notzed.jjmpeg.fx/classes/au/notzed/jjmpeg/fx/FXPixelReader.java @@ -110,4 +110,4 @@ public class FXPixelReader implements PixelReader, AVPixelReader { public void release() { reader.release(); } -} +} \ No newline at end of file diff --git a/src/notzed.jjmpeg/classes/au/notzed/jjmpeg/AVChannelLayout.java b/src/notzed.jjmpeg/classes/au/notzed/jjmpeg/AVChannelLayout.java deleted file mode 100644 index 206c81e..0000000 --- a/src/notzed.jjmpeg/classes/au/notzed/jjmpeg/AVChannelLayout.java +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Copyright (C) 2019 Michael Zucchi - * - * This file is part of jjmpeg - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package au.notzed.jjmpeg; - -/** - */ -public class AVChannelLayout implements AVChannelLayoutBits { - - static { - AVObject.init(); - } - - /** - * Call av_get_channel_layout(name) - */ - public static native long valueOf(String name); - - /** - * Call av_get_channel_name(value) - */ - public static native String toString(long value); - - /** - * call av_get_channel_layout_nb_channels(layout) - * - * @param layout - * @return - */ - public static native int getNumChannels(long layout); - - /** - * call av_get_default_channel_layout(nb_channels) - * - * @param nchannels - * @return - */ - public static native long getDefaultLayout(int nchannels); - -} diff --git a/src/notzed.jjmpeg/classes/au/notzed/jjmpeg/AVCodec.java b/src/notzed.jjmpeg/classes/au/notzed/jjmpeg/AVCodec.java deleted file mode 100644 index cd1356e..0000000 --- a/src/notzed.jjmpeg/classes/au/notzed/jjmpeg/AVCodec.java +++ /dev/null @@ -1,97 +0,0 @@ -/* - * Copyright (C) 2017 Michael Zucchi - * - * This file is part of jjmpeg - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package au.notzed.jjmpeg; - -/** - * - */ -public class AVCodec extends AVObject implements AVCodecBits, AVDiscardBits { - - private AVCodec(long p) { - super(p); - } - - private static native void release(long p); - - public static native int getVersion(); - - public static native String getConfiguration(); - - public static native String getLicense(); - - public static native void registerAll(); - - public static native AVCodec next(AVCodec val); - - public static Iterable codecs() { - return () -> new AVObjectIterator<>(AVCodec::next); - } - - public static native AVCodec findDecoder(int codecID); - - public static native AVCodec findDecoder(String name); - - public static native AVCodec findEncoder(int codecID); - - public static native AVCodec findEncoder(String name); - - /** - * Get AVCodec.name. - * - * @return - */ - public native String getName(); - - /** - * Get AVCodec.long_name. - * - * @return - */ - public native String getLongName(); - - /** - * Get AVCodec.type. - * - * @return - * @see AVMediaType - */ - public native int getType(); - - /** - * Get AVCodec.id. - * - * @return - * @see AVCodecID - */ - public native int getID(); - - public native int getCapabilities(); - - public native AVRational[] getFramerates(); - - public native int[] getPixelFormats(); - - public native int[] getSampleRates(); - - public native int[] getSampleFormats(); - - public native long[] getChannelLayouts(); - - public native int getMaxLowres(); -} diff --git a/src/notzed.jjmpeg/classes/au/notzed/jjmpeg/AVCodecContext.java b/src/notzed.jjmpeg/classes/au/notzed/jjmpeg/AVCodecContext.java deleted file mode 100644 index d3fae47..0000000 --- a/src/notzed.jjmpeg/classes/au/notzed/jjmpeg/AVCodecContext.java +++ /dev/null @@ -1,486 +0,0 @@ -/* - * Copyright (C) 2017 Michael Zucchi - * - * This file is part of jjmpeg - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package au.notzed.jjmpeg; - -/** - * AVCodecContext accessors. - *

- * The accessors here are currently implemented as direct struct accessors but - * most fields may also be accessed by the {@link AVOptions} accessor methods. The - * AVOptions methods are somewhat inconvenient but provide additional - * validation checks for setting options. - *

- * Note that there are many other options, these are documented in libavcodec/avcodec.h and the ffmpeg - * source in libavcodec/options_table.h. This can also be retrieved at runtime - * via - */ -public class AVCodecContext extends AVOptions implements AVCodecContextBits { - - private AVCodecContext(long p) { - super(p); - } - - /** - * Free the context. - *

- * Calls avcodec_free_context(). - * - * @param p - */ - private static native void release(long p); - - /** - * Allocate and initialise an AVCodecContext. - *

- * Calls avcodec_alloc_context3(). - * - * @param codec Codec used to initialise parameters, may be null. - * @return - */ - public static native AVCodecContext allocContext(AVCodec codec); - - /** - * Open a context. - *

- * Calls avcodec_open2(). - * - * @param codec Codec used. It must match the one used in allocContext(). - * @param options Codec options. - * @throws AVIOException is thrown iv avcodec_open2 returns an error. - */ - public native void open(AVCodec codec, AVDictionary options) throws AVIOException; - - /** - * Flush internal buffers. - *

- * Used to reset codec state, for example after a seek. - *

- * Calls avcodec_flush_buffers(). - */ - public native void flushBuffers(); - - /** - * Align dimensions suitable for codec. - *

- * Calls avcodec_align_dimensions(). - * - * @param input Input dimensions. - * @return Modified dimensions. - */ - public native AVSize alignDimensions(AVSize input); - - /** - * Submit raw packet to a decoder. - *

- * Packets are submitted to a decoder which generates output frames. - *

- * If the return value is EAGAIN or AVERROR_EOF then this function - * returns false, for all other error values it throws an exception. - *

- * Calls avcodec_send_packet(). - * - * @param pkt - * @return true if the packet was accepted, false if a frame must be received first. - * @throws AVIOException - * @see #receiveFrame(au.notzed.jjmpeg.AVFrame) - */ - public native boolean sendPacket(AVPacket pkt) throws AVIOException; - - /** - * Retrieve a decoded frame from a decoder. - *

- * If the return value from avcodec_receive_frame() is EAGAIN or AVERROR_EOF - * then this function returns false, for all other error values it throws an exception. - *

- * Calls avcodec_receive_frame(). - * - * @param frame - * @return Returns true if the frame is complete, false otherwise. - * @throws AVIOException - * @see #sendPacket(au.notzed.jjmpeg.AVPacket) - */ - public native boolean receiveFrame(AVFrame frame) throws AVIOException; - - /** - * Calls avcodec_send_frame(). - *

- * If the return value is EAGAIN or AVERROR_EOF then this function - * returns false, for all other error values it throws an exception. - * - * @param frame - * @return - * @throws AVIOException - */ - public native boolean sendFrame(AVFrame frame) throws AVIOException; - - /** - * Calls avcodec_receive_packet(). - *

- * If the return value is EAGAIN or AVERROR_EOF then this function - * returns false, for all other error values it throws an exception. - * - * @param pkt - * @return - * @throws AVIOException - */ - public native boolean receivePacket(AVPacket pkt) throws AVIOException; - - /** - * Get encoding/decoding AVCodecContext.codec_type. - * - * @return - * @see AVMediaType - */ - public native int getCodecType(); - - /** - * Set encoding/decoding AVCodecContext.codec_type. - * - * @param val - * @see AVMediaType - */ - public native void setCodecType(int val); - - /** - * Get encoding/decoding AVCodecContext.codec_id. - * - * @return - * @see AVCodecID - */ - public native int getCodecID(); - - /** - * Set encoding/decoding AVCodecContext.codec_id. - * - * @param val - * @see AVCodecID - */ - public native void setCodecID(int val); - - /** - * Get encoding/decoding AVCodecContext.bit_rate. - *

- * AVOption int "b" or "ab" - * - * @return - */ - public native long getBitRate(); - - /** - * Set encoding/decoding AVCodecContext.bit_rate. - *

- * AVOption int "b" or "ab" - * - * @param bitrate - */ - public native void setBitRate(long bitrate); - - /** - * Get encoding AVCodecContext.global_quality. - *

- * AVOption int "global_quality". - * - * @return - */ - public native int getGlobalQuality(); - - /** - * Set AVCodecContext.global_quality. - *

- * AVOption int "global_quality". - * - * @param quality - */ - public native void setGlobalQuality(int quality); - - /** - * Get the encoding/decoding AVCodecContext.flags and AVCodecContext.flags2. - *

- * This combines .flags and .flags2 into a single 64-bit flag set. The - * AV_CODE_FLAG2_* constants have been shifted appropriately. - *

- * AVOption int "flag", also specific flags "unaligned", "mv4", and so on. - * - * @return - */ - public native long getFlags(); - - /** - * Adjust the encoding/decoding AVCodecContext.flags and AVCodecContext.flags2. - *

- * This performs a combined get and set operation on the flags allowing any cobimation - * of flags to be set in a single call. - *

- * AVOption int "flag", also specific flags "unaligned", "mv4", and so on. - * - * @param mask Mask of bits to change. Flags with a bit set here will be set to the values in flags. - * @param flags Value to set bits to. - * @see #getFlags() for an explanation of the flag values. - */ - public native void setFlags(long mask, long flags); - - /** - * Get the encoding AVCodecContext.time_base. - *

- * AVOption rational (q) "time_base". - * - * @return A copy of the time_base (adjustments will not be carried through). - */ - public native AVRational getTimeBase(); - - /** - * Set the encoding AVCodecContext.time_base. - *

- * A time_base must always be set for encoding. - *

- * AVOption rational (q) "time_base". - * - * @param timebase - */ - public native void setTimeBase(AVRational timebase); - - /** - * Get the encoding/decoding AVCodecContext.delay. - *

- * AVOption int "delay". - * - * @return - */ - public native int getDelay(); - - /** - * Get video encoding/decoding AVCodecContext.width. - *

- * AVOption image size "video_size". - * - * @return - */ - public native int getWidth(); - - /** - * Set video encoding/decoding AVCodecContext.width. - *

- * AVOption image size "video_size". - * - * @param width - */ - public native void setWidth(int width); - - /** - * Get video encoding/decoding AVCodecContext.height. - *

- * AVOption image size "video_size". - * - * @return - */ - public native int getHeight(); - - /** - * Set video encoding/decoding AVCodecContext.width. - *

- * AVOption image size "video_size". - * - * @param height - */ - public native void setHeight(int height); - - /** - * Get video encoding/decoding AVCodecContext.sample_aspect_ratio. - *

- * AVOption rational "aspect" or "sar". - * - * @return - */ - public native AVRational getAspectRatio(); - - /** - * Set video encoding/decoding AVCodecContext.sample_aspect_ratio. - *

- * AVOption rational "aspect" or "sar". - * - * @param ratio - */ - public native void setAspectRatio(AVRational ratio); - - /** - * Get video encoding AVCodecContext.gop_size. - *

- * AVOption int "g". - * - * @return - */ - public native int getGOPSize(); - - /** - * Set video encoding AVCodecContext.gop_size. - *

- * AVOption int "g". - * - * @param val - */ - public native void setGOPSize(int val); - - /** - * Get video encoding/decoding AVCodecContext.pix_fmt. - *

- * AVOption pixel format "pixel_format". - * - * @return - * @see AVPixelFormat - */ - public native int getPixelFormat(); - - /** - * Set video encoding/decoding AVCodecContext.pix_fmt. - *

- * AVOption pixel format "pixel_format". - * - * @param format - * @see AVPixelFormat - */ - public native void setPixelFormat(int format); - - /** - * Get audio encoding/decoding AVCodecContext.sample_rate. - *

- * AVOption int "ar". - * - * @return - */ - public native int getSampleRate(); - - /** - * Set audio encoding/decoding AVCodecContext.sample_rate. - *

- * AVOption int "ar". - * - * @param hertz - */ - public native void setSampleRate(int hertz); - - /** - * Get audio encoding/decoding AVCodecContext.channels. - *

- * AVOption int "ac". - * - * @return - */ - public native int getNumChannels(); - - /** - * Set audio encoding/decoding AVCodecContext.channels. - *

- * AVOption int "ac". - * - * @param nchannels - */ - public native void setNumChannels(int nchannels); - - /** - * Get audio encoding/decoding AVCodecContext.sample_fmt. - * - * @return - * @see AVSampleFormat - */ - public native int getSampleFormat(); - - /** - * Set audio encoding/decoding AVCodecContext.sample_fmt. - * - * @param format - * @see AVSampleFormat - */ - public native void setSampleFormat(int format); - - /** - * Get audio encoding/decoding AVCodecContext.frame_size. - *

- * AVOption int "frame_size". - * - * @return - */ - public native int getFrameSize(); - - /** - * Get audio encoding/decoding AVCodecContext.frame_number. - *

- * AVOption int "frame_number". - * - * @return - */ - public native int getFrameNumber(); - - /** - * Get audio encoding/decoding AVCodecContext.channel_layout. - *

- * AVOption channel layout "channel_layout". - * - * @return - * @see AVChannelLayout - */ - public native long getChannelLayout(); - - /** - * Set audio encoding/decoding AVCodecContext.channel_layout. - *

- * AVOption channel layout "channel_layout". - * - * @param layout - * @see AVChannelLayout - */ - public native void setChannelLayout(long layout); - - /** - * Get audio decoding AVCodecContext.request_channel_layout. - *

- * AVOption channel layout "request_channel_layout". - * - * @return - * @see AVChannelLayout - */ - public native long getRequestChannelLayout(); - - /** - * Set audio decoding AVCodecContext.request_channel_layout. - *

- * AVOption channel layout "request_channel_layout". - * - * @param layout - * @see AVChannelLayout - */ - public native void setRequestChannelLayout(long layout); - - /** - * Get encoding/decoding AVCodecContext.thread_count. - *

- * AVOption int "threads". - * - * @return - */ - public native int getThreadCount(); - - /** - * Set encoding/decoding AVCodecContext.thread_count. - *

- * AVOption int "threads". - * - * @param nthreads - */ - public native void setThreadCount(int nthreads); -} diff --git a/src/notzed.jjmpeg/classes/au/notzed/jjmpeg/AVCodecID.java b/src/notzed.jjmpeg/classes/au/notzed/jjmpeg/AVCodecID.java deleted file mode 100644 index ab39bb8..0000000 --- a/src/notzed.jjmpeg/classes/au/notzed/jjmpeg/AVCodecID.java +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright (C) 2017 Michael Zucchi - * - * This file is part of jjmpeg - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package au.notzed.jjmpeg; - -/** - */ -public class AVCodecID implements AVCodecIDBits { - - static { - AVObject.init(); - } - - /** - * Call avcodec_get_name(value) - */ - public static native String toString(int value); - - /** - * Call avcodec_get_type(value) - * - * @param value AVCodecID. - * @return Corresponding AVMediaType. - */ - public static native int getType(int value); -} diff --git a/src/notzed.jjmpeg/classes/au/notzed/jjmpeg/AVCodecParameters.java b/src/notzed.jjmpeg/classes/au/notzed/jjmpeg/AVCodecParameters.java deleted file mode 100644 index c5115df..0000000 --- a/src/notzed.jjmpeg/classes/au/notzed/jjmpeg/AVCodecParameters.java +++ /dev/null @@ -1,96 +0,0 @@ -/* - * Copyright (C) 2017 Michael Zucchi - * - * This file is part of jjmpeg - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package au.notzed.jjmpeg; - -/** - * - */ -public class AVCodecParameters extends AVObject { - - private AVCodecParameters(long p) { - super(p); - } - - private static native void release(long p); - - public static native AVCodecParameters alloc(); - - public native void copy(AVCodecParameters src); - - public native void fromContext(AVCodecContext cc); - - public native void toContext(AVCodecContext cc); - - /* */ - public native int getCodecType(); - - public native void setCodecType(int type); - - public native int getCodecID(); - - public native void setCodecID(int id); - - public native int getCodecTag(); - - public native void setCodecTag(int val); - - public native long getBitRate(); - - public native void setBitRate(long val); - - /* - Video only options - */ - public native int getPixelFormat(); - - public native void setPixelFormat(int val); - - public native int getWidth(); - - public native void setWidth(int val); - - public native int getHeight(); - - public native void setHeight(int val); - - public native AVRational getAspectRatio(); - - public native void setAspectRatio(AVRational r); - - /* - * Audio stuff - */ - public native int getSampleFormat(); - - public native void setSampleFormat(int val); - - public native long getChannelLayout(); - - public native void setChannelLayout(long val); - - public native int getNumChannels(); - - public native void setNumChannels(int val); - - public native int getSampleRate(); - - public native void setSampleRate(int val); - - // ryv? -} diff --git a/src/notzed.jjmpeg/classes/au/notzed/jjmpeg/AVDevice.java b/src/notzed.jjmpeg/classes/au/notzed/jjmpeg/AVDevice.java deleted file mode 100644 index 705078c..0000000 --- a/src/notzed.jjmpeg/classes/au/notzed/jjmpeg/AVDevice.java +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Copyright (C) 2017 Michael Zucchi - * - * This file is part of jjmpeg - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package au.notzed.jjmpeg; - -/** - * Interface to libavdevice. - *

- * This is currently a dummy object but could hold AVDeviceInfo if that was useful. - */ -public class AVDevice extends AVObject { - - private AVDevice(long p) { - super(p); - } - - private static void release(long p) { - } - - public static native int getVersion(); - - public static native String getConfiguration(); - - public static native String getLicense(); - - public static native void registerAll(); - - public native static AVInputFormat nextAudioInputDevice(AVInputFormat last); - - public static Iterable audioInputDevices() { - return () -> new AVObjectIterator<>(AVDevice::nextAudioInputDevice); - } - - public native static AVInputFormat nextVideoInputDevice(AVInputFormat last); - - public static Iterable videoInputDevices() { - return () -> new AVObjectIterator<>(AVDevice::nextVideoInputDevice); - } - - public native static AVOutputFormat nextAudioOutputDevice(AVOutputFormat last); - - public static Iterable audioOutputDevices() { - return () -> new AVObjectIterator<>(AVDevice::nextAudioOutputDevice); - } - - public native static AVOutputFormat nextVideoOutputDevice(AVOutputFormat last); - - public static Iterable videoOutputDevices() { - return () -> new AVObjectIterator<>(AVDevice::nextVideoOutputDevice); - } - -} diff --git a/src/notzed.jjmpeg/classes/au/notzed/jjmpeg/AVDictionary.java b/src/notzed.jjmpeg/classes/au/notzed/jjmpeg/AVDictionary.java deleted file mode 100644 index 6110f45..0000000 --- a/src/notzed.jjmpeg/classes/au/notzed/jjmpeg/AVDictionary.java +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright (C) 2017 Michael Zucchi - * - * This file is part of jjmpeg - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package au.notzed.jjmpeg; - -import java.util.TreeMap; - -/** - * AVDictionary is a remarkably shithouse "ADT" used for configuration parameters. - *

- * This does not wrap it, it simply provides an equivalent functionality - * using a TreeMap. - *

- *

Historical Note

- *

- * AVDictionary was inherited from libav. It's a miserable - * design, it's simply a pointer to an array which updates itself by copying the whole array - * every time it's length is changed. - *

- */ -public class AVDictionary extends TreeMap { - - /** - * Convert the dictionary to an array of {@code Entry}. - *

- * This is used by the native binding to read elements. - * - * @return An array containing {@link java.util.Map.Entry} objects. - */ - public Object[] toArray() { - return entrySet().toArray(); - } -} diff --git a/src/notzed.jjmpeg/classes/au/notzed/jjmpeg/AVError.java b/src/notzed.jjmpeg/classes/au/notzed/jjmpeg/AVError.java deleted file mode 100644 index 7367b51..0000000 --- a/src/notzed.jjmpeg/classes/au/notzed/jjmpeg/AVError.java +++ /dev/null @@ -1,31 +0,0 @@ -/* - * Copyright (C) 2017 Michael Zucchi - * - * This file is part of jjmpeg - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package au.notzed.jjmpeg; - -/** - * - */ -public class AVError implements AVErrorBits { - - static { - AVObject.init(); - } - - public static native String toString(int errno); -} diff --git a/src/notzed.jjmpeg/classes/au/notzed/jjmpeg/AVFormatContext.java b/src/notzed.jjmpeg/classes/au/notzed/jjmpeg/AVFormatContext.java deleted file mode 100644 index f7f1d7e..0000000 --- a/src/notzed.jjmpeg/classes/au/notzed/jjmpeg/AVFormatContext.java +++ /dev/null @@ -1,172 +0,0 @@ -/* - * Copyright (C) 2017 Michael Zucchi - * - * This file is part of jjmpeg - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package au.notzed.jjmpeg; - -import java.io.FileNotFoundException; - -/** - * - */ -public class AVFormatContext extends AVOptions { - - private AVFormatContext(long p) { - super(p); - } - - private static native void release(long p); - - // Fields - public native AVInputFormat getInputFormat(); - - public native AVOutputFormat getOutputFormat(); - - // hmm? - //public native void setOutputFormat(AVOutputFormat val); - public native AVIOContext getIOContext(); - - public native void setIOContext(AVIOContext val); - - /* stream info */ - public native int getCtxFlags(); - - public native int getNumStreams(); - - public native AVStream getStream(int index); - - //public native String getFilename(); - //public native void setFilename(String name); - // - public native long getStartTime(); - - public native long getDuration(); - - public native long getBitRate(); -// packet_size -// max_delay - - public native int getFlags(); - - public native void setFlags(int val); - - public native long getProbeSize(); - - public native void setProbeSize(long val); - - public native long getMaxAnalyseDuration(); - - public native void setMaxAnalyseDuration(long val); -// ... - - public native int getVideoCodecID(); - - public native void setVideoCodecID(int val); - - public native int getAudioCodecID(); - - public native void setAudioCodecID(int val); - - public native int getSubtitleCodecID(); - - public native void setSubtitleCodecID(int val); -// ... - - public native AVDictionary getMetadata(); - - public native void setMetadata(AVDictionary val); -// ... - - public native void setDebug(int val); -// ... - - public native int getSeek2Any(); - - public native void setSeek2Any(int val); - - // Native Methods - public static native int getVersion(); - - public static native String getConfiguration(); - - public static native String getLicense(); - - public static native void registerAll(); - - // registerInputFormat() - // registerOutputFormat() - public static native void networkInit(); - - public static native void networkDeinit(); - - // - static public native AVFormatContext allocContext(); - - public native AVStream newStream(AVCodec c); - - // newProgram - static public native AVFormatContext allocContext(AVOutputFormat of, String format_name, String filename) throws AVIOException; - - // probeInputFormat / 2 / 3 - // probeInputBuffer / 2 - public static native AVFormatContext openInput(String url, AVInputFormat fmt, AVDictionary options) throws AVIOException, FileNotFoundException; - - // options is updated by result - public native void findStreamInfo(AVDictionary[] options) throws AVIOException; - - // returns false on end of file - public native boolean readFrame(AVPacket pkt) throws AVIOException; - - public native void seekFrame(int stream_index, long timestamp, int flags) throws AVIOException; - - public native void seekFile(int stream_index, long min_ts, long ts, long max_ts, int flags) throws AVIOException; - - public native void flush() throws AVIOException; - - public native void readPlay() throws AVIOException; - - public native void readPause() throws AVIOException; - - // two separate ways to close!! - // closeInput() -> has to p <= null - // freeContext() - // - public native int writeHeader(AVDictionary options) throws AVIOException; - - public native int initOutput(AVDictionary options) throws AVIOException; - - // returns true if flushed - public native boolean writeFrame(AVPacket pktkt) throws AVIOException; - - /** - * Write a frame to the output. - *

- * Calls av_interleaved_write_frame(). - * - * @param pkt Packet containing data. - * @throws AVIOException on error. - */ - public native void interleavedWriteFrame(AVPacket pkt) throws AVIOException; - - public native void writeUncodedFrame(int stream_index, AVFrame frame) throws AVIOException; - - public native void interleavedWriteUncodedFrame(int stream_index, AVFrame frame) throws AVIOException; - - public native void writeTrailer() throws AVIOException; - - public native int findDefaultStreamIndex(); -} diff --git a/src/notzed.jjmpeg/classes/au/notzed/jjmpeg/AVFrame.java b/src/notzed.jjmpeg/classes/au/notzed/jjmpeg/AVFrame.java deleted file mode 100644 index ca2032e..0000000 --- a/src/notzed.jjmpeg/classes/au/notzed/jjmpeg/AVFrame.java +++ /dev/null @@ -1,266 +0,0 @@ -/* - * Copyright (C) 2017 Michael Zucchi - * - * This file is part of jjmpeg - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package au.notzed.jjmpeg; - -import java.nio.Buffer; -import java.nio.ByteBuffer; - -/** - * Accessor for a struct AVFrame. - *

- * Both video and audio frames are stored in the same object; various fields - * will only make sense for the corresponding data. - *

- * To read and write pixels for video frames use {@link getPixelReader} and {@link getPixelWriter}. - *

- * To read and write samples for audio frames use {@link getSampleReader} and {@link getSampleWriter}. - */ -public class AVFrame extends AVObject { - - private AVFrame(long p) { - super(p); - } - - private native static void release(long p); - - public native static AVFrame alloc(); - - public native void copy(AVFrame source); - - public native void copyProperties(AVFrame source); - - /** - * Call av_frame_ref() to copy the contents. this must be newly - * allocated or unreffed. - * - * @param source - */ - public native void ref(AVFrame source); - - /** - * Call av_frame_unref() to clear allocated data. This does not free - * the AVFrame itself. - */ - public native void unref(); - - public native AVFrameSideData getSideData(int type); - - /* - * Data stuff. - *

- * TODO: perhaps i want audio/video specific versions, as the interpretation - * of the fields depends upon it. It depends on whether this is easy to determine - * from other fields. - */ - @Deprecated - public native ByteBuffer getPlane(int i); - - @Deprecated - public native int getStride(int i); - - /* - * Video stuff - */ - /** - * Create a new AVFrame and allocate video frame information. - *

- * This calls av_frame_alloc(), initialises the provided fields and - * then calls av_frame_get_buffer(). - * - * @param fmt - * @param width - * @param height - * @return - */ - public native static AVFrame alloc(int fmt, int width, int height); - - public native int getWidth(); - - public native void setWidth(int width); - - public native int getHeight(); - - public native void setHeight(int height); - - /** - * .format for video. - * - * @return - */ - public native int getPixelFormat(); - - public native boolean isKeyFrame(); - - public native AVRational getAspectRatio(); - - public native long getPTS(); - - public native void setPTS(long val); - - public native int getDisplayPictureNumber(); - - public native int getCodedPictureNumber(); - - public native boolean isInterlaced(); - - public native boolean isTopFieldFirst(); - - /* - * Audio stuff - */ - public native static AVFrame alloc(int fmt, int channels, long channel_layout, int num_samples); - - public native int getNumSamples(); - - public native void setNumSamples(int n); - - /** - * .format for audio. - * - * @return - */ - public native int getSampleFormat(); - - public native int getSampleRate(); - - public native void setSampleRate(int v); - - public native long getChannelLayout(); - - public native void setChannelLayout(long v); - - public native int getNumChannels(); - - public native void setNumChannels(int v); - - public native int getBestEffortTimestamp(); - - /** - * Create a PixelReader for this frame. Pixel readers can convert the image format and perform scaling. - *

- * Multiple readers with differing options may be created from a given frame. - * - * @param dwidth target width - * @param dheight target height - * @param flags SwsContext creation flags - * @return A pixel reader. Note that scanlineStride is currently ignored for all getPixels() calls. - */ - public AVPixelReader getPixelReader(int dwidth, int dheight, int flags) { - return FrameReader.alloc(this, dwidth, dheight, flags); - } - - static class FrameReader extends AVObject implements AVPixelReader { - - private FrameReader(long p) { - super(p); - } - - private native static void release(long p); - - public native static FrameReader alloc(AVFrame frame, int width, int height, int flags); - - @Override - native public void getPixels(int y, int h, int fmt, T buffer, int scanlineStride); - - @Override - native public void getPixels(int y, int h, int fmt, byte[] buffer, int offset, int scanlineStride); - - @Override - native public void getPixels(int y, int h, int fmt, short[] buffer, int offset, int scanlineStride); - - @Override - native public void getPixels(int y, int h, int fmt, int[] buffer, int offset, int scanlineStride); - } - - public AVPixelWriter getPixelWriter(int swidth, int sheight, int flags) { - return FrameWriter.alloc(this, swidth, sheight, flags); - } - - static class FrameWriter extends AVObject implements AVPixelWriter { - - private FrameWriter(long p) { - super(p); - } - - private native static void release(long p); - - public native static FrameWriter alloc(AVFrame frame, int width, int height, int flags); - - @Override - native public void setPixels(int y, int h, int fmt, T buffer, int scanlineStride); - - @Override - native public void setPixels(int y, int h, int fmt, byte[] buffer, int offset, int scanlineStride); - - @Override - native public void setPixels(int y, int h, int fmt, short[] buffer, int offset, int scanlineStride); - - @Override - native public void setPixels(int y, int h, int fmt, int[] buffer, int offset, int scanlineStride); - } - - /** - * Create a new sample reader. - * - * @param layout AVChannelLayout. Planar formats are not supported. - * @param fmt AVSampleFormat. - * @param rate sample rate - * @return an AVSampleReader which will retrieve samples of the given - * format and layout. - */ - public AVSampleReader getSampleReader(long layout, int fmt, int rate) { - return SampleReader.alloc(this, layout, fmt, rate); - } - - static class SampleReader extends AVObject implements AVSampleReader { - - private SampleReader(long p) { - super(p); - } - - private native static void release(long p); - - public native static SampleReader alloc(AVFrame frame, long layout, int fmt, int rate); - - @Override - public native int getNumSamples(); - - @Override - public native int getSamples(byte[] buffer, int offset, int length); - - @Override - public native int getSamples(short[] buffer, int offset, int length); - - @Override - public native int getSamples(int[] buffer, int offset, int length); - - @Override - public native int getSamples(float[] buffer, int offset, int length); - - @Override - public native void getSamples(T buffer); - - } - - public AVSampleWriter getSampleWriter(long layout, int fmt, int rate) { - //return SampleReader.alloc(this, layout, fmt, rate); - throw new UnsupportedOperationException(); - } - -} diff --git a/src/notzed.jjmpeg/classes/au/notzed/jjmpeg/AVFrameSideData.java b/src/notzed.jjmpeg/classes/au/notzed/jjmpeg/AVFrameSideData.java deleted file mode 100644 index 7626f17..0000000 --- a/src/notzed.jjmpeg/classes/au/notzed/jjmpeg/AVFrameSideData.java +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright (C) 2019 Michael Zucchi - * - * This file is part of jjmpeg - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package au.notzed.jjmpeg; - -import java.nio.ByteBuffer; - -/** - * - */ -public class AVFrameSideData extends AVObject { - - private AVFrameSideData(long p) { - super(p); - } - - private static void release(long p) { - } - - public native int getType(); - - public native ByteBuffer getData(); - -} diff --git a/src/notzed.jjmpeg/classes/au/notzed/jjmpeg/AVFrameSideDataType.java b/src/notzed.jjmpeg/classes/au/notzed/jjmpeg/AVFrameSideDataType.java deleted file mode 100644 index ead17a4..0000000 --- a/src/notzed.jjmpeg/classes/au/notzed/jjmpeg/AVFrameSideDataType.java +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Copyright (C) 2019 Michael Zucchi - * - * This file is part of jjmpeg - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package au.notzed.jjmpeg; - -/** - */ -public class AVFrameSideDataType implements AVFrameSideDataTypeBits { - - static { - AVObject.init(); - } - - /** - * Call av_frame_side_data_name - */ - public static native String toString(int value); -} diff --git a/src/notzed.jjmpeg/classes/au/notzed/jjmpeg/AVIOContext.java b/src/notzed.jjmpeg/classes/au/notzed/jjmpeg/AVIOContext.java deleted file mode 100644 index 94118ac..0000000 --- a/src/notzed.jjmpeg/classes/au/notzed/jjmpeg/AVIOContext.java +++ /dev/null @@ -1,134 +0,0 @@ -/* - * Copyright (C) 2017 Michael Zucchi - * - * This file is part of jjmpeg - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package au.notzed.jjmpeg; - -import java.nio.ByteBuffer; - -/** - * - */ -public class AVIOContext extends AVOptions implements AVIOContextBits { - - /** - * Maintain a reference to an interrupt or i/o handler if set. - *

- * The C uses a weak reference and this makes sure it stays around - * while {@code this} does. - */ - Object handler; - - // - public static final int AVSEEK_SET = 0; - public static final int AVSEEK_CUR = 1; - public static final int AVSEEK_END = 2; - /** - * If set then alloc() will pass write_flag=1 to avio_alloc_context(). - */ - public static final int AVIO_WRITABLE = (1 << 31); - /** - * If set, then alloc() will set AVIOContext.direct=1. - */ - public static final int AVIO_DIRECT = (1 << 30); - - private AVIOContext(long p) { - super(p); - } - - private static native void release(long p); - - /** - * Create an AVIOContext backed by libavformat i/o. - *

- * Calls avio_open2(). - * - * @param url - * @param avio_flags AVIO_FLAGS_*. - * @param interrupt_cb If non-null, supplies interrupt-check function. - * @param options - * @return - * @throws au.notzed.jjmpeg.AVIOException - */ - public static native AVIOContext open(String url, int avio_flags, AVIOInterrupt interrupt_cb, AVDictionary options) throws AVIOException; - - /** - * Create an AVIOContext backed by libavformat i/o with no callback or options. - * - * @param url - * @param avio_flags - * @return - * @throws AVIOException - */ - public static AVIOContext open(String url, int avio_flags) throws AVIOException { - return open(url, avio_flags, null, null); - } - - /** - * Create an AVIOContext backed by Java I/O. - * - * @param buffer_size - * @param alloc_flags combination of AVIO_SEEKABLE_*, AVIO_WRITABLE, and AVIO_DIRECT. - * @param handler Functions which implement i/o. - * @return - */ - public static native AVIOContext alloc(int buffer_size, int alloc_flags, AVIOHandler handler); - - /** - * Callback hook for interrupt checking. - */ - public interface AVIOInterrupt { - - /** - * Called during blocking operations. - * - * @return true if the blocking i/o should abort. - */ - public boolean isInterrupted(); - } - - /** - * Callback hooks which allow Java I/O functions to provide I/O for FFmpeg. - */ - public interface AVIOHandler { - - /** - * Read data into dest. - * - * @param dst ByteBuffer with position and limit set to the bounds of valid data. - * @return The number of bytes actually read or -errno on error. - */ - public int readPacket(ByteBuffer dst); - - /** - * Write from src. - * - * @param src ByteBuffer with position and limit set to the bounds of valid data. - * @return Number of bytes written or -errno on error. - */ - public int writePacket(ByteBuffer src); - - /** - * Called to perform seek. - * - * @param offset - * @param whence AVSEEK_* value. - * @return - */ - public long seek(long offset, int whence); - } -} diff --git a/src/notzed.jjmpeg/classes/au/notzed/jjmpeg/AVInputFormat.java b/src/notzed.jjmpeg/classes/au/notzed/jjmpeg/AVInputFormat.java deleted file mode 100644 index af63be8..0000000 --- a/src/notzed.jjmpeg/classes/au/notzed/jjmpeg/AVInputFormat.java +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright (C) 2017 Michael Zucchi - * - * This file is part of jjmpeg - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package au.notzed.jjmpeg; - -/** - * - */ -public class AVInputFormat extends AVObject { - - private AVInputFormat(long p) { - super(p); - } - - public static native AVInputFormat findInputFormat(String name); - - public static native AVInputFormat next(AVInputFormat val); - - public static Iterable formats() { - return () -> new AVObjectIterator<>(AVInputFormat::next); - } - - public native void register(); - - public native String getName(); - - public native String getLongName(); -} diff --git a/src/notzed.jjmpeg/classes/au/notzed/jjmpeg/AVLogger.java b/src/notzed.jjmpeg/classes/au/notzed/jjmpeg/AVLogger.java index 91359f3..372a6f5 100644 --- a/src/notzed.jjmpeg/classes/au/notzed/jjmpeg/AVLogger.java +++ b/src/notzed.jjmpeg/classes/au/notzed/jjmpeg/AVLogger.java @@ -1,6 +1,5 @@ /* - * Copyright (c) 2006 Michael Niedermayer - * Copyright (C) 2017 Michael Zucchi + * Copyright (C) 2022 Michael Zucchi * * This file is part of jjmpeg * @@ -22,56 +21,7 @@ package au.notzed.jjmpeg; /** * */ -public interface AVLogger { - - /** - * Print no output. - */ - public static final int AV_LOG_QUIET = -8; - - /** - * Something went really wrong and we will crash now. - */ - public static final int AV_LOG_PANIC = 0; - - /** - * Something went wrong and recovery is not possible. - * For example, no header was found for a format which depends - * on headers or an illegal combination of parameters is used. - */ - public static final int AV_LOG_FATAL = 8; - - /** - * Something went wrong and cannot losslessly be recovered. - * However, not all future data is affected. - */ - public static final int AV_LOG_ERROR = 16; - - /** - * Something somehow does not look correct. This may or may not - * lead to problems. An example would be the use of '-vstrict -2'. - */ - public static final int AV_LOG_WARNING = 24; - - /** - * Standard information. - */ - public static final int AV_LOG_INFO = 32; - - /** - * Detailed information. - */ - public static final int AV_LOG_VERBOSE = 40; - - /** - * Stuff which is only useful for libav* developers. - */ - public static final int AV_LOG_DEBUG = 48; - - /** - * Extremely verbose debugging, useful for libav* development. - */ - public static final int AV_LOG_TRACE = 56; +public interface AVLogger extends AVLoggerBits { public void log(int level, String what); diff --git a/src/notzed.jjmpeg/classes/au/notzed/jjmpeg/AVMediaType.java b/src/notzed.jjmpeg/classes/au/notzed/jjmpeg/AVMediaType.java deleted file mode 100644 index 0e32eba..0000000 --- a/src/notzed.jjmpeg/classes/au/notzed/jjmpeg/AVMediaType.java +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Copyright (C) 2017 Michael Zucchi - * - * This file is part of jjmpeg - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package au.notzed.jjmpeg; - -/** - * - */ -public class AVMediaType implements AVMediaTypeBits { - - static { - AVObject.init(); - } - - /** - * Call av_get_media_type_string() - */ - public static native String toString(int value); -} diff --git a/src/notzed.jjmpeg/classes/au/notzed/jjmpeg/AVObject.java b/src/notzed.jjmpeg/classes/au/notzed/jjmpeg/AVObject.java index 0bb6d50..2984229 100644 --- a/src/notzed.jjmpeg/classes/au/notzed/jjmpeg/AVObject.java +++ b/src/notzed.jjmpeg/classes/au/notzed/jjmpeg/AVObject.java @@ -18,28 +18,29 @@ */ package au.notzed.jjmpeg; -import au.notzed.nativez.NativeZ; -import java.util.Iterator; -import java.util.function.Function; +import au.notzed.nativez.*; import java.util.logging.Logger; +import jdk.incubator.foreign.ResourceScope; /** * */ -public abstract class AVObject extends NativeZ { +public abstract class AVObject extends Native { protected AVObject(long p) { - super(p); + super(null); } - static { - System.loadLibrary("jjmpeg"); + static{ + System.loadLibrary("avcodec"); + System.loadLibrary("avdevice"); + System.loadLibrary("avfilter"); + System.loadLibrary("avformat"); + System.loadLibrary("avresample"); + System.loadLibrary("avutil"); - AVCodec.registerAll(); - AVFormatContext.registerAll(); - //AVDevice.registerAll(); // ignore failure? - - AVUtil.setLogger(AVUtil.createAVLogger(Logger.getLogger("notzed.jjmpeg"))); + AVUtil.setLogger(AVUtil.createAVLogger(Logger.getLogger("notzed.jjmpeg")), + ResourceScope.globalScope()); } /** @@ -52,29 +53,4 @@ public abstract class AVObject extends NativeZ { public static void init() { } - /** - * Handy iterator for various uses in the library. - */ - static class AVObjectIterator implements Iterator { - - Function nextFunc; - T next; - - public AVObjectIterator(Function nextFunc) { - this.nextFunc = nextFunc; - this.next = nextFunc.apply(null); - } - - @Override - public boolean hasNext() { - return next != null; - } - - @Override - public T next() { - T current = next; - next = nextFunc.apply(current); - return current; - } - } } diff --git a/src/notzed.jjmpeg/classes/au/notzed/jjmpeg/AVObjectIterator.java b/src/notzed.jjmpeg/classes/au/notzed/jjmpeg/AVObjectIterator.java new file mode 100644 index 0000000..45b8e0c --- /dev/null +++ b/src/notzed.jjmpeg/classes/au/notzed/jjmpeg/AVObjectIterator.java @@ -0,0 +1,31 @@ +package au.notzed.jjmpeg; + +import java.util.Iterator; +import java.util.function.Function; + +/** + * Handy iterator for various uses in the library. + */ +class AVObjectIterator implements Iterator { + + Function nextFunc; + T next; + + public AVObjectIterator(Function nextFunc) { + this.nextFunc = nextFunc; + this.next = nextFunc.apply(null); + } + + @Override + public boolean hasNext() { + return next != null; + } + + @Override + public T next() { + T current = next; + next = nextFunc.apply(current); + return current; + } + +} diff --git a/src/notzed.jjmpeg/classes/au/notzed/jjmpeg/AVOutputFormat.java b/src/notzed.jjmpeg/classes/au/notzed/jjmpeg/AVOutputFormat.java deleted file mode 100644 index 41bc992..0000000 --- a/src/notzed.jjmpeg/classes/au/notzed/jjmpeg/AVOutputFormat.java +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Copyright (C) 2017 Michael Zucchi - * - * This file is part of jjmpeg - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package au.notzed.jjmpeg; - -/** - * - */ -public class AVOutputFormat extends AVObject { - - private AVOutputFormat(long p) { - super(p); - } - - public static final int AVFMT_NOFILE = 0x0001; - public static final int AVFMT_NEEDNUMBER = 0x0002; - public static final int AVFMT_GLOBALHEADER = 0x0040; - public static final int AVFMT_NOTIMESTAMPS = 0x0080; - public static final int AVFMT_VARIABLE_FPS = 0x0400; - public static final int AVFMT_NODIMENSIONS = 0x0800; - public static final int AVFMT_NOSTREAMS = 0x1000; - public static final int AVFMT_ALLOW_FLUSH = 0x10000; - public static final int AVFMT_TS_NONSTRICT = 0x20000; - public static final int AVFMT_TS_NEGATIVE = 0x40000; - - public static native AVOutputFormat guessFormat(String short_name, String filename, String mime_type); - - public native int guessCodecID(String short_name, String filename, String mime_type, int media_type); - - public static native AVOutputFormat next(AVOutputFormat val); - - public static Iterable formats() { - return () -> new AVObjectIterator<>(AVOutputFormat::next); - } - - public native void register(); - - public native String getName(); - - public native String getLongName(); - - public native String getMimeType(); - - public native String getExtensions(); - - public native int getVideoCodec(); - - public native int getAudioCodec(); - - public native int getSubtitleCodec(); - - public native int getFlags(); - -} diff --git a/src/notzed.jjmpeg/classes/au/notzed/jjmpeg/AVPacket.java b/src/notzed.jjmpeg/classes/au/notzed/jjmpeg/AVPacket.java deleted file mode 100644 index 50ff939..0000000 --- a/src/notzed.jjmpeg/classes/au/notzed/jjmpeg/AVPacket.java +++ /dev/null @@ -1,133 +0,0 @@ -/* - * Copyright (C) 2017 Michael Zucchi - * - * This file is part of jjmpeg - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package au.notzed.jjmpeg; - -import java.nio.ByteBuffer; - -/** - * AVPacket stores compressed stream data. - *

- * This contains some data pointers and is mostly handled by - * libavcodec/libavformat, all we really do is pass them between - * encoders/decoders to/from formats. - */ -public class AVPacket extends AVObject implements Cloneable { - - private AVPacket(long p) { - super(p); - } - - /** - * The packet contains a keyframe - */ - public static final int AV_PKT_FLAG_KEY = 0x0001; - /** - * The packet content is corrupted - */ - public static final int AV_PKT_FLAG_CORRUPT = 0x0002; - /** - * Flag is used to discard packets which are required to maintain valid - * decoder state but are not required for output and should be dropped - * after decoding. - *

- */ - public static final int AV_PKT_FLAG_DISCARD = 0x0004; - /** - * The packet comes from a trusted source. - *

- * Otherwise-unsafe constructs such as arbitrary pointers to data - * outside the packet may be followed. - */ - public static final int AV_PKT_FLAG_TRUSTED = 0x0008; - - /** - * Calls av_packet_free. - * - * @param p - */ - private static native void release(long p); - - /** - * Creates a new packet (initialised) with no data. - * Calls av_packet_alloc - * - * @return - */ - public static native AVPacket alloc(); - - /** - * Retrieve the current data buffer pointer and size. - *

- * This value must not be saved between calls which might update the packet. - * - * @return - */ - public native ByteBuffer getData(); - - /** - * Resize then retrieve the current data buffer pointer and size. - *

- * This will call av_packet_grow() or av_packet_shrink() as necessary - * to set the data size, and will return a reference to it. - * - * @param size - * @return - */ - public native ByteBuffer getData(long size); - - /** - * Clear and free any data pointers and returns the packet to an initialised state. - *

- * It needs to be called ... at certain points I guess. - *

- * This calls av_packet_unref(). - */ - public native void clear(); - - @Override - public native AVPacket clone(); - - public native void rescaleTS(AVRational src, AVRational dst); - - /* */ - public native long getPTS(); - - public native void setPTS(long val); - - public native long getDTS(); - - public native void setDTS(long val); - - public native long getDuration(); - - public native void setDuration(long val); - - public native int getSize(); - - public native int getStreamIndex(); - - public native void setStreamIndex(int val); - - public native int getFlags(); - - public native void setFlags(int mask, int val); - - public native long getPosition(); - -} diff --git a/src/notzed.jjmpeg/classes/au/notzed/jjmpeg/AVPixelFormat.java b/src/notzed.jjmpeg/classes/au/notzed/jjmpeg/AVPixelFormat.java deleted file mode 100644 index b49fcd9..0000000 --- a/src/notzed.jjmpeg/classes/au/notzed/jjmpeg/AVPixelFormat.java +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Copyright (C) 2017 Michael Zucchi - * - * This file is part of jjmpeg - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package au.notzed.jjmpeg; - -/** - */ -public class AVPixelFormat implements AVPixelFormatBits { - - static { - AVObject.init(); - } - - /** - * Call av_get_pix_fmt(name) - */ - public static native int valueOf(String name); - - /** - * Call av_get_pix_fmt_name(value) - */ - public static native String toString(int value); -} diff --git a/src/notzed.jjmpeg/classes/au/notzed/jjmpeg/AVRational.java b/src/notzed.jjmpeg/classes/au/notzed/jjmpeg/AVRational.java deleted file mode 100644 index 3120144..0000000 --- a/src/notzed.jjmpeg/classes/au/notzed/jjmpeg/AVRational.java +++ /dev/null @@ -1,147 +0,0 @@ -/* - * Copyright (c) 2003 Michael Niedermayer - * Copyright (C) 2017 Michael Zucchi - * - * This file is part of jjmpeg - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package au.notzed.jjmpeg; - -/** - * AVRational holds a rational number. - *

- * In previous versions of jjmpeg this was a reference type, it has - * changed to a value type and made a Number. - */ -public class AVRational extends Number implements Comparable { - - public final int num; - public final int den; - - public AVRational(int num, int den) { - this.num = num; - this.den = den; - } - - static { - AVObject.init(); - } - - public AVRational inv() { - return new AVRational(den, num); - } - - /** - * Calls av_d2q - * - * @param d - * @param max - * @return - */ - public static native AVRational d2q(double d, int max); - - /** - * Calls av_rescale(). - * - * @param a - * @param b - * @param c - * @return a * b / c - */ - public static native long rescale(long a, long b, long c); - - /** - * - * @param c - * @return this * c - */ - public native AVRational mul(AVRational c); - - /** - * - * @param c - * @return this / c - */ - public native AVRational div(AVRational c); - - public native AVRational add(AVRational c); - - public native AVRational sub(AVRational c); - - /** - * Calculate ts * (num * scale) / den - * - * @param ts - * @param scale - * @return - */ - public long rescale(long ts, int scale) { - return rescale(ts, num * scale, den); - } - - @Override - public String toString() { - return String.format("%d/%d", num, den); - } - - @Override - public int intValue() { - throw new UnsupportedOperationException(); - } - - @Override - public long longValue() { - throw new UnsupportedOperationException(); - } - - @Override - public float floatValue() { - return (float) num / den; - } - - @Override - public double doubleValue() { - return (double) num / den; - } - - /** - * Compare two rationals. - * - * @param b Second rational - * - * Taken from avutil/rational.c - * - * @return One of the following values: - *

    - *
  • 0 if `a == b` - *
  • 1 if `a > b` - *
  • -1 if `a < b` - *
  • `INT_MIN` if one of the values is of the form `0 / 0` - *
- */ - @Override - public int compareTo(AVRational b) { - long tmp = num * (long) b.den - b.num * (long) den; - - if (tmp != 0) - return (int) ((tmp ^ den ^ b.den) >> 63) | 1; - else if (b.den != 0 && den != 0) - return 0; - else if (num != 0 && b.num != 0) - return (num >> 31) - (b.num >> 31); - else - return Integer.MIN_VALUE; - } -} diff --git a/src/notzed.jjmpeg/classes/au/notzed/jjmpeg/AVSampleFormat.java b/src/notzed.jjmpeg/classes/au/notzed/jjmpeg/AVSampleFormat.java deleted file mode 100644 index 4dc6045..0000000 --- a/src/notzed.jjmpeg/classes/au/notzed/jjmpeg/AVSampleFormat.java +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Copyright (C) 2019 Michael Zucchi - * - * This file is part of jjmpeg - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package au.notzed.jjmpeg; - -/** - */ -public class AVSampleFormat implements AVSampleFormatBits { - - static { - AVObject.init(); - } - - /** - * Call av_get_sample_fmt(name) - */ - public static native int valueOf(String name); - - /** - * Call av_get_sample_fmt_name(value) - */ - public static native String toString(int value); -} diff --git a/src/notzed.jjmpeg/classes/au/notzed/jjmpeg/AVStream.java b/src/notzed.jjmpeg/classes/au/notzed/jjmpeg/AVStream.java deleted file mode 100644 index c38fed1..0000000 --- a/src/notzed.jjmpeg/classes/au/notzed/jjmpeg/AVStream.java +++ /dev/null @@ -1,72 +0,0 @@ -/* - * Copyright (C) 2017 Michael Zucchi - * - * This file is part of jjmpeg - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package au.notzed.jjmpeg; - -/** - * - */ -public class AVStream extends AVObject { - - private AVStream(long p) { - super(p); - } - - public native int getIndex(); - - public native int getID(); - - public native void setID(int id); - - public native AVRational getTimeBase(); - - public native void setTimeBase(AVRational value); - - public native long getStartTime(); - - public native void setStartTime(long val); - - public native long getDuration(); - - public native void setDuration(long val); - - public native long getNumFrames(); - - public native void setNumFrames(long val); - - public native int getDiscard(); - - public native void setDiscard(int val); - - public native AVRational getAverageFrameRate(); - - public native void setAverageFrameRate(AVRational val); - - public native AVRational getSampleAspectRatio(); - - public native void setSampleAspectRatio(AVRational val); - - public native AVRational getDisplayAspectRatio(); - - public native void setDisplayAspectRatio(AVRational val); - - public native AVCodecParameters getCodecParameters(); - - // not sure about this? - public native void setCodecParameters(AVCodecParameters val); -} diff --git a/src/notzed.jjmpeg/classes/au/notzed/jjmpeg/AVUtil.java b/src/notzed.jjmpeg/classes/au/notzed/jjmpeg/AVUtil.java deleted file mode 100644 index 727d838..0000000 --- a/src/notzed.jjmpeg/classes/au/notzed/jjmpeg/AVUtil.java +++ /dev/null @@ -1,106 +0,0 @@ -/* - * Copyright (C) 2017 Michael Zucchi - * - * This file is part of jjmpeg - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package au.notzed.jjmpeg; - -import static java.lang.Math.min; -import java.util.Arrays; -import java.util.logging.Level; -import java.util.logging.LogRecord; -import java.util.logging.Logger; - -/** - * Static methods for other non-class based interfaces. - */ -public class AVUtil { - - static { - AVObject.init(); - } - - /** - * Call av_log_set_callback() with the provided logger. - * - * @param logger Logger callback. Use null to set the default ffmpeg callback. - */ - public native static void setLogger(AVLogger logger); - - /** - * Set log level. - * - * @param level AVLogger.AV_LOG* constants. - */ - public native static void setLogLevel(int level); - - /** - * Get log level. - * - * @return AVLogger.AV_LOG* constants. - */ - public native static int getLogLevel(); - - private static final int levels[] = { - AVLogger.AV_LOG_QUIET, - AVLogger.AV_LOG_PANIC, - AVLogger.AV_LOG_FATAL, - AVLogger.AV_LOG_ERROR, - AVLogger.AV_LOG_WARNING, - AVLogger.AV_LOG_INFO, - AVLogger.AV_LOG_VERBOSE, - AVLogger.AV_LOG_DEBUG, - AVLogger.AV_LOG_TRACE - }; - - private static final Level jlevels[] = { - Level.SEVERE, - Level.SEVERE, - Level.SEVERE, - Level.SEVERE, - Level.WARNING, - Level.INFO, - Level.FINE, - Level.FINER, - Level.FINEST - }; - - public static AVLogger createAVLogger(Logger log) { - return (int l, String what) -> { - int jl = Arrays.binarySearch(levels, l); - - // Map to java.util.logging level - if (jl < 0) - jl = -jl; - jl = min(jl, levels.length - 1); - - if (log.isLoggable(jlevels[jl])) { - LogRecord lr = new LogRecord(jlevels[jl], what); - Throwable t = new Throwable(); - - // Look up the actual method name which logged the message. - // The LogRecord routine will uselessly just find this method instead. - StackTraceElement[] list = t.getStackTrace(); - if (list.length > 1) { - lr.setSourceClassName(list[1].getClassName()); - lr.setSourceMethodName(list[1].getMethodName()); - } - - log.log(lr); - } - }; - } -} diff --git a/src/notzed.jjmpeg/classes/au/notzed/jjmpeg/FramePixelReader.java b/src/notzed.jjmpeg/classes/au/notzed/jjmpeg/FramePixelReader.java new file mode 100644 index 0000000..9540555 --- /dev/null +++ b/src/notzed.jjmpeg/classes/au/notzed/jjmpeg/FramePixelReader.java @@ -0,0 +1,136 @@ +/* + * Copyright (C) 2020 Michael Zucchi + * + * This file is part of jjmpeg + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package au.notzed.jjmpeg; + +import java.nio.Buffer; +import java.nio.ByteBuffer; +import java.nio.BufferOverflowException; +import jdk.incubator.foreign.*; +import au.notzed.nativez.*; + +public class FramePixelReader implements AVPixelReader { + + SwsContext sws; + final AVFrame frame; + final int dwidth, dheight, flags; + int dfmt = -1; + + ResourceScope scope = ResourceScope.newImplicitScope(); + MemorySegment seg; + + public FramePixelReader(AVFrame frame, int dwidth, int dheight, int flags) { + this.frame = frame; + this.dwidth = dwidth; + this.dheight = dheight; + this.flags = flags; + } + + SwsContext getContext(int fmt) { + if (sws == null || fmt != dfmt) { + dfmt = fmt; + if (sws != null) { + //sws.release(); + } + sws = SwsContext.getContext(frame.getWidth(), frame.getHeight(), frame.getFormat(), + dwidth, dheight, dfmt, flags, + null, null, null); + } + return sws; + } + + MemorySegment getSegment(long size) { + if (seg == null || seg.byteSize() < size) { + if (seg != null) { + //Memory.free(seg.baseAddress()); + } + //seg = Memory.ofNative(Memory.malloc(size), size); + seg = MemorySegment.allocateNative(size, 16, scope); + } + return seg; + } + + private void getPixels(int y, int h, int fmt, MemorySegment buffer, int scanlineStride) { + SwsContext ctx = getContext(fmt); + + // FIXME: check sizes + try ( Frame a = Frame.frame()) { + IntArray stride = IntArray.createArray(4, a); + PointerArray data = PointerArray.createArray(4, a); + int res; + + res = AVUtil.av_image_fill_linesizes(stride, fmt, dwidth); + res = AVUtil.av_image_fill_pointers(data, fmt, h, buffer, stride); + + if (res > 0 && res <= buffer.byteSize()) { + ctx.scale( + frame.getData(), + frame.getLinesize(), + y, h, + data, stride); + } else { + throw new BufferOverflowException(); + } + } + } + + public void getPixelsHeap(int y, int h, int fmt, MemorySegment buffer, int scanlineStride) { + MemorySegment dst = getSegment(bufferSize(h, fmt)); + getPixels(y, h, fmt, dst, scanlineStride); + buffer.copyFrom(dst); + } + + public long bufferSize(int h, int fmt) { + try ( Frame a = Frame.frame()) { + IntArray stride = IntArray.createArray(4, a); + PointerArray data = PointerArray.createArray(4, a); + int res; + + res = AVUtil.av_image_fill_linesizes(stride, fmt, dwidth); + res = AVUtil.av_image_fill_pointers(data, fmt, h, null, stride); + + return res; + } + } + + public void getPixels(int y, int h, int fmt, T buffer, int scanlineStride) { + if (buffer.isDirect()) + getPixels(y, h, fmt, MemorySegment.ofByteBuffer((ByteBuffer)buffer), scanlineStride); + else + getPixelsHeap(y, h, fmt, MemorySegment.ofByteBuffer((ByteBuffer)buffer), scanlineStride); + } + + public void getPixels(int y, int h, int fmt, byte[] buffer, int offset, int scanlineStride) { + getPixelsHeap(y, h, fmt, MemorySegment.ofArray(buffer).asSlice(offset), scanlineStride); + } + + public void getPixels(int y, int h, int fmt, short[] buffer, int offset, int scanlineStride) { + getPixelsHeap(y, h, fmt, MemorySegment.ofArray(buffer).asSlice(offset * 2), scanlineStride); + } + + public void getPixels(int y, int h, int fmt, int[] buffer, int offset, int scanlineStride) { + getPixelsHeap(y, h, fmt, MemorySegment.ofArray(buffer).asSlice(offset * 4), scanlineStride); + } + + public void release() { + if (scope != null) { + scope.close(); + scope = null; + } + } +} diff --git a/src/notzed.jjmpeg/classes/au/notzed/jjmpeg/SwsContext.java b/src/notzed.jjmpeg/classes/au/notzed/jjmpeg/SwsContext.java deleted file mode 100644 index 4487e8e..0000000 --- a/src/notzed.jjmpeg/classes/au/notzed/jjmpeg/SwsContext.java +++ /dev/null @@ -1,81 +0,0 @@ -/* - * Copyright (C) 2017 Michael Zucchi - * - * This file is part of jjmpeg - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package au.notzed.jjmpeg; - -import java.nio.ByteBuffer; - -/** - * Software Scaling Operations. - *

- * See also AVFrame.getPixelReader() for a higher level implementation. - *

- * @deprecated Not fully implemented Use {@link AVFrame#getPixelReader} - */ -@Deprecated -public class SwsContext extends AVObject { - - public static final int SWS_FAST_BILINEAR = 1; - public static final int SWS_BILINEAR = 2; - public static final int SWS_BICUBIC = 4; - public static final int SWS_X = 8; - public static final int SWS_POINT = 0x10; - public static final int SWS_AREA = 0x20; - public static final int SWS_BICUBLIN = 0x40; - public static final int SWS_GAUSS = 0x80; - public static final int SWS_SINC = 0x100; - public static final int SWS_LANCZOS = 0x200; - public static final int SWS_SPLINE = 0x400; - // more here - - private SwsContext(long p) { - super(p); - } - - private static native void release(long p); - - public static native int getVersion(); - - public static native String getConfiguration(); - - public static native String getLicense(); - - public native static SwsContext alloc( - int srcW, int srcH, int srcFormat, - int dstW, int dstH, int dstFormat, - int flags, - SwsFilter srcFilter, - SwsFilter dstFilter, - double[] params); - - public native int scale(AVFrame src, int srcSliceY, int srcSliceH, AVFrame dst); - - /* these aren't implemented yet, they need size and stuff passed in */ - public native int scale(AVFrame src, int srcSliceY, int srcSliceH, int[] dst); - - public native int scale(AVFrame src, int srcSliceY, int srcSliceH, byte[] dst); - - public native int scale(byte[] src, int srcSliceY, int srcSliceH, AVFrame dst); - - public native int scale(ByteBuffer src, int srcSliceY, int srcSliceH, AVFrame dst); - - /* - Other than AVFrame<>AVFrame the interfaces above cannot be easily made to work. - - */ -} diff --git a/src/notzed.jjmpeg/classes/au/notzed/jjmpeg/SwsFilter.java b/src/notzed.jjmpeg/classes/au/notzed/jjmpeg/SwsFilter.java deleted file mode 100644 index 186b221..0000000 --- a/src/notzed.jjmpeg/classes/au/notzed/jjmpeg/SwsFilter.java +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright (C) 2017 Michael Zucchi - * - * This file is part of jjmpeg - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package au.notzed.jjmpeg; - -/** - * TODO: fill this out - * - * @deprecated not implemented. - */ -@Deprecated -public class SwsFilter extends AVObject { - - private SwsFilter(long p) { - super(p); - } - - private native static void release(long p); - - public static native SwsFilter create( - float lumaGBlur, float chromaGBlur, - float lumaSharpen, float chromaSharpen, - float chromaHShift, float chromaVShift, - int verbose); - -} diff --git a/src/notzed.jjmpeg/classes/au/notzed/jjmpeg/io/JJMediaReader.java b/src/notzed.jjmpeg/classes/au/notzed/jjmpeg/io/JJMediaReader.java index 41b61bc..241c6e7 100644 --- a/src/notzed.jjmpeg/classes/au/notzed/jjmpeg/io/JJMediaReader.java +++ b/src/notzed.jjmpeg/classes/au/notzed/jjmpeg/io/JJMediaReader.java @@ -23,7 +23,7 @@ import au.notzed.jjmpeg.AVCodecContext; import au.notzed.jjmpeg.AVCodecID; import au.notzed.jjmpeg.AVCodecParameters; import au.notzed.jjmpeg.AVDictionary; -import au.notzed.jjmpeg.AVDiscardBits; +import au.notzed.jjmpeg.AVDiscard; import au.notzed.jjmpeg.AVFormatContext; import au.notzed.jjmpeg.AVFrame; import au.notzed.jjmpeg.AVIOException; @@ -34,10 +34,13 @@ import au.notzed.jjmpeg.AVPixelFormat; import au.notzed.jjmpeg.AVRational; import au.notzed.jjmpeg.AVSampleFormat; import au.notzed.jjmpeg.AVStream; +import au.notzed.nativez.Frame; +import au.notzed.nativez.HandleArray; import java.io.FileNotFoundException; import java.util.AbstractList; import java.util.List; import java.util.logging.Logger; +import jdk.incubator.foreign.ResourceScope; /** * High level interface for scanning audio and video frames. @@ -107,12 +110,12 @@ public class JJMediaReader implements AutoCloseable { * @see #getStreams * @see #readFrame */ - public JJMediaReader(String name) throws AVIOException, FileNotFoundException { - this(name, null, null); + public JJMediaReader(String name, ResourceScope scope) throws AVIOException, FileNotFoundException { + this(name, null, null, scope); } - public JJMediaReader(String name, AVInputFormat fmt, AVDictionary options) throws AVIOException, FileNotFoundException { - this(AVFormatContext.openInput(name, fmt, options)); + public JJMediaReader(String name, AVInputFormat fmt, HandleArray options, ResourceScope scope) throws AVIOException, FileNotFoundException { + this(AVFormatContext.openInput(name, fmt, options, scope)); } public JJMediaReader(AVFormatContext format) throws AVIOException { @@ -126,8 +129,9 @@ public class JJMediaReader implements AutoCloseable { // find all streams and map to something int nstreams = format.getNumStreams(); JJReaderStream[] list = new JJReaderStream[nstreams]; + HandleArray stream = format.getStreams(); for (int i = 0; i < nstreams; i++) { - AVStream s = format.getStream(i); + AVStream s = stream.get(i); AVCodecParameters cp = s.getCodecParameters(); switch (cp.getCodecType()) { case AVMediaType.AVMEDIA_TYPE_VIDEO: @@ -138,7 +142,7 @@ public class JJMediaReader implements AutoCloseable { break; default: list[i] = new JJReaderUnknown(s, cp); - s.setDiscard(AVDiscardBits.AVDISCARD_ALL); + s.setDiscard(AVDiscard.AVDISCARD_ALL); break; } } @@ -206,8 +210,8 @@ public class JJMediaReader implements AutoCloseable { for (JJReaderStream m: streams) { m.release(); } - format.release(); - packet.release(); + format.close(); + packet.free();; } /** @@ -338,7 +342,7 @@ public class JJMediaReader implements AutoCloseable { } freePacket = false; - while (format.readFrame(packet)) { + while (format.readFrame(packet) == 0) { try { int index = packet.getStreamIndex(); JJReaderStream ms = streams.get(index); @@ -398,7 +402,7 @@ public class JJMediaReader implements AutoCloseable { long duration; long durationms; // Raw decoded frame - final AVFrame frame; + AVFrame frame; // Incremented every time a frame is decoded long frameIndex; // Some formats (mpeg?) always seek to the next keyframe, which is really not desirable. @@ -427,9 +431,12 @@ public class JJMediaReader implements AutoCloseable { duration = stream.getDuration(); durationms = tb.rescale(duration, 1000); - // conservatively assume keyframe every 32 frames - seekOffsetMS = stream.getAverageFrameRate().inv().rescale(1000, 32); - seekOffset = (long) tb.inv().mul(new AVRational((int) seekOffsetMS, 1000)).doubleValue(); + try ( Frame f = Frame.frame()) { + + // conservatively assume keyframe every 32 frames + seekOffsetMS = stream.getAverageFrameRate().inv(f).rescale(1000, 32); + seekOffset = (long)tb.inv(f).mul(AVRational.create((int)seekOffsetMS, 1000, f), f).doubleValue(); + } } public void open() throws AVIOException { @@ -441,13 +448,14 @@ public class JJMediaReader implements AutoCloseable { } public void release() { - if (codec != null) { - codec.release(); - c.release(); + if (c != null) { + c.free(); + c = null; + } + if (frame != null) { + frame.free(); + frame = null; } - if (frame != null) - frame.release(); - stream.release(); } /** @@ -548,7 +556,7 @@ public class JJMediaReader implements AutoCloseable { } c.sendPacket(packet); - done = c.receiveFrame(frame); + done = c.receiveFrame(frame) == 0; frameIndex += 1; } @@ -631,21 +639,13 @@ public class JJMediaReader implements AutoCloseable { + " codec %s\n", cp.getWidth(), cp.getHeight(), - AVPixelFormat.toString(cp.getPixelFormat()), - cp.getAspectRatio(), + AVPixelFormat.toString(cp.getFormat()), + cp.getSampleAspectRatio(), AVCodecID.toString(cp.getCodecID()))); super.open(); } - @Override - public void release() { - super.release(); - - if (c != null) - c.release(); - } - @Override public int getType() { return AVMediaType.AVMEDIA_TYPE_VIDEO; @@ -667,7 +667,7 @@ public class JJMediaReader implements AutoCloseable { public String toString() { AVRational fr = stream.getAverageFrameRate(); - return String.format("[Video %6.3fs %dx%d @ %d/%d %s]", getDurationMS() * 1E-3, cp.getWidth(), cp.getHeight(), fr.num, fr.den, AVPixelFormat.toString(cp.getPixelFormat())); + return String.format("[Video %6.3fs %dx%d @ %d/%d %s]", getDurationMS() * 1E-3, cp.getWidth(), cp.getHeight(), fr.getNum(), fr.getDen(), AVPixelFormat.toString(cp.getFormat())); } } @@ -683,9 +683,9 @@ public class JJMediaReader implements AutoCloseable { -> String.format("Open audio reader\n" + " audio x%d %dHz %s\n" + " codec %s\n", - cp.getNumChannels(), + cp.getChannels(), cp.getSampleRate(), - AVSampleFormat.toString(cp.getSampleFormat()), + AVSampleFormat.toString(cp.getFormat()), AVCodecID.toString(cp.getCodecID()))); super.open(); @@ -705,7 +705,7 @@ public class JJMediaReader implements AutoCloseable { } public int getNumChannels() { - return c.getNumChannels(); + return c.getChannels(); } public long getChannelLayout() { @@ -714,7 +714,7 @@ public class JJMediaReader implements AutoCloseable { @Override public String toString() { - return String.format("[Audio %d @ %dHz %s]", cp.getNumChannels(), cp.getSampleRate(), AVSampleFormat.toString(cp.getSampleFormat())); + return String.format("[Audio %d @ %dHz %s]", cp.getChannels(), cp.getSampleRate(), AVSampleFormat.toString(cp.getFormat())); } } } diff --git a/src/notzed.jjmpeg/classes/au/notzed/jjmpeg/io/JJMediaWriter.java b/src/notzed.jjmpeg/classes/au/notzed/jjmpeg/io/JJMediaWriter.java index 4c43f7d..30e1667 100644 --- a/src/notzed.jjmpeg/classes/au/notzed/jjmpeg/io/JJMediaWriter.java +++ b/src/notzed.jjmpeg/classes/au/notzed/jjmpeg/io/JJMediaWriter.java @@ -37,14 +37,17 @@ import au.notzed.jjmpeg.AVPacket; import au.notzed.jjmpeg.AVRational; import au.notzed.jjmpeg.AVStream; import au.notzed.jjmpeg.AVError; +import au.notzed.jjmpeg.AVFormat; import au.notzed.jjmpeg.AVIOContext; import au.notzed.jjmpeg.AVPixelFormat; import au.notzed.jjmpeg.AVIOException; import au.notzed.jjmpeg.AVMediaType; import au.notzed.jjmpeg.AVSampleFormat; +import au.notzed.nativez.Frame; import java.util.ArrayList; import java.util.List; import java.util.logging.Logger; +import jdk.incubator.foreign.ResourceScope; /** * High level media file writer interface. @@ -69,10 +72,10 @@ public class JJMediaWriter implements AutoCloseable { * * @param filename */ - public JJMediaWriter(String filename) throws AVIOException { + public JJMediaWriter(String filename, ResourceScope scope) throws AVIOException { this.filename = filename; - oc = AVFormatContext.allocContext(null, null, filename); + oc = AVFormatContext.allocOutputContext(null, null, filename, scope); } /** @@ -92,7 +95,7 @@ public class JJMediaWriter implements AutoCloseable { public void open() throws AVIOException { /* now that all the parameters are set, we can open the audio and video codecs and allocate the necessary encode buffers */ - for (JJWriterStream sd : streams) { + for (JJWriterStream sd: streams) { sd.open(); } @@ -138,7 +141,7 @@ public class JJMediaWriter implements AutoCloseable { c.setCodecID(codec.getID()); c.setCodecType(codec.getType()); - if ((oc.getOutputFormat().getFlags() & AVOutputFormat.AVFMT_GLOBALHEADER) != 0) + if ((oc.getOutputFormat().getFlags() & AVFormat.AVFMT_GLOBALHEADER) != 0) c.setFlags(AVCodecContext.AV_CODEC_FLAG_GLOBAL_HEADER, AVCodecContext.AV_CODEC_FLAG_GLOBAL_HEADER); vs = new JJWriterVideo(st, c); @@ -169,22 +172,24 @@ public class JJMediaWriter implements AutoCloseable { * @throws au.notzed.jjmpeg.AVIOException on error */ public JJWriterVideo addVideoStream(AVCodec codec, int streamid, int pixel_format, int width, int height, AVRational frame_rate, long bit_rate) throws AVIOException { - JJWriterVideo sd = addVideoStream(codec, streamid); + try (Frame frame = Frame.frame()) { + JJWriterVideo sd = addVideoStream(codec, streamid); - /* Initialise provided parameters */ - AVCodecContext c = sd.c; - AVStream st = sd.stream; + /* Initialise provided parameters */ + AVCodecContext c = sd.c; + AVStream st = sd.stream; - c.setWidth(width); - c.setHeight(height); + c.setWidth(width); + c.setHeight(height); - st.setAverageFrameRate(frame_rate); - sd.setTimeBase(new AVRational(frame_rate.den, frame_rate.num)); + st.setAverageFrameRate(frame_rate); + sd.setTimeBase(frame_rate.inv(frame)); - c.setBitRate(bit_rate); - c.setPixelFormat(pixel_format); + c.setBitRate(bit_rate); + c.setPixelFormat(pixel_format); - return sd; + return sd; + } } public JJWriterAudio addAudioStream(AVCodec codec, int streamid) throws AVIOException { @@ -209,7 +214,7 @@ public class JJMediaWriter implements AutoCloseable { c.setCodecID(codec.getID()); c.setCodecType(codec.getType()); - if ((oc.getOutputFormat().getFlags() & AVOutputFormat.AVFMT_GLOBALHEADER) != 0) + if ((oc.getOutputFormat().getFlags() & AVFormat.AVFMT_GLOBALHEADER) != 0) c.setFlags(AVCodecContext.AV_CODEC_FLAG_GLOBAL_HEADER, AVCodecContext.AV_CODEC_FLAG_GLOBAL_HEADER); as = new JJWriterAudio(st, c); @@ -242,14 +247,14 @@ public class JJMediaWriter implements AutoCloseable { c.setBitRate(bit_rate); c.setSampleRate(sample_rate); - c.setNumChannels(AVChannelLayout.getNumChannels(layout)); + c.setChannels(AVChannelLayout.getNumChannels(layout)); c.setChannelLayout(layout); return as; } public void flush() throws AVIOException { - for (JJWriterStream sd : streams) { + for (JJWriterStream sd: streams) { sd.writeFrame(null); } } @@ -268,12 +273,12 @@ public class JJMediaWriter implements AutoCloseable { oc.writeTrailer(); } - for (JJWriterStream sd : streams) { + for (JJWriterStream sd: streams) { sd.close(); } /* free the stream */ - oc.release(); + oc.free(); } public abstract class JJWriterStream { @@ -364,16 +369,15 @@ public class JJMediaWriter implements AutoCloseable { * @throws AVIOException on error. */ public void writeFrame(AVFrame frame) throws AVIOException { - if (c.sendFrame(frame)) { - while (c.receivePacket(packet)) { + if (c.sendFrame(frame) == 0) { + while (c.receivePacket(packet) == 0) { writePacket(packet); } } } void close() { - stream.release(); - packet.release(); + packet.free(); } } @@ -400,7 +404,7 @@ public class JJMediaWriter implements AutoCloseable { AVCodec.findEncoder(c.getCodecID()).getName(), c.getBitRate(), c.getWidth(), c.getHeight(), AVPixelFormat.toString(c.getPixelFormat()), - c.getAspectRatio())); + c.getSampleAspectRatio())); } public void setWidth(int width) { @@ -423,7 +427,7 @@ public class JJMediaWriter implements AutoCloseable { void close() { super.close(); - frame.release(); + frame.free(); } public AVFrame getFrame() { @@ -461,7 +465,7 @@ public class JJMediaWriter implements AutoCloseable { } public void setNumChannels(int channels) { - c.setNumChannels(channels); + c.setChannels(channels); } public void setChannelLayout(long layout) { @@ -477,14 +481,14 @@ public class JJMediaWriter implements AutoCloseable { } // ??? unchecked - frame = AVFrame.alloc(c.getSampleFormat(), c.getNumChannels(), 2048); + frame = AVFrame.alloc(c.getSampleFormat(), c.getChannels(), 2048); Logger.getLogger("jjmpeg.io") .fine(() -> String.format("open audio stream %s %d [x%d %dHz %s]\n", AVCodec.findEncoder(c.getCodecID()).getName(), c.getBitRate(), - c.getNumChannels(), c.getSampleRate(), AVSampleFormat.toString(c.getSampleFormat()))); + c.getChannels(), c.getSampleRate(), AVSampleFormat.toString(c.getSampleFormat()))); } @Override diff --git a/src/notzed.jjmpeg/classes/module-info.java b/src/notzed.jjmpeg/classes/module-info.java index ee36244..3ddf766 100644 --- a/src/notzed.jjmpeg/classes/module-info.java +++ b/src/notzed.jjmpeg/classes/module-info.java @@ -18,10 +18,8 @@ */ module notzed.jjmpeg { requires java.logging; - requires notzed.nativez; - + requires transitive notzed.nativez; + exports au.notzed.jjmpeg; exports au.notzed.jjmpeg.io; - - opens au.notzed.jjmpeg to notzed.nativez; } diff --git a/src/notzed.jjmpeg/gen/ffmpeg.api b/src/notzed.jjmpeg/gen/ffmpeg.api new file mode 100644 index 0000000..86d1a23 --- /dev/null +++ b/src/notzed.jjmpeg/gen/ffmpeg.api @@ -0,0 +1,546 @@ +# -*- Mode:text; tab-width:4; electric-indent-mode: nil; indent-line-function:insert-tab; -*- + +%include code.api; +%include types.api; + +struct field:rename=studly-caps default=all func:rename=camel-case access=rw { +} + +struct AVFormatContext default=none func:rename=s/^(avformat_|av_)//,camel-case field:rename=studly-caps { + iformat access=r rename=InputFormat; + oformat access=r rename=OutputFormat; + pb rename=IOContext; + + ctx_flags access=r; + nb_streams access=r rename=NumStreams; + + streams array-size=nb_streams array; + + start_time access=r; + duration access=r; + bit_rate access=r; + + interrupt_callback; + + # maybe close, free should be closeInput, freeContext + func:avformat_open_input scope:0=explicit success:result$=0 return:0 array:options; + func:avformat_close_input raw-in:0 rename=close; + + func:avformat_find_stream_info instance:0; + func:av_read_frame instance:0; + + func:avformat_alloc_output_context2 scope:0=explicit return:0 rename=allocOutputContext; + func:avformat_free_context raw:0 rename=free; + + func:avformat_seek_file instance:0; + + func:avformat_new_stream instance:0; + func:avformat_write_header instance:0 array:options; + func:av_interleaved_write_frame instance:0; + func:av_write_trailer instance:0; + + code: {{ + // not relly ideal but it'll do + public void free() { free(segment.address()); } + public void close() { close(segment.address()); } + }} +} + +struct AVStream default=none field:rename=studly-caps { + index access=r; + id rename=ID; + time_base; + start_time; + duration; + nb_frames rename=NumFrames; + discard; + avg_frame_rate rename=AverageFrameRate; + sample_aspect_ratio; + codecpar rename=CodecParameters; + + code: {{ + final static VarHandle avg_frame_rate$num$VH = LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("avg_frame_rate"), MemoryLayout.PathElement.groupElement("num")); + final static VarHandle avg_frame_rate$den$VH = LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("avg_frame_rate"), MemoryLayout.PathElement.groupElement("den")); + public void setAverageFrameRate(AVRational b) { + avg_frame_rate$num$VH.set(segment, b.getNum()); + avg_frame_rate$den$VH.set(segment, b.getDen()); + } + final static VarHandle time_base$num$VH = LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("time_base"), MemoryLayout.PathElement.groupElement("num")); + final static VarHandle time_base$den$VH = LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("time_base"), MemoryLayout.PathElement.groupElement("den")); + public void setTimeBase(AVRational b) { + time_base$num$VH.set(segment, b.getNum()); + time_base$den$VH.set(segment, b.getDen()); + } + }} +} + +enum AVDiscard; + +struct AVCodec access=r default=none func:rename=s/^avcodec_//,camel-case field:rename=studly-caps { + id rename=ID; + name; + long_name; + type; + capabilities; + max_lowres; + # need some sort of length=null-terminated here i suppose; + supported_framerates rename=framerates; + pix_fmts rename=pixelFormats; + + func:av_codec_next rename=next; + func:avcodec_find_decoder ; + func:avcodec_find_decoder_by_name ; + func:avcodec_find_encoder ; + func:avcodec_find_encoder_by_name ; + + define:AVCodecBits; +} + +struct AVCodecContext default=none func:rename=s/^avcodec_//,camel-case field:rename=studly-caps { + codec_type; + codec_id rename=CodecID; + bit_rate; + global_quality; + + flags; + flags2; + + time_base; + + skip_loop_filter; + skip_idct; + skip_frame; + width; + height; + sample_aspect_ratio; + pix_fmt rename=PixelFormat; + sample_fmt rename=SampleFormat; + sample_rate; + channels; + channel_layout; + frame_size access=r; + frame_number access=r; + + func:avcodec_alloc_context3 rename=allocContext; + func:avcodec_open2 instance:0 rename=open; + func:avcodec_send_packet instance:0; + func:avcodec_receive_packet instance:0; + func:avcodec_send_frame instance:0; + func:avcodec_receive_frame instance:0; + func:avcodec_free_context ; + func:avcodec_flush_buffers instance:0; + + define:AVCodecContextBits; + + code: {{ + public void setFlags(int flags, int mask) { + setFlags((getFlags() & ~mask) | (mask & flags)); + } + public void setFlags2(int flags, int mask) { + setFlags2((getFlags2() & ~mask) | (mask & flags)); + } + final static VarHandle time_base$num$VH = LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("time_base"), MemoryLayout.PathElement.groupElement("num")); + final static VarHandle time_base$den$VH = LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("time_base"), MemoryLayout.PathElement.groupElement("den")); + public void setTimeBase(AVRational b) { + time_base$num$VH.set(segment, b.getNum()); + time_base$den$VH.set(segment, b.getDen()); + } + public void free() { + try (Frame frame = Frame.frame()) { + PointerArray holder = PointerArray.createArray(1, frame); + holder.set(0, segment.address()); + freeContext(holder); + } + } + }} +} + +struct AVFrame default=all func:rename=s/^av_frame_//,camel-case field:rename=studly-caps { + func:av_frame_alloc; + func:av_frame_free rename=freeFrame; + func:av_frame_get_buffer instance:0; + + code: {{ + public static AVFrame alloc(int format, int width, int height) { + AVFrame frame = alloc(); + frame.setFormat(format); + frame.setWidth(width); + frame.setHeight(height); + if (frame.getBuffer(0) == 0) + return frame; + frame.free(); + throw new RuntimeException("Allocating video frame data"); + } + public void free() { + try (Frame frame = Frame.frame()) { + PointerArray holder = PointerArray.createArray(1, frame); + holder.set(0, segment.address()); + freeFrame(holder); + } + } + public AVPixelReader createPixelReader(int w, int h, int flags) { + return new FramePixelReader(this, w, h, 0); + } + public AVSampleReader createSampleReader(long layout, int fmt, int sampleRate) { + throw new UnsupportedOperationException(); + } + }} +} + +struct AVFrameSideData default=none { + enum:AVFrameSideDataType; + + func:av_frame_side_data_name rename=typeToString; +} + +struct AVRational field:rename=studly-caps { + func:av_rescale; + func:av_mul_q rename=mul; + + code: {{ + public AVRational mul(AVRational b, SegmentAllocator frame) { + return AVRational.mul(this, b, frame); + } + public void set(int num, int den) { + setNum(num); + setDen(den); + } + public void set(AVRational b) { + setNum(b.getNum()); + setDen(b.getDen()); + } + public static AVRational create(int num, int den, SegmentAllocator frame) { + AVRational rat = create(frame); + rat.setNum(num); + rat.setDen(den); + return rat; + } + + public long rescale(long ts, int scale) { + return av_rescale(ts, scale * getNum(), getDen()); + } + + public AVRational inv(SegmentAllocator alloc) { + AVRational dst = AVRational.create(alloc); + + dst.setNum(getDen()); + dst.setDen(getNum()); + return dst; + } + + public double doubleValue() { + return (double)getNum() / (double)getDen(); + } + + public float floatValue() { + return (float)getNum() / (float)getDen(); + } + }} +} + +struct AVCodecParameters func:rename=s/^avcodec_parameters_//,camel-case field:rename=studly-caps { + codec_id rename=CodecID; + + func:avcodec_parameters_alloc; + func:avcodec_parameters_free instance:0; + func:avcodec_parameters_copy instance:0; + func:avcodec_parameters_to_context instance:1; + func:avcodec_parameters_from_context instance:0; +} + +struct AVPacket default=all func:rename=s/^av_packet_//,camel-case field:rename=studly-caps { + pts|dts rename=upper-leadin; + data array-size=size; + + func:av_packet_alloc; + func:av_packet_free rename=freePacket; + func:av_init_packet instance:0 rename=init; + + func:av_packet_rescale_ts instance:0 rename=rescaleTS; + + func:av_packet_unref instance:0 rename=clear; + code: {{ + public void free() { + try (Frame frame = Frame.frame()) { + PointerArray holder = PointerArray.createArray(1, frame); + holder.set(0, segment.address()); + freePacket(holder); + } + } + }} +} + +library AVSampleFormat { + enum:AVSampleFormat; + av_get_sample_fmt rename=valueOf; + av_get_sample_fmt_name rename=toString; +} + +struct SwsContext func:rename=s/^sws_// { +# func:/sws_/; + func:sws_getContext; + func:sws_freeContext instance:0; + func:sws_scale instance:0; + + define:sws; +} + +struct SwsFilter { +} +struct SwsVector { +} +struct AVPixFmtDescriptor { +} +struct AVComponentDescriptor access=rwi { +} + +define AVLoggerBits ffmpeg.h { + /^AV_LOG_/ i32; +} + +# TODO: rename args doesn't work yet +call (u64:vi32u64:i8u64:${__va_list_tag})v access=rw rename=AVLogFunc { + arg$0 rename=avcl; + arg$1 rename=level; + arg$2 raw rename=fmt; + arg$3 raw rename=valist; +} + +library AVUtil + import=java.util.Arrays,java.util.logging.Level,java.util.logging.LogRecord,java.util.logging.Logger { + av_image_copy_plane segment:src segment:dst; + av_image_copy_to_buffer segment:dst; + av_image_fill_arrays segment:src; + av_image_fill_pointers segment:ptr; + /av_image_/; + av_log_set_callback; + av_log_format_line2 raw:fmt raw:vl array:line implied:line_size=line.size(); + + code: {{ + private static final int levels[] = { + AVLogger.AV_LOG_QUIET, + AVLogger.AV_LOG_PANIC, + AVLogger.AV_LOG_FATAL, + AVLogger.AV_LOG_ERROR, + AVLogger.AV_LOG_WARNING, + AVLogger.AV_LOG_INFO, + AVLogger.AV_LOG_VERBOSE, + AVLogger.AV_LOG_DEBUG, + AVLogger.AV_LOG_TRACE + }; + + private static final Level jlevels[] = { + Level.SEVERE, + Level.SEVERE, + Level.SEVERE, + Level.SEVERE, + Level.WARNING, + Level.INFO, + Level.FINE, + Level.FINER, + Level.FINEST + }; + + public static AVLogger createAVLogger(Logger log) { + return (int l, String what) -> { + int jl = Arrays.binarySearch(levels, l); + + // Map to java.util.logging level + if (jl < 0) + jl = -jl; + jl = Math.min(jl, levels.length - 1); + + if (log.isLoggable(jlevels[jl])) { + LogRecord lr = new LogRecord(jlevels[jl], what); + Throwable t = new Throwable(); + + // Look up the actual method name which logged the message. + // The LogRecord routine will uselessly just find this method instead. + StackTraceElement[] list = t.getStackTrace(); + if (list.length > 1) { + lr.setSourceClassName(list[1].getClassName()); + lr.setSourceMethodName(list[1].getMethodName()); + } + + log.log(lr); + } + }; + } + + public static void setLogger(AVLogger log, ResourceScope scope) { + AVUtil.av_log_set_callback(AVLogFunc.upcall((avcl, level, fmt, valist) -> { + try (Frame frame = Frame.frame()) { + ByteArray line = ByteArray.createArray(1024, frame); + IntArray print_prefix = IntArray.create(frame, 1); + AVUtil.av_log_format_line2(avcl, level, fmt, valist, line, print_prefix); + log.log(level, line.toUtf8String()); + } + }, scope)); + } + }} +} + +library AVPixelFormat { + enum:AVPixelFormat; + + av_get_pix_fmt rename=valueOf; + av_get_pix_fmt_name rename=toString; +} + +library AVCodecID { + enum:AVCodecID; + + avcodec_get_name rename=toString; + avcodec_get_type rename=getType; +} + +struct AVProbeData default=none field:rename=studly-caps { +} + +struct AVBufferRef access=rwi default=none { +} +struct AVPacketSideData default=none { +} + +call (u64:vu64:u8i32)i32 rename=data_func access=w; +call (u64:vi64i32)i64 rename=seek_func access=w; + +struct AVIOContext default=none { + define:AVIOContextBits; + func:avio_alloc_context; + func:avio_context_free; + func:avio_open2 return:0 rename=open array:options ; # scope:0=explicit; + func:avio_close; +} +struct AVIOInterruptCB default=none { +} + +struct AVDictionaryEntry { +} + +struct AVDictionary func:rename=s/^av_dict_//,camel-case { + define:dict; + func:/av_dict_/; +} + +library AVFormat { + define:AVFormatBits; +} + +struct AVInputFormat default=none access=r field:rename=studly-caps { + name; + long_name; + flags; + extensions; + mime_type; + + func:av_demuxer_iterate rename=next; + func:av_register_input_format instance:0 rename=register; + func:av_find_input_format rename=find; +} + +struct AVOutputFormat default=none access=r field:rename=studly-caps { + name; + long_name; + mime_type; + flags; + extensions; + audio_codec; + video_codec; + subtitle_codec; + + func:av_muxer_iterate rename=next; +} + +library AVChannelLayout { + define:AVChannelLayoutBits; + + av_get_channel_layout rename=valueOf; + av_get_channel_name rename=toString; + av_get_channel_layout_nb_channels rename=getNumChannels; + av_get_default_channel_layout rename=getDefaultLayout; +} + +library AVDevice { + avdevice_version rename=getVersion; + avdevice_configuration rename=getConfiguration; + avdevice_license rename=getLicense; + avdevice_register_all rename=registerAll; + av_input_audio_device_next rename=nextAudioInputDevice; + av_input_video_device_next rename=nextVideoInputDevice; + av_output_audio_device_next rename=nextAudioOutputDevice; + av_output_video_device_next rename=nextVideoOutputDevice; + + code: {{ + public static Iterable audioInputDevices() { + return () -> new AVObjectIterator<>(AVDevice::nextAudioInputDevice); + } + + public static Iterable videoInputDevices() { + return () -> new AVObjectIterator<>(AVDevice::nextVideoInputDevice); + } + + public static Iterable audioOutputDevices() { + return () -> new AVObjectIterator<>(AVDevice::nextAudioOutputDevice); + } + + public static Iterable videoOutputDevices() { + return () -> new AVObjectIterator<>(AVDevice::nextVideoOutputDevice); + } + }} +} + +# exception? +library AVError { + define:AVErrorBits; + av_strerror segment:errbuf implied:errbuf_size=Memory.size(errbuf); + code: {{ + public static String toString(int errnum) { + try (Frame frame = Frame.frame()) { + MemorySegment errbuf = frame.allocate(AV_ERROR_MAX_STRING_SIZE); + + av_strerror(errnum, errbuf); + + return errbuf.getUtf8String(0L); + } + } + }} +} + +define dict ffmpeg.h { + /AV_DICT_/; +} + +define AVChannelLayoutBits ffmpeg.h { + /^AV_CH_LAYOUT_/ x64; +} + +define AVErrorBits ffmpeg.h { + /^AVERROR_/ x32; + AV_ERROR_MAX_STRING_SIZE; +} + +define AVCodecContextBits ffmpeg.h { + /^AV_CODEC_FLAG_|AV_CODEC_FLAG2_/ u32; + /^AV_INPUT_BUFFER_/ i32; +} + +define AVCodecBits ffmpeg.h { + /^AV_CODEC_CAP_/ x32; +} + +define AVIOContextBits ffmpeg.h { + /^AVSEEK_|AVIO_FLAG_|AVIO_SEEKABLE_/; +} + +define AVFormatBits ffmpeg.h { + /^AVFMT_/; +} + +define AVOptionsBits ffmpeg.h { + /^AV_OPT_/; +} + +define sws ffmpeg.h { + /^SWS_/; +} diff --git a/src/notzed.jjmpeg/gen/ffmpeg.h b/src/notzed.jjmpeg/gen/ffmpeg.h new file mode 100644 index 0000000..c9e0b31 --- /dev/null +++ b/src/notzed.jjmpeg/gen/ffmpeg.h @@ -0,0 +1,10 @@ + +#include +#include +#include +#include +#include +#include +#include + +#include diff --git a/src/notzed.jjmpeg/gen/gen.make b/src/notzed.jjmpeg/gen/gen.make index 296573b..9c84020 100644 --- a/src/notzed.jjmpeg/gen/gen.make +++ b/src/notzed.jjmpeg/gen/gen.make @@ -1,102 +1,3 @@ -# -# Copyright (C) 2017 Michael Zucchi -# -# This file is part of jjmpeg -# -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . -# -extract_enum=src/notzed.jjmpeg/gen/extract-enum.pl -extract_defines=src/notzed.jjmpeg/gen/extract-defines.pl - -# Relative to module! -notzed.jjmpeg_JAVA_GENERATED = \ - au/notzed/jjmpeg/AVChannelLayoutBits.java \ - au/notzed/jjmpeg/AVCodecBits.java \ - au/notzed/jjmpeg/AVCodecContextBits.java \ - au/notzed/jjmpeg/AVCodecIDBits.java \ - au/notzed/jjmpeg/AVDiscardBits.java \ - au/notzed/jjmpeg/AVErrorBits.java \ - au/notzed/jjmpeg/AVFrameSideDataTypeBits.java \ - au/notzed/jjmpeg/AVIOContextBits.java \ - au/notzed/jjmpeg/AVMediaTypeBits.java \ - au/notzed/jjmpeg/AVOptionsBits.java \ - au/notzed/jjmpeg/AVPixelFormatBits.java \ - au/notzed/jjmpeg/AVSampleFormatBits.java - -HOST_CC=cc -HOST_CPPFLAGS=-I$(FFMPEG_HOME)/include - -$(notzed.jjmpeg_genjavadir)/%.java: $(notzed.jjmpeg_gendir)/%-gen - @install -d $(@D) - $< > $@ || ( rm $@ ; exit 1) - -$(notzed.jjmpeg_gendir)/%-gen: $(notzed.jjmpeg_gendir)/%-gen.c - $(HOST_CC) $(HOST_CPPFLAGS) -o $@ $< - -# dependent on itself as it contains buisiness logic in the rules -tmp:=$(notzed.jjmpeg_gendir)/au/notzed/jjmpeg -dep:=src/notzed.jjmpeg/gen/gen.make - -$(tmp)/AVCodecIDBits-gen.c: $(extract_enum) $(dep) - @install -d $(@D) - perl $(extract_enum) -I$(FFMPEG_HOME)/include AVCodecID AV_CODEC_ID_ $(FFMPEG_HOME)/include/libavcodec/avcodec.h $@ - -$(tmp)/AVPixelFormatBits-gen.c: $(extract_enum) $(dep) - @install -d $(@D) - perl $(extract_enum) -I$(FFMPEG_HOME)/include AVPixelFormat AV_PIX_FMT_ $(FFMPEG_HOME)/include/libavutil/pixfmt.h $@ - -$(tmp)/AVSampleFormatBits-gen.c: $(extract_enum) $(dep) - @install -d $(@D) - perl $(extract_enum) -I$(FFMPEG_HOME)/include AVSampleFormat AV_SAMPLE_FMT_ $(FFMPEG_HOME)/include/libavutil/samplefmt.h $@ - -$(tmp)/AVMediaTypeBits-gen.c: $(extract_enum) $(dep) - @install -d $(@D) - perl $(extract_enum) -I$(FFMPEG_HOME)/include AVMediaType AVMEDIA_TYPE_ $(FFMPEG_HOME)/include/libavutil/avutil.h $@ - -$(tmp)/AVDiscardBits-gen.c: $(extract_enum) $(dep) - @install -d $(@D) - perl $(extract_enum) -I$(FFMPEG_HOME)/include AVDiscard AVDISCARD_ $(FFMPEG_HOME)/include/libavcodec/avcodec.h $@ - -$(tmp)/AVFrameSideDataTypeBits-gen.c: $(extract_defines) $(dep) - @install -d $(@D) - perl $(extract_enum) -I$(FFMPEG_HOME)/include AVFrameSideDataType AV_FRAME_ $(FFMPEG_HOME)/include/libavutil/frame.h $@ - -$(tmp)/AVChannelLayoutBits-gen.c: $(extract_enum) $(dep) - @install -d $(@D) - perl $(extract_defines) -f $(FFMPEG_HOME) -interface AVChannelLayoutBits -header libavutil/channel_layout.h -type long -d AV_CH_LAYOUT_ $@ - -$(tmp)/AVErrorBits-gen.c: $(extract_defines) $(dep) - @install -d $(@D) - perl $(extract_defines) -f $(FFMPEG_HOME) -interface AVErrorBits -header libavutil/avutil.h -d AVERROR_ $@ - -$(tmp)/AVCodecContextBits-gen.c: $(extract_defines) $(dep) - @install -d $(@D) - perl $(extract_defines) -c -f ${FFMPEG_HOME} \ - -interface AVCodecContextBits -header libavcodec/avcodec.h \ - -type long -d AV_CODEC_FLAG_ -shift "<<32" -d AV_CODEC_FLAG2_ \ - -shift "" -type int -d AV_INPUT_BUFFER_ \ - $@ - -$(tmp)/AVCodecBits-gen.c: $(extract_defines) $(dep) - @install -d $(@D) - perl $(extract_defines) -c -interface AVCodecBits -f $(FFMPEG_HOME) -header libavcodec/avcodec.h -d AV_CODEC_CAP_ $@ - -$(tmp)/AVIOContextBits-gen.c: $(extract_defines) $(dep) - @install -d $(@D) - perl $(extract_defines) -c -interface AVIOContextBits -f $(FFMPEG_HOME) -header libavformat/avio.h -d AVSEEK_ -d AVIO_FLAG_ -d AVIO_SEEKABLE_ $@ - -$(tmp)/AVOptionsBits-gen.c: $(extract_defines) $(dep) - @install -d $(@D) - perl $(extract_defines) -interface AVOptionsBits -f $(FFMPEG_HOME) -header libavutil/opt.h -d AV_OPT_ $@ +notzed.jjmpeg_API = ffmpeg +notzed.jjmpeg_APIFLAGS = -t au.notzed.jjmpeg -I$(FFMPEG_HOME)/include -Isrc/notzed.jjmpeg/gen