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
#
-# Copyright (C) 2019 Michael Zucchi
+# Copyright (C) 2019,2022 Michael Zucchi
#
# This is the copyright for java.make
#
# generators must exist in src/<module>/gen. Native
# libraries must exist in src/<module>/jni.
+# native_MODULES list of native-only "modules".
+
+
# Global variables
# JAVA_HOME location of jdk.
# JARFLAGS jar flags
# JMOD jmod command.
# JMODFLAGS jmod flags.
+# JAVAFLAGS java flags for run targets
# Module specific variables
# <module>_JARFLAGS
# <module>_JMODFLAGS
+# all paths are relative to the root package name
+
# <module>_JAVA Java sources. If not set it is found from src/<module>/classes/(*.java)
# <module>_RESOURCES .jar resources. If not set it is found from src/<module>/classes/(not *.java)
-# <module>_JAVA_GENERATED Java generated sources. These must be relative to the package name.
+# <module>_JAVA_GENERATED Java generated sources.
+# <module>_RESOURCES_GENERATED Java generated sources.
# Variables for use in fragments
# <module>_gendir Location for files used in Java generation process (per project).
# <module>_genjavadir Location where _JAVA_GENERATED .java files will be created (per project).
-# <module>_jnidir Location for jni generated files (per target).
# <module>_objdir Location for c objects (per target).
# <module>_incdir Location for output includes, .jmod staging.
# <module>_libdir Location for output libraries, .jmod staging. May point to _bindir.
# These are compiled after the java sources have been compiled as that
# process also generates any native binding headers.
-# <module>_JNI_LIBRARIES list of libraries to build.
+# <module>_NATIVE_LIBRARIES list of libraries to build.
# library names match System.loadLibrary().
# Global variables
# <target>_LDLIBS
# <target>_CPPFLAGS
# <target>_CFLAGS
+# <target>_CC
+# <target>_CXXFLAGS
+# <target>_CXX
# SO shared library suffix
# LIB shared library prefix
# Per library variables.
-# <library>_SOURCES .c, .cc, .C - source files for library. Paths are relative to src/<module>/jni.
-# <library>_HEADERS header files for jmod
-# <library>_COMMANDS commands/bin/scripts for jmod
+# <library>_SOURCES .c source files for library. Paths are relative to src/<module>/native.
+# <library>_CXXSOURCES .c source files for library. Paths are relative to src/<module>/native.
+# <library>_HEADERS header files for install/jmod
+# <library>_COMMANDS commands/bin/scripts for install/jmod
# <library>_LDFLAGS link flags
# <library>_LIBADD extra objects to add to link line
# <library>_LDLIBS link libraries
-# <library>_CPPFLAGS c pre-processor flags. "-Isrc/<module>/jni -Ibin/include/<module>" is implicit.
+# <library>_CPPFLAGS c and c++ pre-processor flags. "-Isrc/<module>/jni -Ibin/include/<module>" is implicit.
# <library>_CCFLAGS c compiler flags
+# <library>_CXXFLAGS c++ compiler flags
# <library>_DEPENDENCIES A list of other objects on which this library depends before linking.
-# <library>_DEFS A list of .def files for nativez-gen.
-# <library>_DEFSFLAGS Flags for nativez-gen invocation.
-
-# .c files have dependencies automatically generated
+# .c and .cc files have dependencies automatically generated
# Targets
# -------
# 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
# -------
# ######################################################################
+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
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:
+# <module>_sdk is the target location of an expanded 'sdk' for this module
+# it resides in a common location bin/<target>/
+# <module>_jmod is the target location of a staging area for jmod files
+# is resides in a per-module lcoation bin/<module>/<target>/
+# <module>_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/<module>.depjava marks all source/generated sources are ready/updated
+# bin/status/<module>.depjar all compiled class files and resources are ready/updated
+# bin/status/<module>.sdk all files are available in bin/<target> 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 \
$$@
# 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/<target>/* to sdk area bin/<target>/*
$(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)))))
# ######################################################################
@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)
-
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=\
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}
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:
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:
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.LineUnavailableException;
import javax.sound.sampled.SourceDataLine;
+import jdk.incubator.foreign.ResourceScope;
/**
* Plays audio files.
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)
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);
import java.io.IOException;
import java.util.IllegalFormatException;
import javax.imageio.ImageIO;
+import jdk.incubator.foreign.ResourceScope;
/**
* Export a video as frames.
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);
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:
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;
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.
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");
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();
});
* @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) {
} 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);
}
}
import au.notzed.jjmpeg.AVPixelFormat;
import au.notzed.jjmpeg.io.JJMediaReader;
import java.io.IOException;
+import jdk.incubator.foreign.ResourceScope;
/**
* A simple video scanner.
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);
public void release() {
reader.release();
}
-}
+}
\ No newline at end of file
+++ /dev/null
-/*
- * Copyright (C) 2019 Michael Zucchi
- *
- * This file is part of jjmpeg <https://www.zedzone.space/software/jjmpeg.html>
- *
- * 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 <http://www.gnu.org/licenses/>.
- */
-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);
-
-}
+++ /dev/null
-/*
- * Copyright (C) 2017 Michael Zucchi
- *
- * This file is part of jjmpeg <https://www.zedzone.space/software/jjmpeg.html>
- *
- * 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 <http://www.gnu.org/licenses/>.
- */
-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<AVCodec> 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();
-}
+++ /dev/null
-/*
- * Copyright (C) 2017 Michael Zucchi
- *
- * This file is part of jjmpeg <https://www.zedzone.space/software/jjmpeg.html>
- *
- * 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 <http://www.gnu.org/licenses/>.
- */
-package au.notzed.jjmpeg;
-
-/**
- * AVCodecContext accessors.
- * <p>
- * 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.
- * <p>
- * 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.
- * <p>
- * Calls avcodec_free_context().
- *
- * @param p
- */
- private static native void release(long p);
-
- /**
- * Allocate and initialise an AVCodecContext.
- * <p>
- * 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.
- * <p>
- * 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.
- * <p>
- * Used to reset codec state, for example after a seek.
- * <p>
- * Calls avcodec_flush_buffers().
- */
- public native void flushBuffers();
-
- /**
- * Align dimensions suitable for codec.
- * <p>
- * Calls avcodec_align_dimensions().
- *
- * @param input Input dimensions.
- * @return Modified dimensions.
- */
- public native AVSize alignDimensions(AVSize input);
-
- /**
- * Submit raw packet to a decoder.
- * <p>
- * Packets are submitted to a decoder which generates output frames.
- * <p>
- * If the return value is EAGAIN or AVERROR_EOF then this function
- * returns false, for all other error values it throws an exception.
- * <p>
- * 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.
- * <p>
- * 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.
- * <p>
- * 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().
- * <p>
- * 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().
- * <p>
- * 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.
- * <p>
- * AVOption int "b" or "ab"
- *
- * @return
- */
- public native long getBitRate();
-
- /**
- * Set encoding/decoding AVCodecContext.bit_rate.
- * <p>
- * AVOption int "b" or "ab"
- *
- * @param bitrate
- */
- public native void setBitRate(long bitrate);
-
- /**
- * Get encoding AVCodecContext.global_quality.
- * <p>
- * AVOption int "global_quality".
- *
- * @return
- */
- public native int getGlobalQuality();
-
- /**
- * Set AVCodecContext.global_quality.
- * <p>
- * AVOption int "global_quality".
- *
- * @param quality
- */
- public native void setGlobalQuality(int quality);
-
- /**
- * Get the encoding/decoding AVCodecContext.flags and AVCodecContext.flags2.
- * <p>
- * This combines .flags and .flags2 into a single 64-bit flag set. The
- * AV_CODE_FLAG2_* constants have been shifted appropriately.
- * <p>
- * 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.
- * <p>
- * This performs a combined get and set operation on the flags allowing any cobimation
- * of flags to be set in a single call.
- * <p>
- * 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.
- * <p>
- * 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.
- * <p>
- * A time_base must always be set for encoding.
- * <p>
- * AVOption rational (q) "time_base".
- *
- * @param timebase
- */
- public native void setTimeBase(AVRational timebase);
-
- /**
- * Get the encoding/decoding AVCodecContext.delay.
- * <p>
- * AVOption int "delay".
- *
- * @return
- */
- public native int getDelay();
-
- /**
- * Get video encoding/decoding AVCodecContext.width.
- * <p>
- * AVOption image size "video_size".
- *
- * @return
- */
- public native int getWidth();
-
- /**
- * Set video encoding/decoding AVCodecContext.width.
- * <p>
- * AVOption image size "video_size".
- *
- * @param width
- */
- public native void setWidth(int width);
-
- /**
- * Get video encoding/decoding AVCodecContext.height.
- * <p>
- * AVOption image size "video_size".
- *
- * @return
- */
- public native int getHeight();
-
- /**
- * Set video encoding/decoding AVCodecContext.width.
- * <p>
- * AVOption image size "video_size".
- *
- * @param height
- */
- public native void setHeight(int height);
-
- /**
- * Get video encoding/decoding AVCodecContext.sample_aspect_ratio.
- * <p>
- * AVOption rational "aspect" or "sar".
- *
- * @return
- */
- public native AVRational getAspectRatio();
-
- /**
- * Set video encoding/decoding AVCodecContext.sample_aspect_ratio.
- * <p>
- * AVOption rational "aspect" or "sar".
- *
- * @param ratio
- */
- public native void setAspectRatio(AVRational ratio);
-
- /**
- * Get video encoding AVCodecContext.gop_size.
- * <p>
- * AVOption int "g".
- *
- * @return
- */
- public native int getGOPSize();
-
- /**
- * Set video encoding AVCodecContext.gop_size.
- * <p>
- * AVOption int "g".
- *
- * @param val
- */
- public native void setGOPSize(int val);
-
- /**
- * Get video encoding/decoding AVCodecContext.pix_fmt.
- * <p>
- * AVOption pixel format "pixel_format".
- *
- * @return
- * @see AVPixelFormat
- */
- public native int getPixelFormat();
-
- /**
- * Set video encoding/decoding AVCodecContext.pix_fmt.
- * <p>
- * AVOption pixel format "pixel_format".
- *
- * @param format
- * @see AVPixelFormat
- */
- public native void setPixelFormat(int format);
-
- /**
- * Get audio encoding/decoding AVCodecContext.sample_rate.
- * <p>
- * AVOption int "ar".
- *
- * @return
- */
- public native int getSampleRate();
-
- /**
- * Set audio encoding/decoding AVCodecContext.sample_rate.
- * <p>
- * AVOption int "ar".
- *
- * @param hertz
- */
- public native void setSampleRate(int hertz);
-
- /**
- * Get audio encoding/decoding AVCodecContext.channels.
- * <p>
- * AVOption int "ac".
- *
- * @return
- */
- public native int getNumChannels();
-
- /**
- * Set audio encoding/decoding AVCodecContext.channels.
- * <p>
- * 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.
- * <p>
- * AVOption int "frame_size".
- *
- * @return
- */
- public native int getFrameSize();
-
- /**
- * Get audio encoding/decoding AVCodecContext.frame_number.
- * <p>
- * AVOption int "frame_number".
- *
- * @return
- */
- public native int getFrameNumber();
-
- /**
- * Get audio encoding/decoding AVCodecContext.channel_layout.
- * <p>
- * AVOption channel layout "channel_layout".
- *
- * @return
- * @see AVChannelLayout
- */
- public native long getChannelLayout();
-
- /**
- * Set audio encoding/decoding AVCodecContext.channel_layout.
- * <p>
- * AVOption channel layout "channel_layout".
- *
- * @param layout
- * @see AVChannelLayout
- */
- public native void setChannelLayout(long layout);
-
- /**
- * Get audio decoding AVCodecContext.request_channel_layout.
- * <p>
- * AVOption channel layout "request_channel_layout".
- *
- * @return
- * @see AVChannelLayout
- */
- public native long getRequestChannelLayout();
-
- /**
- * Set audio decoding AVCodecContext.request_channel_layout.
- * <p>
- * AVOption channel layout "request_channel_layout".
- *
- * @param layout
- * @see AVChannelLayout
- */
- public native void setRequestChannelLayout(long layout);
-
- /**
- * Get encoding/decoding AVCodecContext.thread_count.
- * <p>
- * AVOption int "threads".
- *
- * @return
- */
- public native int getThreadCount();
-
- /**
- * Set encoding/decoding AVCodecContext.thread_count.
- * <p>
- * AVOption int "threads".
- *
- * @param nthreads
- */
- public native void setThreadCount(int nthreads);
-}
+++ /dev/null
-/*
- * Copyright (C) 2017 Michael Zucchi
- *
- * This file is part of jjmpeg <https://www.zedzone.space/software/jjmpeg.html>
- *
- * 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 <http://www.gnu.org/licenses/>.
- */
-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);
-}
+++ /dev/null
-/*
- * Copyright (C) 2017 Michael Zucchi
- *
- * This file is part of jjmpeg <https://www.zedzone.space/software/jjmpeg.html>
- *
- * 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 <http://www.gnu.org/licenses/>.
- */
-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?
-}
+++ /dev/null
-/*
- * Copyright (C) 2017 Michael Zucchi
- *
- * This file is part of jjmpeg <https://www.zedzone.space/software/jjmpeg.html>
- *
- * 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 <http://www.gnu.org/licenses/>.
- */
-package au.notzed.jjmpeg;
-
-/**
- * Interface to libavdevice.
- * <p>
- * 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<AVInputFormat> audioInputDevices() {
- return () -> new AVObjectIterator<>(AVDevice::nextAudioInputDevice);
- }
-
- public native static AVInputFormat nextVideoInputDevice(AVInputFormat last);
-
- public static Iterable<AVInputFormat> videoInputDevices() {
- return () -> new AVObjectIterator<>(AVDevice::nextVideoInputDevice);
- }
-
- public native static AVOutputFormat nextAudioOutputDevice(AVOutputFormat last);
-
- public static Iterable<AVOutputFormat> audioOutputDevices() {
- return () -> new AVObjectIterator<>(AVDevice::nextAudioOutputDevice);
- }
-
- public native static AVOutputFormat nextVideoOutputDevice(AVOutputFormat last);
-
- public static Iterable<AVOutputFormat> videoOutputDevices() {
- return () -> new AVObjectIterator<>(AVDevice::nextVideoOutputDevice);
- }
-
-}
+++ /dev/null
-/*
- * Copyright (C) 2017 Michael Zucchi
- *
- * This file is part of jjmpeg <https://www.zedzone.space/software/jjmpeg.html>
- *
- * 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 <http://www.gnu.org/licenses/>.
- */
-package au.notzed.jjmpeg;
-
-import java.util.TreeMap;
-
-/**
- * AVDictionary is a remarkably shithouse "ADT" used for configuration parameters.
- * <p>
- * This does not wrap it, it simply provides an equivalent functionality
- * using a TreeMap.
- * </p>
- * <h3>Historical Note</h3>
- * <p>
- * AVDictionary was inherited from libav. It's a miserable
- * design, it's simply a pointer to an array which updates itself <em>by copying the whole array</em>
- * every time it's length is changed.
- * </p>
- */
-public class AVDictionary extends TreeMap<String, String> {
-
- /**
- * Convert the dictionary to an array of {@code Entry<String,String>}.
- * <p>
- * 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();
- }
-}
+++ /dev/null
-/*
- * Copyright (C) 2017 Michael Zucchi
- *
- * This file is part of jjmpeg <https://www.zedzone.space/software/jjmpeg.html>
- *
- * 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 <http://www.gnu.org/licenses/>.
- */
-package au.notzed.jjmpeg;
-
-/**
- *
- */
-public class AVError implements AVErrorBits {
-
- static {
- AVObject.init();
- }
-
- public static native String toString(int errno);
-}
+++ /dev/null
-/*
- * Copyright (C) 2017 Michael Zucchi
- *
- * This file is part of jjmpeg <https://www.zedzone.space/software/jjmpeg.html>
- *
- * 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 <http://www.gnu.org/licenses/>.
- */
-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.
- * <p>
- * 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();
-}
+++ /dev/null
-/*
- * Copyright (C) 2017 Michael Zucchi
- *
- * This file is part of jjmpeg <https://www.zedzone.space/software/jjmpeg.html>
- *
- * 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 <http://www.gnu.org/licenses/>.
- */
-package au.notzed.jjmpeg;
-
-import java.nio.Buffer;
-import java.nio.ByteBuffer;
-
-/**
- * Accessor for a struct AVFrame.
- * <p>
- * Both video and audio frames are stored in the same object; various fields
- * will only make sense for the corresponding data.
- * <p>
- * To read and write pixels for video frames use {@link getPixelReader} and {@link getPixelWriter}.
- * <p>
- * 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.
- * <p>
- * 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.
- * <p>
- * 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.
- * <p>
- * 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 <T extends Buffer> 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 <T extends Buffer> 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 <T extends Buffer> void getSamples(T buffer);
-
- }
-
- public AVSampleWriter getSampleWriter(long layout, int fmt, int rate) {
- //return SampleReader.alloc(this, layout, fmt, rate);
- throw new UnsupportedOperationException();
- }
-
-}
+++ /dev/null
-/*
- * Copyright (C) 2019 Michael Zucchi
- *
- * This file is part of jjmpeg <https://www.zedzone.space/software/jjmpeg.html>
- *
- * 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 <http://www.gnu.org/licenses/>.
- */
-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();
-
-}
+++ /dev/null
-/*
- * Copyright (C) 2019 Michael Zucchi
- *
- * This file is part of jjmpeg <https://www.zedzone.space/software/jjmpeg.html>
- *
- * 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 <http://www.gnu.org/licenses/>.
- */
-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);
-}
+++ /dev/null
-/*
- * Copyright (C) 2017 Michael Zucchi
- *
- * This file is part of jjmpeg <https://www.zedzone.space/software/jjmpeg.html>
- *
- * 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 <http://www.gnu.org/licenses/>.
- */
-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.
- * <p>
- * 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.
- * <p>
- * 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);
- }
-}
+++ /dev/null
-/*
- * Copyright (C) 2017 Michael Zucchi
- *
- * This file is part of jjmpeg <https://www.zedzone.space/software/jjmpeg.html>
- *
- * 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 <http://www.gnu.org/licenses/>.
- */
-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<AVInputFormat> formats() {
- return () -> new AVObjectIterator<>(AVInputFormat::next);
- }
-
- public native void register();
-
- public native String getName();
-
- public native String getLongName();
-}
/*
- * Copyright (c) 2006 Michael Niedermayer <michaelni@gmx.at>
- * Copyright (C) 2017 Michael Zucchi
+ * Copyright (C) 2022 Michael Zucchi
*
* This file is part of jjmpeg <https://www.zedzone.space/software/jjmpeg.html>
*
/**
*
*/
-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);
+++ /dev/null
-/*
- * Copyright (C) 2017 Michael Zucchi
- *
- * This file is part of jjmpeg <https://www.zedzone.space/software/jjmpeg.html>
- *
- * 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 <http://www.gnu.org/licenses/>.
- */
-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);
-}
*/
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());
}
/**
public static void init() {
}
- /**
- * Handy iterator for various uses in the library.
- */
- static class AVObjectIterator<T> implements Iterator<T> {
-
- Function<T, T> nextFunc;
- T next;
-
- public AVObjectIterator(Function<T, T> 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;
- }
- }
}
--- /dev/null
+package au.notzed.jjmpeg;
+
+import java.util.Iterator;
+import java.util.function.Function;
+
+/**
+ * Handy iterator for various uses in the library.
+ */
+class AVObjectIterator<T> implements Iterator<T> {
+
+ Function<T, T> nextFunc;
+ T next;
+
+ public AVObjectIterator(Function<T, T> 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;
+ }
+
+}
+++ /dev/null
-/*
- * Copyright (C) 2017 Michael Zucchi
- *
- * This file is part of jjmpeg <https://www.zedzone.space/software/jjmpeg.html>
- *
- * 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 <http://www.gnu.org/licenses/>.
- */
-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<AVOutputFormat> 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();
-
-}
+++ /dev/null
-/*
- * Copyright (C) 2017 Michael Zucchi
- *
- * This file is part of jjmpeg <https://www.zedzone.space/software/jjmpeg.html>
- *
- * 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 <http://www.gnu.org/licenses/>.
- */
-package au.notzed.jjmpeg;
-
-import java.nio.ByteBuffer;
-
-/**
- * AVPacket stores compressed stream data.
- * <p>
- * 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.
- * <p>
- */
- public static final int AV_PKT_FLAG_DISCARD = 0x0004;
- /**
- * The packet comes from a trusted source.
- * <p>
- * 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.
- * <p>
- * 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.
- * <p>
- * 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.
- * <p>
- * It needs to be called ... at certain points I guess.
- * <p>
- * 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();
-
-}
+++ /dev/null
-/*
- * Copyright (C) 2017 Michael Zucchi
- *
- * This file is part of jjmpeg <https://www.zedzone.space/software/jjmpeg.html>
- *
- * 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 <http://www.gnu.org/licenses/>.
- */
-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);
-}
+++ /dev/null
-/*
- * Copyright (c) 2003 Michael Niedermayer <michaelni@gmx.at>
- * Copyright (C) 2017 Michael Zucchi
- *
- * This file is part of jjmpeg <https://www.zedzone.space/software/jjmpeg.html>
- *
- * 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 <http://www.gnu.org/licenses/>.
- */
-package au.notzed.jjmpeg;
-
-/**
- * AVRational holds a rational number.
- * <p>
- * 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<AVRational> {
-
- 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:
- * <ul>
- * <li>0 if `a == b`
- * <li>1 if `a > b`
- * <li>-1 if `a < b`
- * <li>`INT_MIN` if one of the values is of the form `0 / 0`
- * </ul>
- */
- @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;
- }
-}
+++ /dev/null
-/*
- * Copyright (C) 2019 Michael Zucchi
- *
- * This file is part of jjmpeg <https://www.zedzone.space/software/jjmpeg.html>
- *
- * 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 <http://www.gnu.org/licenses/>.
- */
-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);
-}
+++ /dev/null
-/*
- * Copyright (C) 2017 Michael Zucchi
- *
- * This file is part of jjmpeg <https://www.zedzone.space/software/jjmpeg.html>
- *
- * 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 <http://www.gnu.org/licenses/>.
- */
-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);
-}
+++ /dev/null
-/*
- * Copyright (C) 2017 Michael Zucchi
- *
- * This file is part of jjmpeg <https://www.zedzone.space/software/jjmpeg.html>
- *
- * 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 <http://www.gnu.org/licenses/>.
- */
-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);
- }
- };
- }
-}
--- /dev/null
+/*
+ * Copyright (C) 2020 Michael Zucchi
+ *
+ * This file is part of jjmpeg <https://www.zedzone.space/software/jjmpeg.html>
+ *
+ * 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 <http://www.gnu.org/licenses/>.
+ */
+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 <T extends Buffer> 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;
+ }
+ }
+}
+++ /dev/null
-/*
- * Copyright (C) 2017 Michael Zucchi
- *
- * This file is part of jjmpeg <https://www.zedzone.space/software/jjmpeg.html>
- *
- * 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 <http://www.gnu.org/licenses/>.
- */
-package au.notzed.jjmpeg;
-
-import java.nio.ByteBuffer;
-
-/**
- * Software Scaling Operations.
- * <p>
- * See also AVFrame.getPixelReader() for a higher level implementation.
- * <p>
- * @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.
-
- */
-}
+++ /dev/null
-/*
- * Copyright (C) 2017 Michael Zucchi
- *
- * This file is part of jjmpeg <https://www.zedzone.space/software/jjmpeg.html>
- *
- * 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 <http://www.gnu.org/licenses/>.
- */
-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);
-
-}
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;
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.
* @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<AVDictionary> options, ResourceScope scope) throws AVIOException, FileNotFoundException {
+ this(AVFormatContext.openInput(name, fmt, options, scope));
}
public JJMediaReader(AVFormatContext format) throws AVIOException {
// find all streams and map to something
int nstreams = format.getNumStreams();
JJReaderStream[] list = new JJReaderStream[nstreams];
+ HandleArray<AVStream> 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:
break;
default:
list[i] = new JJReaderUnknown(s, cp);
- s.setDiscard(AVDiscardBits.AVDISCARD_ALL);
+ s.setDiscard(AVDiscard.AVDISCARD_ALL);
break;
}
}
for (JJReaderStream m: streams) {
m.release();
}
- format.release();
- packet.release();
+ format.close();
+ packet.free();;
}
/**
}
freePacket = false;
- while (format.readFrame(packet)) {
+ while (format.readFrame(packet) == 0) {
try {
int index = packet.getStreamIndex();
JJReaderStream ms = streams.get(index);
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.
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 {
}
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();
}
/**
}
c.sendPacket(packet);
- done = c.receiveFrame(frame);
+ done = c.receiveFrame(frame) == 0;
frameIndex += 1;
}
+ " 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;
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()));
}
}
-> 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();
}
public int getNumChannels() {
- return c.getNumChannels();
+ return c.getChannels();
}
public long getChannelLayout() {
@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()));
}
}
}
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.
*
* @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);
}
/**
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();
}
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);
* @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 {
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);
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);
}
}
oc.writeTrailer();
}
- for (JJWriterStream sd : streams) {
+ for (JJWriterStream sd: streams) {
sd.close();
}
/* free the stream */
- oc.release();
+ oc.free();
}
public abstract class JJWriterStream {
* @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();
}
}
AVCodec.findEncoder(c.getCodecID()).getName(),
c.getBitRate(),
c.getWidth(), c.getHeight(), AVPixelFormat.toString(c.getPixelFormat()),
- c.getAspectRatio()));
+ c.getSampleAspectRatio()));
}
public void setWidth(int width) {
void close() {
super.close();
- frame.release();
+ frame.free();
}
public AVFrame getFrame() {
}
public void setNumChannels(int channels) {
- c.setNumChannels(channels);
+ c.setChannels(channels);
}
public void setChannelLayout(long layout) {
}
// ??? 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
*/
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;
}
--- /dev/null
+# -*- Mode:text; tab-width:4; electric-indent-mode: nil; indent-line-function:insert-tab; -*-
+
+%include code.api;
+%include types.api;
+
+struct <default> 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:<inline> {{
+ // 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:<inline> {{
+ 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:<inline> {{
+ 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:<inline> {{
+ 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:<inline> {{
+ 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:<inline> {{
+ 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:<inline> {{
+ 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:<inline> {{
+ public static Iterable<AVInputFormat> audioInputDevices() {
+ return () -> new AVObjectIterator<>(AVDevice::nextAudioInputDevice);
+ }
+
+ public static Iterable<AVInputFormat> videoInputDevices() {
+ return () -> new AVObjectIterator<>(AVDevice::nextVideoInputDevice);
+ }
+
+ public static Iterable<AVOutputFormat> audioOutputDevices() {
+ return () -> new AVObjectIterator<>(AVDevice::nextAudioOutputDevice);
+ }
+
+ public static Iterable<AVOutputFormat> videoOutputDevices() {
+ return () -> new AVObjectIterator<>(AVDevice::nextVideoOutputDevice);
+ }
+ }}
+}
+
+# exception?
+library AVError {
+ define:AVErrorBits;
+ av_strerror segment:errbuf implied:errbuf_size=Memory.size(errbuf);
+ code:<inline> {{
+ 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_/;
+}
--- /dev/null
+
+#include <libavdevice/avdevice.h>
+#include <libavcodec/avcodec.h>
+#include <libavformat/avformat.h>
+#include <libswscale/swscale.h>
+#include <libavutil/imgutils.h>
+#include <libavutil/opt.h>
+#include <libavutil/frame.h>
+
+#include <libavutil/samplefmt.h>
-#
-# Copyright (C) 2017 Michael Zucchi
-#
-# This file is part of jjmpeg <https://www.zedzone.space/software/jjmpeg.html>
-#
-# 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 <http://www.gnu.org/licenses/>.
-#
-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