diff --git a/deps/patches/005_fix_ffmpeg.patch b/deps/patches/005_fix_ffmpeg.patch new file mode 100644 index 00000000..c3eed149 --- /dev/null +++ b/deps/patches/005_fix_ffmpeg.patch @@ -0,0 +1,418 @@ +diff --git a/pjmedia/src/pjmedia-codec/ffmpeg_vid_codecs.c b/pjmedia/src/pjmedia-codec/ffmpeg_vid_codecs.c +index 2ea34386c5..652839e900 100644 +--- pjproject-2.10/pjmedia/src/pjmedia-codec/ffmpeg_vid_codecs.c ++++ pjsip/pjmedia/src/pjmedia-codec/ffmpeg_vid_codecs.c +@@ -41,10 +41,6 @@ + + #define THIS_FILE "ffmpeg_vid_codecs.c" + +-#define LIBAVCODEC_VER_AT_LEAST(major,minor) (LIBAVCODEC_VERSION_MAJOR > major || \ +- (LIBAVCODEC_VERSION_MAJOR == major && \ +- LIBAVCODEC_VERSION_MINOR >= minor)) +- + #include "../pjmedia/ffmpeg_util.h" + #include + #include +@@ -80,7 +76,7 @@ + # define AV_OPT_SET(obj,name,val,opt) (av_set_string3(obj,name,val,opt,NULL)==0) + # define AV_OPT_SET_INT(obj,name,val) (av_set_int(obj,name,val)!=NULL) + #endif +-#define AVCODEC_HAS_DECODE(c) (c->decode) ++#define AVCODEC_HAS_DECODE(c) (c->decode) + + /* AVCodec H264 default PT */ + #define AVC_H264_PT PJMEDIA_RTP_PT_H264_RSV3 +@@ -732,6 +728,141 @@ static int find_codec_idx_by_fmt_id(pjmedia_format_id fmt_id) + return -1; + } + ++static void init_codec(const AVCodec *c, pj_bool_t is_encoder, ++ pj_bool_t is_decoder) ++{ ++ pj_status_t status; ++ ffmpeg_codec_desc *desc; ++ pjmedia_format_id fmt_id; ++ int codec_info_idx; ++ ++#if LIBAVCODEC_VERSION_MAJOR <= 52 ++# define AVMEDIA_TYPE_VIDEO CODEC_TYPE_VIDEO ++#endif ++ if (c->type != AVMEDIA_TYPE_VIDEO) ++ return; ++ ++ /* Video encoder and decoder are usually implemented in separate ++ * AVCodec instances. While the codec attributes (e.g: raw formats, ++ * supported fps) are in the encoder. ++ */ ++ ++ status = CodecID_to_pjmedia_format_id(c->id, &fmt_id); ++ /* Skip if format ID is unknown */ ++ if (status != PJ_SUCCESS) ++ return; ++ ++ codec_info_idx = find_codec_idx_by_fmt_id(fmt_id); ++ /* Skip if codec is unwanted by this wrapper (not listed in ++ * the codec info array) ++ */ ++ if (codec_info_idx < 0) ++ return; ++ ++ desc = &codec_desc[codec_info_idx]; ++ ++ /* Skip duplicated codec implementation */ ++ if ((is_encoder && (desc->info.dir & PJMEDIA_DIR_ENCODING)) ++ || ++ (is_decoder && (desc->info.dir & PJMEDIA_DIR_DECODING))) ++ { ++ return; ++ } ++ ++ /* Get raw/decoded format ids in the encoder */ ++ if (c->pix_fmts && is_encoder) { ++ pjmedia_format_id raw_fmt[PJMEDIA_VID_CODEC_MAX_DEC_FMT_CNT]; ++ unsigned raw_fmt_cnt = 0; ++ unsigned raw_fmt_cnt_should_be = 0; ++ const enum AVPixelFormat *p = c->pix_fmts; ++ ++ for(;(p && *p != -1) && ++ (raw_fmt_cnt < PJMEDIA_VID_CODEC_MAX_DEC_FMT_CNT); ++ ++p) ++ { ++ pjmedia_format_id fmt_id; ++ ++ raw_fmt_cnt_should_be++; ++ status = PixelFormat_to_pjmedia_format_id(*p, &fmt_id); ++ if (status != PJ_SUCCESS) { ++ PJ_PERROR(6, (THIS_FILE, status, ++ "Unrecognized ffmpeg pixel format %d", *p)); ++ continue; ++ } ++ ++ //raw_fmt[raw_fmt_cnt++] = fmt_id; ++ /* Disable some formats due to H.264 error: ++ * x264 [error]: baseline profile doesn't support 4:4:4 ++ */ ++ if (desc->info.pt != PJMEDIA_RTP_PT_H264 || ++ fmt_id != PJMEDIA_FORMAT_RGB24) ++ { ++ raw_fmt[raw_fmt_cnt++] = fmt_id; ++ } ++ } ++ ++ if (raw_fmt_cnt == 0) { ++ PJ_LOG(5, (THIS_FILE, "No recognized raw format " ++ "for codec [%s/%s], codec ignored", ++ c->name, c->long_name)); ++ /* Skip this encoder */ ++ return; ++ } ++ ++ if (raw_fmt_cnt < raw_fmt_cnt_should_be) { ++ PJ_LOG(6, (THIS_FILE, "Codec [%s/%s] have %d raw formats, " ++ "recognized only %d raw formats", ++ c->name, c->long_name, ++ raw_fmt_cnt_should_be, raw_fmt_cnt)); ++ } ++ ++ desc->info.dec_fmt_id_cnt = raw_fmt_cnt; ++ pj_memcpy(desc->info.dec_fmt_id, raw_fmt, ++ sizeof(raw_fmt[0])*raw_fmt_cnt); ++ } ++ ++ /* Get supported framerates */ ++ if (c->supported_framerates) { ++ const AVRational *fr = c->supported_framerates; ++ while ((fr->num != 0 || fr->den != 0) && ++ desc->info.fps_cnt < PJMEDIA_VID_CODEC_MAX_FPS_CNT) ++ { ++ desc->info.fps[desc->info.fps_cnt].num = fr->num; ++ desc->info.fps[desc->info.fps_cnt].denum = fr->den; ++ ++desc->info.fps_cnt; ++ ++fr; ++ } ++ } ++ ++ /* Get ffmpeg encoder instance */ ++ if (is_encoder && !desc->enc) { ++ desc->info.dir |= PJMEDIA_DIR_ENCODING; ++ desc->enc = c; ++ } ++ ++ /* Get ffmpeg decoder instance */ ++ if (is_decoder && !desc->dec) { ++ desc->info.dir |= PJMEDIA_DIR_DECODING; ++ desc->dec = c; ++ } ++ ++ /* Enable this codec when any ffmpeg codec instance are recognized ++ * and the supported raw formats info has been collected. ++ */ ++ if ((desc->dec || desc->enc) && desc->info.dec_fmt_id_cnt) ++ { ++ desc->enabled = PJ_TRUE; ++ } ++ ++ /* Normalize default value of clock rate */ ++ if (desc->info.clock_rate == 0) ++ desc->info.clock_rate = 90000; ++ ++ /* Set supported packings */ ++ desc->info.packings |= PJMEDIA_VID_PACKING_WHOLE; ++ if (desc->packetize && desc->unpacketize) ++ desc->info.packings |= PJMEDIA_VID_PACKING_PACKETS; ++} + + /* + * Initialize and register FFMPEG codec factory to pjmedia endpoint. +@@ -775,144 +906,33 @@ PJ_DEF(pj_status_t) pjmedia_codec_ffmpeg_vid_init(pjmedia_vid_codec_mgr *mgr, + */ + avcodec_init(); + #endif +- avcodec_register_all(); +- +- /* Enum FFMPEG codecs */ +- for (c=av_codec_next(NULL); c; c=av_codec_next(c)) { +- ffmpeg_codec_desc *desc; +- pjmedia_format_id fmt_id; +- int codec_info_idx; +- +-#if LIBAVCODEC_VERSION_MAJOR <= 52 +-# define AVMEDIA_TYPE_VIDEO CODEC_TYPE_VIDEO +-#endif +- if (c->type != AVMEDIA_TYPE_VIDEO) +- continue; + +- /* Video encoder and decoder are usually implemented in separate +- * AVCodec instances. While the codec attributes (e.g: raw formats, +- * supported fps) are in the encoder. +- */ +- +- //PJ_LOG(3, (THIS_FILE, "%s", c->name)); +- status = CodecID_to_pjmedia_format_id(c->id, &fmt_id); +- /* Skip if format ID is unknown */ +- if (status != PJ_SUCCESS) +- continue; +- +- codec_info_idx = find_codec_idx_by_fmt_id(fmt_id); +- /* Skip if codec is unwanted by this wrapper (not listed in +- * the codec info array) +- */ +- if (codec_info_idx < 0) +- continue; +- +- desc = &codec_desc[codec_info_idx]; +- +- /* Skip duplicated codec implementation */ +- if ((AVCODEC_HAS_ENCODE(c) && (desc->info.dir & PJMEDIA_DIR_ENCODING)) +- || +- (AVCODEC_HAS_DECODE(c) && (desc->info.dir & PJMEDIA_DIR_DECODING))) +- { +- continue; +- } +- +- /* Get raw/decoded format ids in the encoder */ +- if (c->pix_fmts && AVCODEC_HAS_ENCODE(c)) { +- pjmedia_format_id raw_fmt[PJMEDIA_VID_CODEC_MAX_DEC_FMT_CNT]; +- unsigned raw_fmt_cnt = 0; +- unsigned raw_fmt_cnt_should_be = 0; +- const enum AVPixelFormat *p = c->pix_fmts; +- +- for(;(p && *p != -1) && +- (raw_fmt_cnt < PJMEDIA_VID_CODEC_MAX_DEC_FMT_CNT); +- ++p) +- { +- pjmedia_format_id fmt_id; +- +- raw_fmt_cnt_should_be++; +- status = PixelFormat_to_pjmedia_format_id(*p, &fmt_id); +- if (status != PJ_SUCCESS) { +- PJ_PERROR(6, (THIS_FILE, status, +- "Unrecognized ffmpeg pixel format %d", *p)); +- continue; +- } +- +- //raw_fmt[raw_fmt_cnt++] = fmt_id; +- /* Disable some formats due to H.264 error: +- * x264 [error]: baseline profile doesn't support 4:4:4 +- */ +- if (desc->info.pt != PJMEDIA_RTP_PT_H264 || +- fmt_id != PJMEDIA_FORMAT_RGB24) +- { +- raw_fmt[raw_fmt_cnt++] = fmt_id; +- } +- } +- +- if (raw_fmt_cnt == 0) { +- PJ_LOG(5, (THIS_FILE, "No recognized raw format " +- "for codec [%s/%s], codec ignored", +- c->name, c->long_name)); +- /* Skip this encoder */ +- continue; +- } +- +- if (raw_fmt_cnt < raw_fmt_cnt_should_be) { +- PJ_LOG(6, (THIS_FILE, "Codec [%s/%s] have %d raw formats, " +- "recognized only %d raw formats", +- c->name, c->long_name, +- raw_fmt_cnt_should_be, raw_fmt_cnt)); +- } ++#if LIBAVCODEC_VER_AT_LEAST(58,137) ++ ++ for (i = 0; i < PJ_ARRAY_SIZE(codec_desc); ++i) { ++ unsigned codec_id; + +- desc->info.dec_fmt_id_cnt = raw_fmt_cnt; +- pj_memcpy(desc->info.dec_fmt_id, raw_fmt, +- sizeof(raw_fmt[0])*raw_fmt_cnt); +- } ++ pjmedia_format_id_to_CodecID(codec_desc[i].info.fmt_id, &codec_id); + +- /* Get supported framerates */ +- if (c->supported_framerates) { +- const AVRational *fr = c->supported_framerates; +- while ((fr->num != 0 || fr->den != 0) && +- desc->info.fps_cnt < PJMEDIA_VID_CODEC_MAX_FPS_CNT) +- { +- desc->info.fps[desc->info.fps_cnt].num = fr->num; +- desc->info.fps[desc->info.fps_cnt].denum = fr->den; +- ++desc->info.fps_cnt; +- ++fr; +- } +- } ++ c = avcodec_find_encoder(codec_id); ++ if (c) ++ init_codec(c, PJ_TRUE, PJ_FALSE); + +- /* Get ffmpeg encoder instance */ +- if (AVCODEC_HAS_ENCODE(c) && !desc->enc) { +- desc->info.dir |= PJMEDIA_DIR_ENCODING; +- desc->enc = c; +- } +- +- /* Get ffmpeg decoder instance */ +- if (AVCODEC_HAS_DECODE(c) && !desc->dec) { +- desc->info.dir |= PJMEDIA_DIR_DECODING; +- desc->dec = c; +- } +- +- /* Enable this codec when any ffmpeg codec instance are recognized +- * and the supported raw formats info has been collected. +- */ +- if ((desc->dec || desc->enc) && desc->info.dec_fmt_id_cnt) +- { +- desc->enabled = PJ_TRUE; +- } +- +- /* Normalize default value of clock rate */ +- if (desc->info.clock_rate == 0) +- desc->info.clock_rate = 90000; ++ c = avcodec_find_decoder(codec_id); ++ if (c) ++ init_codec(c, PJ_FALSE, PJ_TRUE); ++ } ++#else + +- /* Set supported packings */ +- desc->info.packings |= PJMEDIA_VID_PACKING_WHOLE; +- if (desc->packetize && desc->unpacketize) +- desc->info.packings |= PJMEDIA_VID_PACKING_PACKETS; ++ avcodec_register_all(); + ++ /* Enum FFMPEG codecs */ ++ for (c=av_codec_next(NULL); c; c=av_codec_next(c)) { ++ init_codec(c, AVCODEC_HAS_ENCODE(c), AVCODEC_HAS_DECODE(c)); + } + ++#endif ++ + /* Review all codecs for applying base format, registering format match for + * SDP negotiation, etc. + */ +@@ -1618,7 +1638,34 @@ static pj_status_t ffmpeg_codec_encode_whole(pjmedia_vid_codec *codec, + avpacket.data = (pj_uint8_t*)output->buf; + avpacket.size = output_buf_len; + +-#if LIBAVCODEC_VER_AT_LEAST(54,15) ++#if LIBAVCODEC_VER_AT_LEAST(58,137) ++ PJ_UNUSED_ARG(got_packet); ++ err = avcodec_send_frame(ff->enc_ctx, &avframe); ++ if (err >= 0) { ++ AVPacket *pkt = NULL; ++ pj_uint8_t *bits_out = (pj_uint8_t*) output->buf; ++ unsigned out_size = 0; ++ pkt = av_packet_alloc(); ++ if (pkt) { ++ while (err >= 0) { ++ err = avcodec_receive_packet(ff->enc_ctx, pkt); ++ if (err == AVERROR(EAGAIN) || err == AVERROR_EOF) { ++ err = out_size; ++ break; ++ } ++ if (err >= 0) { ++ pj_memcpy(bits_out, pkt->data, pkt->size); ++ bits_out += pkt->size; ++ out_size += pkt->size; ++ av_packet_unref(&avpacket); ++ } ++ } ++ av_packet_free(&pkt); ++ } ++ } ++ ++#elif LIBAVCODEC_VER_AT_LEAST(54,15) ++ + err = avcodec_encode_video2(ff->enc_ctx, &avpacket, &avframe, &got_packet); + if (!err && got_packet) + err = avpacket.size; +@@ -1861,7 +1908,18 @@ static pj_status_t ffmpeg_codec_decode_whole(pjmedia_vid_codec *codec, + avpacket.flags = 0; + #endif + +-#if LIBAVCODEC_VER_AT_LEAST(52,72) ++#if LIBAVCODEC_VER_AT_LEAST(58,137) ++ err = avcodec_send_packet(ff->dec_ctx, &avpacket); ++ if (err >= 0) { ++ err = avcodec_receive_frame(ff->dec_ctx, &avframe); ++ if (err == AVERROR_EOF) ++ err = 0; ++ ++ if (err >= 0) { ++ got_picture = PJ_TRUE; ++ } ++ } ++#elif LIBAVCODEC_VER_AT_LEAST(52,72) + err = avcodec_decode_video2(ff->dec_ctx, &avframe, + &got_picture, &avpacket); + #else +diff --git a/pjmedia/src/pjmedia/ffmpeg_util.c b/pjmedia/src/pjmedia/ffmpeg_util.c +index 8451f22008..9de668519d 100644 +--- pjproject-2.10/pjmedia/src/pjmedia/ffmpeg_util.c ++++ pjsip/pjmedia/src/pjmedia/ffmpeg_util.c +@@ -79,7 +79,9 @@ void pjmedia_ffmpeg_add_ref() + if (pjmedia_ffmpeg_ref_cnt++ == 0) { + av_log_set_level(AV_LOG_ERROR); + av_log_set_callback(&ffmpeg_log_cb); ++#if LIBAVCODEC_VER_AT_MAX(58,137) + av_register_all(); ++#endif + } + } + +diff --git a/pjmedia/src/pjmedia/ffmpeg_util.h b/pjmedia/src/pjmedia/ffmpeg_util.h +index cd8283edb8..dc9bedbd5d 100644 +--- pjproject-2.10/pjmedia/src/pjmedia/ffmpeg_util.h ++++ pjsip/pjmedia/src/pjmedia/ffmpeg_util.h +@@ -46,6 +46,13 @@ + # define AV(str) AV_ ## str + //#endif + ++#define LIBAVCODEC_VER_AT_LEAST(major,minor) (LIBAVCODEC_VERSION_MAJOR > major || \ ++ (LIBAVCODEC_VERSION_MAJOR == major && \ ++ LIBAVCODEC_VERSION_MINOR >= minor)) ++ ++#define LIBAVCODEC_VER_AT_MAX(major,minor) (LIBAVCODEC_VERSION_MAJOR < major || \ ++ (LIBAVCODEC_VERSION_MAJOR == major && \ ++ LIBAVCODEC_VERSION_MINOR <= minor)) + + void pjmedia_ffmpeg_add_ref(); + void pjmedia_ffmpeg_dec_ref(); diff --git a/deps/patches/007_video_support_dshow_mingw.patch b/deps/patches/007_video_support_dshow_mingw.patch new file mode 100644 index 00000000..e40ec3b5 --- /dev/null +++ b/deps/patches/007_video_support_dshow_mingw.patch @@ -0,0 +1,480 @@ +diff -ruN pjsip/aconfigure patch/aconfigure +--- pjsip/aconfigure 2024-09-03 11:24:53 ++++ patch/aconfigure 2024-09-03 11:27:36 +@@ -681,6 +681,9 @@ + ac_pjmedia_video_has_ios_opengl + ac_pjmedia_video_has_vtoolbox + ac_pjmedia_video_has_darwin ++ac_dshow_ldflags ++ac_dshow_cflags ++ac_pjmedia_video_dev_has_dshow + ac_android_cflags + ac_pjmedia_video_has_android + ac_pjmedia_video +@@ -6471,10 +6474,12 @@ + + + +-# Disable video on mingw ++# Disable video on mingw by default (but respect --enable-video=yes) + case $target in + *mingw*) ++ if test ! "$enable_video" = "yes"; then + enable_video="no" ++ fi + ;; + esac + +@@ -6545,6 +6550,18 @@ + fi + ac_android_cflags="$ac_android_cflags -DPJMEDIA_VIDEO_DEV_HAS_ANDROID=1" + ;; ++ *mingw*) ++ if test "$enable_video" = "yes"; then ++ ac_pjmedia_video=windows_os ++ ++ ac_pjmedia_video_dev_has_dshow=yes ++ ++ ac_dshow_cflags="-DPJMEDIA_HAS_VIDEO=1 -DPJMEDIA_VIDEO_DEV_HAS_DSHOW=1" ++ ++ ac_dshow_ldflags=" -lstdc++ -lquartz -lole32 -loleaut32 -lrpcrt4 -lwinmm -luuid -lmingwex -lstrmiids " ++ LIBS="$LIBS -lstdc++ -lquartz -lole32 -loleaut32 -lrpcrt4 -lwinmm -luuid -lmingwex -lstrmiids " ++ fi ++ ;; + *darwin*) + ac_pjmedia_video=darwin_os + +@@ -7053,6 +7070,7 @@ + ac_sdl_cflags=`$SDL_CONFIG --cflags` + ac_sdl_cflags="-DPJMEDIA_VIDEO_DEV_HAS_SDL=1 $ac_sdl_cflags" + ac_sdl_ldflags=`$SDL_CONFIG --libs` ++ ac_sdl_ldflags=${ac_sdl_ldflags//-mwindows/} + LIBS="$LIBS $ac_sdl_ldflags" + else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: Unsupported SDL version" >&5 +diff -ruN pjsip/aconfigure.ac patch/aconfigure.ac +--- pjsip/aconfigure.ac 2024-09-03 11:24:53 ++++ patch/aconfigure.ac 2024-09-03 11:27:36 +@@ -763,10 +763,12 @@ + + AC_SUBST(ac_pjmedia_video) + +-# Disable video on mingw ++# Disable video on mingw by default (but respect --enable-video=yes) + case $target in + *mingw*) ++ if test ! "$enable_video" = "yes"; then + enable_video="no" ++ fi + ;; + esac + +@@ -818,6 +820,18 @@ + fi + ac_android_cflags="$ac_android_cflags -DPJMEDIA_VIDEO_DEV_HAS_ANDROID=1" + ;; ++ *mingw*) ++ if test "$enable_video" = "yes"; then ++ ac_pjmedia_video=windows_os ++ AC_SUBST(ac_pjmedia_video_dev_has_dshow) ++ ac_pjmedia_video_dev_has_dshow=yes ++ AC_SUBST(ac_dshow_cflags) ++ ac_dshow_cflags="-DPJMEDIA_HAS_VIDEO=1 -DPJMEDIA_VIDEO_DEV_HAS_DSHOW=1" ++ AC_SUBST(ac_dshow_ldflags) ++ ac_dshow_ldflags=" -lstdc++ -lquartz -lole32 -loleaut32 -lrpcrt4 -lwinmm -luuid -lmingwex -lstrmiids " ++ LIBS="$LIBS -lstdc++ -lquartz -lole32 -loleaut32 -lrpcrt4 -lwinmm -luuid -lmingwex -lstrmiids " ++ fi ++ ;; + *darwin*) + ac_pjmedia_video=darwin_os + AC_SUBST(ac_pjmedia_video_has_darwin) +@@ -1072,6 +1086,7 @@ + ac_sdl_cflags=`$SDL_CONFIG --cflags` + ac_sdl_cflags="-DPJMEDIA_VIDEO_DEV_HAS_SDL=1 $ac_sdl_cflags" + ac_sdl_ldflags=`$SDL_CONFIG --libs` ++ ac_sdl_ldflags=${ac_sdl_ldflags//-mwindows/} + LIBS="$LIBS $ac_sdl_ldflags" + else + AC_MSG_RESULT([Unsupported SDL version]) +diff -ruN pjsip/build.mak.in patch/build.mak.in +--- pjsip/build.mak.in 2024-09-03 11:24:53 ++++ patch/build.mak.in 2024-09-03 11:27:36 +@@ -200,13 +200,22 @@ + AC_PJMEDIA_VIDEO_HAS_IOS_OPENGL = @ac_pjmedia_video_has_ios_opengl@ + DARWIN_CFLAGS = @ac_darwin_cflags@ + ++# mingw ++AC_PJMEDIA_VIDEO_DEV_HAS_DSHOW = @ac_pjmedia_video_dev_has_dshow@ ++ifeq (@ac_pjmedia_video_dev_has_dshow@,yes) ++DSHOW_CFLAGS = @ac_dshow_cflags@ ++DSHOW_LDFLAGS = @ac_dshow_ldflags@ ++APP_THIRD_PARTY_LIB_FILES += $(PJ_DIR)/third_party/lib/libbaseclasses-$(LIB_SUFFIX) ++APP_THIRD_PARTY_LIBS += -lbaseclasses-$(TARGET_NAME) ++endif ++ + # Android + ANDROID_CFLAGS = @ac_android_cflags@ + + # PJMEDIA features exclusion +-PJ_VIDEO_CFLAGS += $(SDL_CFLAGS) $(FFMPEG_CFLAGS) $(V4L2_CFLAGS) $(QT_CFLAGS) \ ++PJ_VIDEO_CFLAGS += $(SDL_CFLAGS) $(FFMPEG_CFLAGS) $(V4L2_CFLAGS) $(DSHOW_CFLAGS) $(QT_CFLAGS) \ + $(OPENH264_CFLAGS) $(VPX_CFLAGS) $(DARWIN_CFLAGS) +-PJ_VIDEO_LDFLAGS += $(SDL_LDFLAGS) $(FFMPEG_LDFLAGS) $(V4L2_LDFLAGS) \ ++PJ_VIDEO_LDFLAGS += $(SDL_LDFLAGS) $(FFMPEG_LDFLAGS) $(V4L2_LDFLAGS) $(DSHOW_LDFLAGS) \ + $(OPENH264_LDFLAGS) $(VPX_LDFLAGS) + + # CFLAGS, LDFLAGS, and LIBS to be used by applications +diff -ruN pjsip/pjmedia/build/os-auto.mak.in patch/pjmedia/build/os-auto.mak.in +--- pjsip/pjmedia/build/os-auto.mak.in 2024-09-03 11:24:53 ++++ patch/pjmedia/build/os-auto.mak.in 2024-09-03 11:27:36 +@@ -18,6 +18,10 @@ + V4L2_CFLAGS = @ac_v4l2_cflags@ + V4L2_LDFLAGS = @ac_v4l2_ldflags@ + ++# Directshow ++DSHOW_CFLAGS = @ac_dshow_cflags@ ++DSHOW_LDFLAGS = @ac_dshow_ldflags@ ++ + # QT + AC_PJMEDIA_VIDEO_HAS_QT = @ac_pjmedia_video_has_qt@ + # QT_CFLAGS = @ac_qt_cflags@ +@@ -39,10 +43,10 @@ + + # PJMEDIA features exclusion + export CFLAGS += @ac_no_small_filter@ @ac_no_large_filter@ @ac_no_speex_aec@ \ +- $(SDL_CFLAGS) $(FFMPEG_CFLAGS) $(V4L2_CFLAGS) $(QT_CFLAGS) \ ++ $(SDL_CFLAGS) $(FFMPEG_CFLAGS) $(V4L2_CFLAGS) $(DSHOW_CFLAGS) $(QT_CFLAGS) \ + $(DARWIN_CFLAGS) $(ANDROID_CFLAGS) \ + $(OPENH264_CFLAGS) $(VPX_CFLAGS) +-export LDFLAGS += $(SDL_LDFLAGS) $(FFMPEG_LDFLAGS) $(V4L2_LDFLAGS) \ ++export LDFLAGS += $(SDL_LDFLAGS) $(FFMPEG_LDFLAGS) $(V4L2_LDFLAGS) $(DSHOW_LDFLAGS) \ + $(OPENH264_LDFLAGS) $(VPX_LDFLAGS) + + # Define the desired sound device backend +@@ -287,6 +291,14 @@ + # + ifeq ($(AC_PJMEDIA_VIDEO_HAS_IOS_OPENGL),yes) + export PJMEDIA_VIDEODEV_OBJS += ios_opengl_dev.o ++endif ++ ++# ++# Directshow video device ++# ++ifeq ($(AC_PJMEDIA_VIDEO_DEV_HAS_DSHOW),yes) ++export PJMEDIA_VIDEODEV_OBJS += dshow_dev.o dshowclasses.o ++export CFLAGS += -I$(THIRD_PARTY)/BaseClasses + endif + + # +diff -ruN pjsip/pjmedia/src/pjmedia-videodev/dshow_dev.c patch/pjmedia/src/pjmedia-videodev/dshow_dev.c +--- pjsip/pjmedia/src/pjmedia-videodev/dshow_dev.c 2024-09-03 11:24:53 ++++ patch/pjmedia/src/pjmedia-videodev/dshow_dev.c 2024-09-03 11:20:53 +@@ -38,6 +38,12 @@ + # define DIBSIZE(BI) ((BI).biHeight < 0 ? (-1)*(_DIBSIZE(BI)) : _DIBSIZE(BI)) + #endif + ++#ifdef _MSC_VER ++# pragma warning(pop) ++#else ++#include ++#endif ++ + #define THIS_FILE "dshow_dev.c" + #define DEFAULT_CLOCK_RATE 90000 + #define DEFAULT_WIDTH 640 +diff -ruN pjsip/pjsip/build/Makefile patch/pjsip/build/Makefile +--- pjsip/pjsip/build/Makefile 2020-02-14 10:48:27 ++++ patch/pjsip/build/Makefile 2024-09-03 11:27:49 +@@ -163,7 +163,7 @@ + export PJSUA2_TEST_OBJS += $(OS_OBJS) $(M_OBJS) $(CC_OBJS) $(HOST_OBJS) \ + main.o + export PJSUA2_TEST_CFLAGS += $(_CFLAGS) $(PJ_VIDEO_CFLAGS) +-export PJSUA2_TEST_CXXFLAGS = $(_CXXFLAGS) $(PJSUA2_LIB_CFLAGS) ++export PJSUA2_TEST_CXXFLAGS = $(_CXXFLAGS) $(PJSUA2_LIB_CFLAGS) $(PJ_VIDEO_CFLAGS) + export PJSUA2_TEST_LDFLAGS += $(PJ_LDXXFLAGS) $(PJ_LDXXLIBS) $(LDFLAGS) + ifeq ($(EXCLUDE_APP),0) + export PJSUA2_TEST_EXE := pjsua2-test-$(TARGET_NAME)$(HOST_EXE) +@@ -182,7 +182,7 @@ + tsx_basic_test.o tsx_bench.o tsx_uac_test.o \ + tsx_uas_test.o txdata_test.o uri_test.o \ + inv_offer_answer_test.o +-export TEST_CFLAGS += $(_CFLAGS) ++export TEST_CFLAGS += $(_CFLAGS) $(PJ_VIDEO_CFLAGS) + export TEST_CXXFLAGS += $(_CXXFLAGS) + export TEST_LDFLAGS += $(PJSIP_LDLIB) \ + $(PJSIP_UA_LDLIB) \ +diff -ruN pjsip/pjsip/src/pjsua2-test/main.cpp patch/pjsip/src/pjsua2-test/main.cpp +--- pjsip/pjsip/src/pjsua2-test/main.cpp 2020-02-14 10:48:27 ++++ patch/pjsip/src/pjsua2-test/main.cpp 2024-09-03 11:27:49 +@@ -20,6 +20,7 @@ + + using namespace pj; + ++extern "C" + int main(int argc, char *argv[]) + { + Endpoint ep; +diff -ruN pjsip/pjsip-apps/build/Samples.mak patch/pjsip-apps/build/Samples.mak +--- pjsip/pjsip-apps/build/Samples.mak 2020-02-14 10:48:27 ++++ patch/pjsip-apps/build/Samples.mak 2024-09-03 11:27:49 +@@ -7,8 +7,8 @@ + ############################################################################### + # Gather all flags. + # +-export _CFLAGS := $(PJ_CFLAGS) $(CFLAGS) +-export _CXXFLAGS:= $(PJ_CXXFLAGS) $(CFLAGS) ++export _CFLAGS := $(PJ_CFLAGS) $(CFLAGS) $(PJ_VIDEO_CFLAGS) ++export _CXXFLAGS:= $(PJ_CXXFLAGS) $(CFLAGS) $(PJ_VIDEO_CFLAGS) + export _LDFLAGS := $(PJ_LDFLAGS) $(PJ_LDLIBS) $(LDFLAGS) + export _LDXXFLAGS := $(PJ_LDXXFLAGS) $(PJ_LDXXLIBS) $(LDFLAGS) + +diff -ruN pjsip/pjsip-apps/src/samples/pjsua2_demo.cpp patch/pjsip-apps/src/samples/pjsua2_demo.cpp +--- pjsip/pjsip-apps/src/samples/pjsua2_demo.cpp 2020-02-14 10:48:27 ++++ patch/pjsip-apps/src/samples/pjsua2_demo.cpp 2024-09-03 11:27:49 +@@ -410,6 +410,7 @@ + } + + ++extern "C" + int main() + { + int ret = 0; +diff -ruN pjsip/third_party/BaseClasses/amvideo2.h patch/third_party/BaseClasses/amvideo2.h +--- pjsip/third_party/BaseClasses/amvideo2.h 1970-01-01 01:00:00 ++++ patch/third_party/BaseClasses/amvideo2.h 2024-09-03 11:27:49 +@@ -0,0 +1,26 @@ ++/* ++ Some necessary macros are missing from mingw version. They are here. ++ See https://github.com/ofTheo/videoInput/blob/master/videoInputSrcAndDemos/libs/DShow/Include/amvideo.h ++*/ ++//------------------------------------------------------------------------------ ++// File: AMVideo.h ++// ++// Desc: Video related definitions and interfaces for ActiveMovie. ++// ++// Copyright (c) 1992 - 2001, Microsoft Corporation. All rights reserved. ++//------------------------------------------------------------------------------ ++ ++#define TRUECOLOR(pbmi) ((TRUECOLORINFO *)(((LPBYTE)&((pbmi)->bmiHeader)) \ ++ + (pbmi)->bmiHeader.biSize)) ++#define COLORS(pbmi) ((RGBQUAD *)(((LPBYTE)&((pbmi)->bmiHeader)) \ ++ + (pbmi)->bmiHeader.biSize)) ++ ++#define SIZE_MASKS (iMASK_COLORS * sizeof(DWORD)) ++#define SIZE_PREHEADER (FIELD_OFFSET(VIDEOINFOHEADER,bmiHeader)) ++ ++#define WIDTHBYTES(bits) ((DWORD)(((bits)+31) & (~31)) / 8) ++#define DIBWIDTHBYTES(bi) (DWORD)WIDTHBYTES((DWORD)(bi).biWidth * (DWORD)(bi).biBitCount) ++#define _DIBSIZE(bi) (DIBWIDTHBYTES(bi) * (DWORD)(bi).biHeight) ++#define DIBSIZE(bi) ((bi).biHeight < 0 ? (-1)*(_DIBSIZE(bi)) : _DIBSIZE(bi)) ++ ++#define PALETTISED(pbmi) ((pbmi)->bmiHeader.biBitCount <= iPALETTE) +diff -ruN pjsip/third_party/BaseClasses/arithutil.cpp patch/third_party/BaseClasses/arithutil.cpp +--- pjsip/third_party/BaseClasses/arithutil.cpp 2020-02-14 10:48:27 ++++ patch/third_party/BaseClasses/arithutil.cpp 2024-09-03 11:27:49 +@@ -21,7 +21,7 @@ + // Enlarged integer divide - 64-bits / 32-bits > 32-bits + // + +-#ifndef _X86_ ++#if !defined(_X86_) || !defined(_MSC_VER) + + #define LLtoU64(x) (*(unsigned __int64*)(void*)(&(x))) + +diff -ruN pjsip/third_party/BaseClasses/sal2.h patch/third_party/BaseClasses/sal2.h +--- pjsip/third_party/BaseClasses/sal2.h 1970-01-01 01:00:00 ++++ patch/third_party/BaseClasses/sal2.h 2024-09-03 11:27:49 +@@ -0,0 +1,19 @@ ++/* ++ See https://github.com/RobertBeckebans/RBDOOM-3-BFG/blob/master/neo/libs/mingw-hacks/sal.h ++*/ ++/* From PortAudio, which is under MIT license: ++ * https://www.assembla.com/code/portaudio/subversion/nodes/portaudio/trunk/src/hostapi/wasapi/mingw-include/sal.h ++ */ ++#pragma once ++ ++#if __GNUC__ >=3 ++#pragma GCC system_header ++#endif ++ ++#define __in ++#define __out ++#define __deref_in ++#define __deref_inout_opt ++#define __field_ecount_opt(x) ++#define __in_bcount_opt(size) ++ +diff -ruN pjsip/third_party/BaseClasses/streams.h patch/third_party/BaseClasses/streams.h +--- pjsip/third_party/BaseClasses/streams.h 2020-02-14 10:48:27 ++++ patch/third_party/BaseClasses/streams.h 2024-09-03 11:27:49 +@@ -23,6 +23,11 @@ + #else + #define AM_NOVTABLE + #endif ++#else ++ #include ++ #include ++ #define AM_NOVTABLE ++ #pragma GCC diagnostic ignored "-Wwrite-strings" + #endif // MSC_VER + + +@@ -193,6 +198,13 @@ + //#include // External device control interface defines + //#include // audio filter device error event codes + ++#ifndef _MSC_VER ++ ++#define min(a,b) ({ __typeof__ (a) _a = (a); __typeof__ (b) _b = (b); _a < _b ? _a : _b; }) ++#include ++ ++#endif ++ + + #else + #ifdef DEBUG +diff -ruN pjsip/third_party/BaseClasses/wxutil.cpp patch/third_party/BaseClasses/wxutil.cpp +--- pjsip/third_party/BaseClasses/wxutil.cpp 2020-02-14 10:48:27 ++++ patch/third_party/BaseClasses/wxutil.cpp 2024-09-03 11:27:49 +@@ -384,7 +384,7 @@ + { + void * ret = dst; + +-#ifdef _X86_ ++#if defined(_X86_) && defined(_MSC_VER) + if (dst <= src || (char *)dst >= ((char *)src + count)) { + + /* +@@ -432,6 +432,7 @@ + return ret; + } + ++#ifdef _MSC_VER + HRESULT AMSafeMemMoveOffset( + __in_bcount(dst_size) void * dst, + __in size_t dst_size, +@@ -458,6 +459,7 @@ + memmoveInternal( (BYTE *)dst+cb_dst_offset, (BYTE *)src+cb_src_offset, count); + return S_OK; + } ++#endif + + + #ifdef DEBUG +diff -ruN pjsip/third_party/BaseClasses/wxutil.h patch/third_party/BaseClasses/wxutil.h +--- pjsip/third_party/BaseClasses/wxutil.h 2020-02-14 10:48:27 ++++ patch/third_party/BaseClasses/wxutil.h 2024-09-03 11:27:49 +@@ -337,6 +337,7 @@ + } + }; + ++#ifdef _MSC_VER + // Ensures that memory is not read past the length source buffer + // and that memory is not written past the length of the dst buffer + // dst - buffer to copy to +@@ -358,13 +359,14 @@ + __in size_t src_size, + __in DWORD cb_src_offset, + __in size_t count); ++#endif + + extern "C" + void * __stdcall memmoveInternal(void *, const void *, size_t); + + inline void * __cdecl memchrInternal(const void *buf, int chr, size_t cnt) + { +-#ifdef _X86_ ++#if defined(_X86_) && defined(_MSC_VER) + void *pRet = NULL; + + _asm { +diff -ruN pjsip/third_party/build/baseclasses/Makefile patch/third_party/build/baseclasses/Makefile +--- pjsip/third_party/build/baseclasses/Makefile 1970-01-01 01:00:00 ++++ patch/third_party/build/baseclasses/Makefile 2024-09-03 11:27:49 +@@ -0,0 +1,72 @@ ++include ../../../build.mak ++include ../../../build/common.mak ++ ++export LIBDIR := ../../lib ++ ++RULES_MAK := $(PJDIR)/build/rules.mak ++ ++export BASECLASSES_LIB := libbaseclasses-$(TARGET_NAME)$(LIBEXT) ++ ++ifeq ($(PJ_SHARED_LIBRARIES),) ++else ++export BASECLASSES_SONAME := libbaseclasses.$(SHLIB_SUFFIX) ++export BASECLASSES_SHLIB := $(BASECLASSES_SONAME).$(PJ_VERSION_MAJOR) ++endif ++ ++############################################################################### ++# Gather all flags. ++# ++export _CFLAGS := $(CC_CFLAGS) $(OS_CFLAGS) $(HOST_CFLAGS) $(M_CFLAGS) \ ++ $(CFLAGS) $(CC_INC)../../BaseClasses \ ++ $(CC_INC)../../../pjmedia/include $(CC_INC)../../../pjlib/include ++export _CXXFLAGS:= $(_CFLAGS) $(CC_CXXFLAGS) $(OS_CXXFLAGS) $(M_CXXFLAGS) \ ++ $(HOST_CXXFLAGS) $(CXXFLAGS) ++export _LDFLAGS := $(CC_LDFLAGS) $(OS_LDFLAGS) $(M_LDFLAGS) $(HOST_LDFLAGS) \ ++ $(LDFLAGS) ++ ++export BASECLASSES_SRCDIR = ../../BaseClasses ++export BASECLASSES_OBJS = amfilter.o amvideo.o arithutil.o combase.o ctlutil.o \ ++ mtype.o renbase.o wxdebug.o wxlist.o \ ++ wxutil.o ++ ++export BASECLASSES_CFLAGS = $(_CFLAGS) ++export BASECLASSES_CXXFLAGS = -fpermissive -D__STRSAFE__NO_INLINE=1 -DPJMEDIA_VIDEO_DEV_HAS_DSHOW=1 $(_CFLAGS) ++ ++ ++export CC_OUT CC AR RANLIB HOST_MV HOST_RM HOST_RMDIR HOST_MKDIR OBJEXT LD LDOUT ++############################################################################### ++# Main entry ++# ++# $(TARGET) is defined in os-$(OS_NAME).mak file in current directory. ++# ++TARGETS := $(BASECLASSES_LIB) $(BASECLASSES_SONAME) ++ ++all: $(TARGETS) ++ ++doc: ++ cd .. && doxygen docs/doxygen.cfg ++ ++dep: depend ++distclean: realclean ++ ++.PHONY: all dep depend clean realclean distclean ++.PHONY: $(TARGETS) ++.PHONY: $(BASECLASSES_LIB) $(BASECLASSES_SONAME) ++ ++libbaseclasses: $(BASECLASSES_LIB) ++$(BASECLASSES_SONAME): $(BASECLASSES_LIB) ++$(BASECLASSES_LIB) $(BASECLASSES_SONAME): ++ $(MAKE) -f $(RULES_MAK) APP=BASECLASSES app=baseclasses $(subst /,$(HOST_PSEP),$(LIBDIR)/$@) ++ ++clean print_lib: ++ $(MAKE) -f $(RULES_MAK) APP=BASECLASSES app=baseclasses $@ ++ ++realclean: ++ $(subst @@,$(subst /,$(HOST_PSEP),.ilbc-$(TARGET_NAME).depend),$(HOST_RMR)) ++ ++ $(MAKE) -f $(RULES_MAK) APP=BASECLASSES app=baseclasses $@ ++ ++depend: ++ $(MAKE) -f $(RULES_MAK) APP=BASECLASSES app=baseclasses $@ ++ ++ +diff -ruN pjsip/third_party/build/os-auto.mak.in patch/third_party/build/os-auto.mak.in +--- pjsip/third_party/build/os-auto.mak.in 2024-09-03 11:24:53 ++++ patch/third_party/build/os-auto.mak.in 2024-09-03 11:27:49 +@@ -39,6 +39,10 @@ + endif + endif + ++ifneq ($(findstring windows_os,@ac_pjmedia_video@),) ++DIRS += baseclasses ++endif ++ + ifneq (@ac_external_srtp@,0) + # External SRTP + else diff --git a/deps/patches/008_support_mingw_w64.patch b/deps/patches/008_support_mingw_w64.patch new file mode 100644 index 00000000..294a8d5d --- /dev/null +++ b/deps/patches/008_support_mingw_w64.patch @@ -0,0 +1,70 @@ +diff -ruN pjsip/Makefile pjsip-patch/Makefile +--- pjsip/Makefile 2020-02-14 10:48:27.000000000 +0100 ++++ pjsip-patch/Makefile 2024-09-03 10:32:23.926160100 +0200 +@@ -129,10 +129,9 @@ + sed -e "s!@INCLUDEDIR@!$(includedir)!" | \ + sed -e "s!@LIBDIR@!$(libdir)!" | \ + sed -e "s/@PJ_VERSION@/$(PJ_VERSION)/" | \ +- sed -e "s!@PJ_LDLIBS@!!" | \ +- sed -e "s!@PJ_LDXXLIBS@!$(PJ_LDXXLIBS)!" | \ +- sed -e "s!@PJ_INSTALL_CFLAGS@!!" | \ +- sed -e "s!@PJ_INSTALL_CXXFLAGS@!$(PJ_INSTALL_CXXFLAGS)!" > $(DESTDIR)/$(libdir)/pkgconfig/libpjproject.pc ++ sed -e "s!@PJ_INSTALL_LDFLAGS@!$(PJ_INSTALL_LDFLAGS)!" | \ ++ sed -e "s!@PJ_INSTALL_LDFLAGS_PRIVATE@!$(PJ_INSTALL_LDFLAGS_PRIVATE)!" | \ ++ sed -e "s!@PJ_INSTALL_CFLAGS@!$(PJ_INSTALL_CFLAGS)!" > $(DESTDIR)$(libdir)/pkgconfig/libpjproject.pc + + uninstall: + $(RM) $(DESTDIR)$(libdir)/pkgconfig/libpjproject.pc +diff -ruN pjsip/aconfigure pjsip-patch/aconfigure +--- pjsip/aconfigure 2024-09-03 10:10:13.926165600 +0200 ++++ pjsip-patch/aconfigure 2024-09-03 10:32:23.941785600 +0200 +@@ -5156,6 +5156,12 @@ + + $as_echo "#define WIN32_LEAN_AND_MEAN 1" >>confdefs.h + ++ case $target in ++ *_64-w64-mingw* ) ++ $as_echo "#define PJ_WIN64 1" >>confdefs.h ++ ++ ;; ++ esac + ;; + *darwin*) + $as_echo "#define PJ_DARWINOS 1" >>confdefs.h +diff -ruN pjsip/aconfigure.ac pjsip-patch/aconfigure.ac +--- pjsip/aconfigure.ac 2020-02-14 10:48:27.000000000 +0100 ++++ pjsip-patch/aconfigure.ac 2024-09-03 10:32:23.973036300 +0200 +@@ -161,6 +161,11 @@ + AC_DEFINE(PJ_WIN32,1) + AC_DEFINE(PJ_WIN32_WINNT,0x0400) + AC_DEFINE(WIN32_LEAN_AND_MEAN) ++ case $target in ++ *_64-w64-mingw* ) ++ AC_DEFINE(PJ_WIN64,1) ++ ;; ++ esac + ;; + *darwin*) + AC_DEFINE(PJ_DARWINOS,1) +diff -ruN pjsip/pjlib/include/pj/compat/os_auto.h.in pjsip-patch/pjlib/include/pj/compat/os_auto.h.in +--- pjsip/pjlib/include/pj/compat/os_auto.h.in 2020-02-14 10:48:27.000000000 +0100 ++++ pjsip-patch/pjlib/include/pj/compat/os_auto.h.in 2024-09-03 10:32:23.988659900 +0200 +@@ -30,6 +30,7 @@ + #undef PJ_OS_NAME + + /* Legacy macros */ ++#undef PJ_WIN64 + #undef PJ_WIN32 + #undef PJ_WIN32_WINNT + #undef WIN32_LEAN_AND_MEAN +diff -ruN pjsip/pjnath/src/pjnath-test/stun_sock_test.c pjsip-patch/pjnath/src/pjnath-test/stun_sock_test.c +--- pjsip/pjnath/src/pjnath-test/stun_sock_test.c 2020-02-14 10:48:27.000000000 +0100 ++++ pjsip-patch/pjnath/src/pjnath-test/stun_sock_test.c 2024-09-03 10:32:23.988659900 +0200 +@@ -25,7 +25,6 @@ + RESPOND_STUN = 1, + WITH_MAPPED = 2, + WITH_XOR_MAPPED = 4, +- + ECHO = 8 + }; +