WINDOWS ?= FALSE
GDB ?= FALSE

# use pkg-config for getting CFLAGS and LDLIBS
SHARED_LIBS=libavdevice                          \
            libavformat                          \
            libavfilter                          \
            libavcodec                           \
            libswresample                        \
            libswscale                           \
            libavutil                            \
            xcoder

ifeq ($(GDB), TRUE)
	OPTFLAG = -g
endif

ifeq ($(WINDOWS), FALSE)
CFLAGS := $(shell pkg-config --cflags $(SHARED_LIBS)) -Wall ${OPTFLAG}
LDLIBS := $(shell pkg-config --libs $(SHARED_LIBS)) -lpthread -lm
else
CFLAGS := $(shell pkg-config --cflags $(SHARED_LIBS)) -Wall ${OPTFLAG}
LDLIBS := $(shell pkg-config --libs $(SHARED_LIBS)) -lpthread -lws2_32
endif

#Check ffmpeg version. Versions prior to 4.2.1 don't support ROI and some other features
#Get libavcodec version and extract major, minor and micro
LIBAVCODEC_VERSION := $(shell pkg-config --modversion libavcodec)
LIBAVCODEC_MAJOR := $(shell echo "$(LIBAVCODEC_VERSION)" | awk -F. '{print $$1}')
LIBAVCODEC_MINOR := $(shell echo "$(LIBAVCODEC_VERSION)" | awk -F. '{print $$2}')
LIBAVCODEC_MICRO := $(shell echo "$(LIBAVCODEC_VERSION)" | awk -F. '{print $$3}')
#Check if libavcodec version is 58.54.100 or above
FFMPEG_421_AND_ABOVE = $(shell echo "$(LIBAVCODEC_MAJOR) $(LIBAVCODEC_MINOR) $(LIBAVCODEC_MICRO)" | awk '{if ($$1 > 58 || ($$1 == 58 && $$2 > 54) || ($$1 == 58 && $$2 == 54 && $$3 >= 100)) print "TRUE"; else print "FALSE"}')
#if FFMPEG_421_AND_ABOVE is TRUE, then define ROI_SUPPORTED macro
ifeq ($(FFMPEG_421_AND_ABOVE),TRUE)
CFLAGS += -DROI_SUPPORTED
endif
#xstack is not supported on versions prior to 4.1.3
FFMPEG_413_AND_ABOVE = $(shell echo "$(LIBAVCODEC_MAJOR) $(LIBAVCODEC_MINOR) $(LIBAVCODEC_MICRO)" | awk '{if ($$1 > 58 || ($$1 == 58 && $$2 > 35) || ($$1 == 58 && $$2 == 35 && $$3 >= 100)) print "TRUE"; else print "FALSE"}')
FFMPEG_342_AND_ABOVE = $(shell echo "$(LIBAVCODEC_MAJOR) $(LIBAVCODEC_MINOR) $(LIBAVCODEC_MICRO)" | awk '{if ($$1 > 57 || ($$1 == 57 && $$2 > 107) || ($$1 == 57 && $$2 == 107 && $$3 >= 100)) print "TRUE"; else print "FALSE"}')
#Netint supports AV1 from 3.4.2 onwards
ifeq ($(FFMPEG_342_AND_ABOVE),TRUE)
CFLAGS += -DAV1_SUPPORTED
endif

CUDA_HOME   ?= /usr/local/cuda
CUDA_INC    := $(CUDA_HOME)/include
CUDA_LIB    := $(CUDA_HOME)/lib64
# CUDA kernels live alongside the original ni_p2p_cuda.c demo
P2P_CUDA_DIR := ../../p2p_demos/nvidia_p2p

# detect FFMPEG_SRC_DIR from installed libavcodec major version.
# nidec.h includes internal FFmpeg headers that must match the installed library.
# Override with FFMPEG_SRC_DIR=... if your source tree layout differs.
ifeq ($(LIBAVCODEC_MAJOR),58)
FFMPEG_SRC_DIR ?= ../../../FFmpeg-n4.3.1
else ifeq ($(LIBAVCODEC_MAJOR),59)
FFMPEG_SRC_DIR ?= ../../../FFmpeg-n5.1.2
else ifeq ($(LIBAVCODEC_MAJOR),60)
FFMPEG_SRC_DIR ?= ../../../FFmpeg-n6.1
else ifeq ($(LIBAVCODEC_MAJOR),61)
FFMPEG_SRC_DIR ?= ../../../FFmpeg-n7.1
else ifeq ($(LIBAVCODEC_MAJOR),62)
FFMPEG_SRC_DIR ?= ../../../FFmpeg-n8.0.1
else
$(warning ni_transcode_p2p_cuda: unknown libavcodec major $(LIBAVCODEC_MAJOR), defaulting FFMPEG_SRC_DIR to FFmpeg-n4.3.1)
FFMPEG_SRC_DIR ?= ../../../FFmpeg-n4.3.1
endif

CUDA_AVAILABLE := $(shell test -f $(CUDA_HOME)/include/cuda.h && command -v nvcc >/dev/null 2>&1 && echo TRUE || echo FALSE)

ifeq ($(WINDOWS), FALSE)
EXAMPLES=ni_demuxing_decoding                   \
         ni_encode_video                        \
         ni_multi_thread_yuv420to444            \
         ni_multi_thread_yuv444to420            \
         ni_multi_thread_encode_video
    ifeq ($(FFMPEG_421_AND_ABOVE),TRUE)
    EXAMPLES += ni_tile_encoding                     \
                ni_hevc_tile_decoding                \
                ni_hevc_tile_transcoding             \
                ni_encode_ai_test                    \
                ni_transcode_ai_test                 \
                ni_2D_engine_p2p_test                \
                ni_av1_tile_decoding                 \
                ni_av1_tile_transcoding              \
                ni_multiview_tile_encoding
    endif
    ifeq ($(FFMPEG_413_AND_ABOVE),TRUE) 
    EXAMPLES += ni_xstack                            \
                ni_live_xstack
    endif
    #These compile on 3.4.2 and above
    ifeq ($(FFMPEG_342_AND_ABOVE),TRUE)
    EXAMPLES += ni_multi_thread_lowdelay_encode   \
         ni_2D_engine_application                 \
         ni_multi_thread_transcoding              \
         ni_multi_encode_scale                    \
         ni_transcode_filter                      \
         ni_ppu_split
    # P2P+CUDA demo: needs CUDA toolkit and nvcc
    ifeq ($(CUDA_AVAILABLE),TRUE)
    EXAMPLES += ni_transcode_p2p_cuda
    else
    $(info ni_transcode_p2p_cuda skipped — CUDA not found at $(CUDA_HOME) or nvcc not in PATH)
    endif
    endif
else
EXAMPLES=ni_demuxing_decoding                 \
          ni_encode_video
endif

OBJS=$(addsuffix .o,$(EXAMPLES))

# ni_transcode_p2p_cuda has its own explicit link rule (nvcc + -lcuda/-lcudart)
ifeq ($(CUDA_AVAILABLE),TRUE)
_LINK_EXAMPLES := $(filter-out ni_transcode_p2p_cuda,$(EXAMPLES))
_LINK_OBJS     := $(addsuffix .o,$(_LINK_EXAMPLES))
else
_LINK_EXAMPLES := $(EXAMPLES)
_LINK_OBJS     := $(OBJS)
endif

.phony: all clean

all: $(EXAMPLES)
	$(RM) $(OBJS)

$(_LINK_EXAMPLES): $(_LINK_OBJS)
	$(CC) $(addsuffix .o,$@) $(CFLAGS) $(LDLIBS) -o $@

%.o : %.c
	${CC} ${CFLAGS} -c -o $@ $<

ifeq ($(CUDA_AVAILABLE),TRUE)

NVCC      := nvcc
NVCCFLAGS := -std=c++11 -Xcompiler "-Wall -Wextra -Wno-unused-result"

P2P_CUDA_KERNEL_SRC := $(P2P_CUDA_DIR)/ni_draw_box_cuda.cu
P2P_CUDA_KERNEL_OBJ := ni_draw_box_cuda.o

P2P_CFLAGS := $(CFLAGS) \
              -I$(CUDA_INC) \
              -I$(P2P_CUDA_DIR) \
              -I$(FFMPEG_SRC_DIR) \
              -I$(FFMPEG_SRC_DIR)/libavcodec

ni_transcode_p2p_cuda.o: ni_transcode_p2p_cuda.c
	${CC} $(P2P_CFLAGS) -c -o $@ $<

$(P2P_CUDA_KERNEL_OBJ): $(P2P_CUDA_KERNEL_SRC)
	$(NVCC) $(NVCCFLAGS) -I$(CUDA_INC) -I$(P2P_CUDA_DIR) -c $< -o $@

NVCC_LDLIBS := $(filter-out -pthread,$(LDLIBS))

ni_transcode_p2p_cuda: ni_transcode_p2p_cuda.o $(P2P_CUDA_KERNEL_OBJ)
	$(NVCC) $(NVCCFLAGS) -L$(CUDA_LIB) $^ -o $@ \
	    $(NVCC_LDLIBS) -lcuda -lcudart

clean_p2p_cuda:
	$(RM) ni_transcode_p2p_cuda ni_transcode_p2p_cuda.o $(P2P_CUDA_KERNEL_OBJ)

endif

clean:
	$(RM) $(EXAMPLES) $(OBJS)
ifeq ($(CUDA_AVAILABLE),TRUE)
	$(RM) ni_transcode_p2p_cuda ni_transcode_p2p_cuda.o $(P2P_CUDA_KERNEL_OBJ)
endif

build_info:
	@echo "libavcodec version: $(LIBAVCODEC_VERSION)"
	@echo "Supports AV1: $(FFMPEG_342_AND_ABOVE)"
	@echo "Supports ROI: $(FFMPEG_421_AND_ABOVE)"
	@echo "Supports xstack: $(FFMPEG_413_AND_ABOVE)"
	@echo "Supported examples: $(EXAMPLES)"
