diff -ruN a/modules/h264passcodec/avcodec.c b/modules/h264passcodec/avcodec.c
--- a/modules/h264passcodec/avcodec.c	1970-01-01 03:00:00.000000000 +0300
+++ b/modules/h264passcodec/avcodec.c	2023-01-30 12:10:57.054035500 +0300
@@ -0,0 +1,119 @@
+/**
+ * @file avcodec.c  Video codecs using libavcodec
+ *
+ * Copyright (C) 2010 - 2016 Alfred E. Heggestad
+ */
+#include <re.h>
+#include <rem.h>
+#include <baresip.h>
+#include "h26x.h"
+#include "avcodec.h"
+#include "defines.h"
+
+/**
+ * @defgroup avcodec avcodec
+ *
+ * Video codecs using libavcodec
+ *
+ * This module implements H.263, H.264 and H.265 video codecs
+ * using libavcodec from FFmpeg or libav projects.
+ *
+ *
+ * Config options:
+ *
+ \verbatim
+      avcodec_h264enc  <NAME>  ; e.g. h264_nvenc, h264_videotoolbox
+      avcodec_h264dec  <NAME>  ; e.g. h264_cuvid, h264_vda, h264_qsv
+ \endverbatim
+ *
+ * References:
+ *
+ *     http://ffmpeg.org
+ *
+ *     https://libav.org
+ *
+ *     RTP Payload Format for H.264 Video
+ *     https://tools.ietf.org/html/rfc6184
+ */
+
+
+//const AVCodec *avcodec_h264enc;      /* optional; specified H.264 encoder */
+//const AVCodec *avcodec_h264dec;      /* optional; specified H.264 decoder */
+
+
+
+int avcodec_resolve_codecid(const char *s)
+{
+	if (0 == str_casecmp(s, "H264"))
+		return AV_CODEC_ID_H264;
+	else
+		return AV_CODEC_ID_NONE;
+}
+
+
+static struct vidcodec h264 = {
+	.name      = "H264",
+	.variant   = "packetization-mode=0",
+	.encupdh   = avcodec_encode_update,
+	.ench      = avcodec_encode,
+	.decupdh   = NULL,
+	.dech      = NULL,
+	.fmtp_ench = avcodec_h264_fmtp_enc,
+	.fmtp_cmph = avcodec_h264_fmtp_cmp,
+	.packetizeh= avcodec_packetize,
+};
+
+static struct vidcodec h264_1 = {
+	.name      = "H264",
+	.variant   = "packetization-mode=1",
+	.encupdh   = avcodec_encode_update,
+	.ench      = avcodec_encode,
+	.decupdh   = NULL,
+	.dech      = NULL,
+	.fmtp_ench = avcodec_h264_fmtp_enc,
+	.fmtp_cmph = avcodec_h264_fmtp_cmp,
+	.packetizeh= avcodec_packetize,
+};
+
+static int module_init(void)
+{
+	struct list *vidcodecl = baresip_vidcodecl();
+	char h264enc[64] = "h264";
+	char h264dec[64] = "h264";
+
+	conf_get_str(conf_cur(), "avcodec_h264enc", h264enc, sizeof(h264enc));
+	conf_get_str(conf_cur(), "avcodec_h264dec", h264dec, sizeof(h264dec));
+
+    printf(">>>>>>>>>init h264passcodec\n");
+    //register 
+    vidcodec_register(vidcodecl, &h264);
+    vidcodec_register(vidcodecl, &h264_1);
+
+/*
+	if (avcodec_h264enc) {
+		info("avcodec: using H.264 encoder '%s' -- %s\n",
+		     avcodec_h264enc->name, avcodec_h264enc->long_name);
+	}
+	if (avcodec_h264dec) {
+		info("avcodec: using H.264 decoder '%s' -- %s\n",
+		     avcodec_h264dec->name, avcodec_h264dec->long_name);
+	}
+*/
+	return 0;
+}
+
+
+static int module_close(void)
+{
+	vidcodec_unregister(&h264);
+
+	return 0;
+}
+
+
+EXPORT_SYM const struct mod_export DECL_EXPORTS(h264passcodec) = {
+	"h264passcodec",
+	"codec",
+	module_init,
+	module_close
+};
diff -ruN a/modules/h264passcodec/avcodec.h b/modules/h264passcodec/avcodec.h
--- a/modules/h264passcodec/avcodec.h	1970-01-01 03:00:00.000000000 +0300
+++ b/modules/h264passcodec/avcodec.h	2023-01-27 21:19:26.141734000 +0300
@@ -0,0 +1,43 @@
+/**
+ * @file avcodec.h  Video codecs using libavcodec -- internal API
+ *
+ * Copyright (C) 2010 Alfred E. Heggestad
+ */
+
+
+/*
+ * Encode
+ */
+
+struct videnc_state;
+
+int avcodec_encode_update(struct videnc_state **vesp,
+			  const struct vidcodec *vc,
+			  struct videnc_param *prm, const char *fmtp,
+			  videnc_packet_h *pkth, void *arg);
+int avcodec_encode(struct videnc_state *st, bool update,
+		   const struct vidframe *frame, uint64_t timestamp);
+int avcodec_packetize(struct videnc_state *st, const struct vidpacket *packet);
+
+
+int avcodec_decode_update(struct viddec_state **vdsp,
+			  const struct vidcodec *vc, const char *fmtp);
+int avcodec_decode_h263(struct viddec_state *st, struct vidframe *frame,
+		bool *intra, bool eof, uint16_t seq, struct mbuf *src);
+int avcodec_decode_h264(struct viddec_state *st, struct vidframe *frame,
+		bool *intra, bool eof, uint16_t seq, struct mbuf *src);
+int avcodec_decode_h265(struct viddec_state *st, struct vidframe *frame,
+			bool *intra, bool eof, uint16_t seq, struct mbuf *src);
+
+
+int avcodec_resolve_codecid(const char *s);
+
+
+/*
+ * SDP
+ */
+
+uint32_t h264_packetization_mode(const char *fmtp);
+int avcodec_h264_fmtp_enc(struct mbuf *mb, const struct sdp_format *fmt,
+		  bool offer, void *arg);
+bool avcodec_h264_fmtp_cmp(const char *lfmtp, const char *rfmtp, void *data);
diff -ruN a/modules/h264passcodec/defines.h b/modules/h264passcodec/defines.h
--- a/modules/h264passcodec/defines.h	1970-01-01 03:00:00.000000000 +0300
+++ b/modules/h264passcodec/defines.h	2023-01-28 20:25:39.609698100 +0300
@@ -0,0 +1,14 @@
+#ifndef __DEFINES_H
+#define __DEFINES_H
+
+//some defines from ffmpeg
+
+
+//only used items have declared
+enum AVCodecID {
+    AV_CODEC_ID_NONE,
+    AV_CODEC_ID_H264
+};
+
+
+#endif
diff -ruN a/modules/h264passcodec/encode.c b/modules/h264passcodec/encode.c
--- a/modules/h264passcodec/encode.c	1970-01-01 03:00:00.000000000 +0300
+++ b/modules/h264passcodec/encode.c	2023-01-30 12:10:13.244035500 +0300
@@ -0,0 +1,318 @@
+/**
+ * @file avcodec/encode.c  Video codecs using libavcodec -- encoder
+ *
+ * Copyright (C) 2010 - 2013 Alfred E. Heggestad
+ * Copyright (C) 2021 by:
+ *     Media Magic Technologies <developer@mediamagictechnologies.com>
+ *     and Divus GmbH <developer@divus.eu>
+ */
+#include <re.h>
+#include <rem.h>
+#include <baresip.h>
+#include "h26x.h"
+#include "avcodec.h"
+#include "defines.h"
+
+
+enum {
+	KEYFRAME_INTERVAL = 10  /* Keyframes per second */
+};
+
+
+struct picsz {
+	enum h263_fmt fmt;  /**< Picture size */
+	uint8_t mpi;        /**< Minimum Picture Interval (1-32) */
+};
+
+
+struct videnc_state {
+//	const AVCodec *codec;
+//	AVCodecContext *ctx;
+	struct mbuf *mb_frag;
+	struct videnc_param encprm;
+	struct vidsz encsize;
+	enum vidfmt fmt;
+	enum AVCodecID codec_id;
+	videnc_packet_h *pkth;
+	void *arg;
+
+	union {
+		struct {
+			struct picsz picszv[8];
+			uint32_t picszn;
+		} h263;
+
+		struct {
+			uint32_t packetization_mode;
+			uint32_t profile_idc;
+			uint32_t profile_iop;
+			uint32_t level_idc;
+			uint32_t max_fs;
+			uint32_t max_smbps;
+		} h264;
+	} u;
+};
+
+
+static void destructor(void *arg)
+{
+	struct videnc_state *st = arg;
+
+	mem_deref(st->mb_frag);
+
+//	if (st->ctx)
+//		avcodec_free_context(&st->ctx);
+}
+
+
+static int init_encoder(struct videnc_state *st, const char *name)
+{
+	/*
+	 * Special handling of H.264 encoder
+	 */
+
+    printf(">>>>>init encoder\n");
+/*
+	if (st->codec_id == AV_CODEC_ID_H264 && avcodec_h264enc) {
+
+		st->codec = avcodec_h264enc;
+
+		info("avcodec: h264 encoder activated\n");
+
+		return 0;
+	}
+
+	st->codec = avcodec_find_encoder(st->codec_id);
+	if (!st->codec)
+		return ENOENT;
+*/
+	return 0;
+}
+
+
+static int open_encoder(struct videnc_state *st,
+			const struct videnc_param *prm,
+			const struct vidsz *size,
+			int pix_fmt)
+{
+	int err = 0;
+
+    printf(">>>>>open encoder\n");
+//	if (st->ctx)
+//		avcodec_free_context(&st->ctx);
+
+//	st->ctx = avcodec_alloc_context3(st->codec);
+//	if (!st->ctx) {
+//		err = ENOMEM;
+//		goto out;
+//	}
+
+//	av_opt_set_defaults(st->ctx);
+
+/*	st->ctx->bit_rate  = prm->bitrate;
+	st->ctx->width     = size->w;
+	st->ctx->height    = size->h;
+
+    st->ctx->pix_fmt   = pix_fmt;
+
+	st->ctx->time_base.num = 1;
+	st->ctx->time_base.den = prm->fps;
+	st->ctx->gop_size = KEYFRAME_INTERVAL * prm->fps;
+
+	if (0 == str_cmp(st->codec->name, "h264")) {
+
+		av_opt_set(st->ctx->priv_data, "profile", "baseline", 0);
+		av_opt_set(st->ctx->priv_data, "preset", "ultrafast", 0);
+		av_opt_set(st->ctx->priv_data, "tune", "zerolatency", 0);
+
+		if (st->u.h264.packetization_mode == 0) {
+			av_opt_set_int(st->ctx->priv_data,
+				       "slice-max-size", prm->pktsize, 0);
+		}
+	}
+*/
+
+	/* params to avoid libavcodec/x264 default preset error */
+/*	if (st->codec_id == AV_CODEC_ID_H264) {
+
+    	av_opt_set(st->ctx->priv_data, "profile", "baseline", 0);
+    }
+
+	st->ctx->me_range = 16;
+	st->ctx->qmin = 10;
+	st->ctx->qmax = 51;
+	st->ctx->max_qdiff = 4;
+
+	if (avcodec_open2(st->ctx, st->codec, NULL) < 0) {
+		err = ENOENT;
+		goto out;
+	}
+*/
+	st->encsize = *size;
+
+ out:
+	if (err) {
+/*
+		if (st->ctx)
+			avcodec_free_context(&st->ctx);
+*/
+	}
+
+	return err;
+}
+
+
+static int decode_sdpparam_h264(struct videnc_state *st, const struct pl *name,
+                                const struct pl *val)
+{
+        if (0 == pl_strcasecmp(name, "packetization-mode")) {
+                st->u.h264.packetization_mode = pl_u32(val);
+
+                if (st->u.h264.packetization_mode != 0 &&
+                    st->u.h264.packetization_mode != 1 ) {
+                        warning("avcodec: illegal packetization-mode %u\n",
+                                st->u.h264.packetization_mode);
+                        return EPROTO;
+                }
+        }
+        else if (0 == pl_strcasecmp(name, "profile-level-id")) {
+                struct pl prof = *val;
+                if (prof.l != 6) {
+                        warning("avcodec: invalid profile-level-id (%r)\n",
+                                val);
+                        return EPROTO;
+                }
+
+                prof.l = 2;
+                st->u.h264.profile_idc = pl_x32(&prof); prof.p += 2;
+                st->u.h264.profile_iop = pl_x32(&prof); prof.p += 2;
+                st->u.h264.level_idc   = pl_x32(&prof);
+        }
+        else if (0 == pl_strcasecmp(name, "max-fs")) {
+                st->u.h264.max_fs = pl_u32(val);
+        }
+        else if (0 == pl_strcasecmp(name, "max-smbps")) {
+                st->u.h264.max_smbps = pl_u32(val);
+        }
+
+        return 0;
+}
+
+static void param_handler(const struct pl *name, const struct pl *val,
+              void *arg)
+{
+    struct videnc_state *st = arg;
+
+    if (st->codec_id == AV_CODEC_ID_H264)
+        (void)decode_sdpparam_h264(st, name, val);
+}
+
+int avcodec_encode_update(struct videnc_state **vesp,
+                          const struct vidcodec *vc,
+                          struct videnc_param *prm, const char *fmtp,
+                          videnc_packet_h *pkth, void *arg)
+{
+        struct videnc_state *st;
+        int err = 0;
+
+        if (!vesp || !vc || !prm || !pkth)
+                return EINVAL;
+
+        if (*vesp)
+                return 0;
+
+        st = mem_zalloc(sizeof(*st), destructor);
+        if (!st)
+                return ENOMEM;
+
+        st->encprm = *prm;
+        st->pkth = pkth;
+        st->arg = arg;
+
+        st->codec_id = avcodec_resolve_codecid(vc->name);
+        if (st->codec_id == AV_CODEC_ID_NONE) {
+                warning("avcodec: unknown encoder (%s)\n", vc->name);
+                err = EINVAL;
+                goto out;
+        }
+
+        st->mb_frag = mbuf_alloc(1024);
+        if (!st->mb_frag) {
+                err = ENOMEM;
+                goto out;
+        }
+
+        st->fmt = -1;
+
+        err = init_encoder(st, vc->name);
+        if (err) {
+                warning("avcodec: %s: could not init encoder\n", vc->name);
+                goto out;
+        }
+
+        if (str_isset(fmtp)) {
+                struct pl sdp_fmtp;
+
+                pl_set_str(&sdp_fmtp, fmtp);
+
+                fmt_param_apply(&sdp_fmtp, param_handler, st);
+        }
+
+        debug("avcodec: video encoder %s: %.2f fps, %d bit/s, pktsize=%u\n",
+              vc->name, prm->fps, prm->bitrate, prm->pktsize);
+
+ out:
+        if (err)
+                mem_deref(st);
+        else
+                *vesp = st;
+
+        return err;
+}
+
+int avcodec_encode(struct videnc_state *st, bool update,
+           const struct vidframe *frame, uint64_t timestamp)
+{
+    printf("avcodec_encode\n");
+    return 0;
+}
+
+int avcodec_packetize(struct videnc_state *st, const struct vidpacket *packet)
+{
+	int err = 0;
+	uint64_t ts;
+	struct mbuf mb;
+
+    printf("packetize\n");
+
+	if (!st || !packet)
+		return EINVAL;
+
+    printf("packetize1\n");
+
+	mb.buf = packet->buf;
+	mb.pos = 0;
+	mb.end = packet->size;
+	mb.size = packet->size;
+
+	ts = video_calc_rtp_timestamp_fix(packet->timestamp);
+
+
+	switch (st->codec_id) {
+
+	case AV_CODEC_ID_H264:
+        {
+		    err = h264_packetize(ts, packet->buf, packet->size,
+				     st->encprm.pktsize,
+				     st->pkth, st->arg);
+            printf("h264_packetize size=%d encpktsize=%d, res=%d\n",packet->size, st->encprm.pktsize, err);
+        }
+		break;
+
+	default:
+		err = EPROTO;
+		break;
+	}
+
+	return err;
+}
diff -ruN a/modules/h264passcodec/h26x.h b/modules/h264passcodec/h26x.h
--- a/modules/h264passcodec/h26x.h	1970-01-01 03:00:00.000000000 +0300
+++ b/modules/h264passcodec/h26x.h	2022-03-27 11:22:42.000000000 +0300
@@ -0,0 +1,96 @@
+/**
+ * @file h26x.h  Interface to H.26x video codecs
+ *
+ * Copyright (C) 2010 Alfred E. Heggestad
+ */
+
+
+/*
+ * H.263
+ */
+
+
+enum h263_mode {
+	H263_MODE_A,
+	H263_MODE_B,
+	H263_MODE_C
+};
+
+enum {
+	H263_HDR_SIZE_MODEA = 4,
+	H263_HDR_SIZE_MODEB = 8,
+	H263_HDR_SIZE_MODEC = 12
+};
+
+/** H.263 picture size format */
+enum h263_fmt {
+	H263_FMT_SQCIF = 1, /**<  128 x 96   */
+	H263_FMT_QCIF  = 2, /**<  176 x 144  */
+	H263_FMT_CIF   = 3, /**<  352 x 288  */
+	H263_FMT_4CIF  = 4, /**<  704 x 576  */
+	H263_FMT_16CIF = 5, /**< 1408 x 1152 */
+	H263_FMT_OTHER = 7,
+};
+
+/**
+ * H.263 Header defined in RFC 2190
+ */
+struct h263_hdr {
+
+	/* common */
+	unsigned f:1;      /**< 1 bit  - Flag; 0=mode A, 1=mode B/C         */
+	unsigned p:1;      /**< 1 bit  - PB-frames, 0=mode B, 1=mode C      */
+	unsigned sbit:3;   /**< 3 bits - Start Bit Position (SBIT)          */
+	unsigned ebit:3;   /**< 3 bits - End Bit Position (EBIT)            */
+	unsigned src:3;    /**< 3 bits - Source format                      */
+
+	/* mode A */
+	unsigned i:1;      /**< 1 bit  - 0=intra-coded, 1=inter-coded       */
+	unsigned u:1;      /**< 1 bit  - Unrestricted Motion Vector         */
+	unsigned s:1;      /**< 1 bit  - Syntax-based Arithmetic Coding     */
+	unsigned a:1;      /**< 1 bit  - Advanced Prediction option         */
+	unsigned r:4;      /**< 4 bits - Reserved (zero)                    */
+	unsigned dbq:2;    /**< 2 bits - DBQUANT                            */
+	unsigned trb:3;    /**< 3 bits - Temporal Reference for B-frame     */
+	unsigned tr:8;     /**< 8 bits - Temporal Reference for P-frame     */
+
+	/* mode B */
+	unsigned quant:5; //=0 for GOB header
+	unsigned gobn:5;  // gob number
+	unsigned mba:9;   // address
+	unsigned hmv1:7;  // horizontal motion vector
+	unsigned vmv1:7;  // vertical motion vector
+	unsigned hmv2:7;
+	unsigned vmv2:7;
+
+
+};
+
+enum {I_FRAME=0, P_FRAME=1};
+
+/** H.263 bit-stream header */
+struct h263_strm {
+	uint8_t psc[2];              /**< Picture Start Code (PSC)        */
+
+	uint8_t temp_ref;            /**< Temporal Reference              */
+	unsigned split_scr:1;        /**< Split Screen Indicator          */
+	unsigned doc_camera:1;       /**< Document Camera Indicator       */
+	unsigned pic_frz_rel:1;      /**< Full Picture Freeze Release     */
+	unsigned src_fmt:3;          /**< Source Format. 3=CIF            */
+	unsigned pic_type:1;         /**< Picture Coding Type. 0=I, 1=P   */
+	unsigned umv:1;              /**< Unrestricted Motion Vector mode */
+	unsigned sac:1;              /**< Syntax-based Arithmetic Coding  */
+	unsigned apm:1;              /**< Advanced Prediction mode        */
+	unsigned pb:1;               /**< PB-frames mode                  */
+	unsigned pquant:5;           /**< Quantizer Information           */
+	unsigned cpm:1;              /**< Continuous Presence Multipoint  */
+	unsigned pei:1;              /**< Extra Insertion Information     */
+	/* H.263 bit-stream ... */
+};
+
+int h263_hdr_encode(const struct h263_hdr *hdr, struct mbuf *mb);
+int h263_hdr_decode(struct h263_hdr *hdr, struct mbuf *mb);
+enum h263_mode h263_hdr_mode(const struct h263_hdr *hdr);
+
+int  h263_strm_decode(struct h263_strm *s, struct mbuf *mb);
+void h263_hdr_copy_strm(struct h263_hdr *hdr, const struct h263_strm *s);
diff -ruN a/modules/h264passcodec/module.mk b/modules/h264passcodec/module.mk
--- a/modules/h264passcodec/module.mk	1970-01-01 03:00:00.000000000 +0300
+++ b/modules/h264passcodec/module.mk	2023-01-27 21:27:00.501734000 +0300
@@ -0,0 +1,14 @@
+#
+# module.mk
+#
+# Copyright (C) 2010 Alfred E. Heggestad
+#
+
+MOD		:= h264passcodec
+$(MOD)_SRCS	+= avcodec.c
+$(MOD)_SRCS	+= encode.c
+$(MOD)_SRCS	+= sdp.c
+$(MOD)_CFLAGS	+= 
+$(MOD)_LFLAGS	+= 
+
+include mk/mod.mk
diff -ruN a/modules/h264passcodec/sdp.c b/modules/h264passcodec/sdp.c
--- a/modules/h264passcodec/sdp.c	1970-01-01 03:00:00.000000000 +0300
+++ b/modules/h264passcodec/sdp.c	2023-01-27 21:27:19.881734000 +0300
@@ -0,0 +1,86 @@
+/**
+ * @file avcodec/sdp.c  Video codecs using libavcodec -- SDP functions
+ *
+ * Copyright (C) 2010 Alfred E. Heggestad
+ * Copyright (C) 2021 by:
+ *     Media Magic Technologies <developer@mediamagictechnologies.com>
+ *     and Divus GmbH <developer@divus.eu>
+ */
+
+#include <re.h>
+#include <baresip.h>
+#include "avcodec.h"
+
+
+static char profile_level_id[256] = "";
+
+
+uint32_t h264_packetization_mode(const char *fmtp)
+{
+	struct pl pl, mode;
+
+	if (!fmtp)
+		return 0;
+
+	pl_set_str(&pl, fmtp);
+
+	if (fmt_param_get(&pl, "packetization-mode", &mode))
+		return pl_u32(&mode);
+
+	return 0;
+}
+
+
+int avcodec_h264_fmtp_enc(struct mbuf *mb, const struct sdp_format *fmt,
+			  bool offer, void *arg)
+{
+	struct vidcodec *vc = arg;
+	uint8_t profile_idc = 0x42; /* baseline profile */
+	uint8_t profile_iop = 0xe0;
+	uint8_t h264_level_idc = 0x1f;
+	(void)offer;
+
+	if (!mb || !fmt || !vc)
+		return 0;
+
+	conf_get_str(conf_cur(), "avcodec_profile_level_id",
+		     profile_level_id, sizeof(profile_level_id));
+
+	if (str_isset(profile_level_id)) {
+		struct pl prof;
+
+		pl_set_str(&prof, profile_level_id);
+		if (prof.l != 6) {
+			warning("avcodec: invalid profile_level_id"
+				" (%r) using default\n",
+				profile_level_id);
+			goto out;
+		}
+
+		prof.l = 2;
+		profile_idc    = pl_x32(&prof); prof.p += 2;
+		profile_iop    = pl_x32(&prof); prof.p += 2;
+		h264_level_idc = pl_x32(&prof);
+	}
+
+ out:
+	return mbuf_printf(mb, "a=fmtp:%s"
+			   " %s"
+			   ";profile-level-id=%02x%02x%02x"
+			   "\r\n",
+			   fmt->id, vc->variant,
+			   profile_idc, profile_iop, h264_level_idc);
+}
+
+
+bool avcodec_h264_fmtp_cmp(const char *lfmtp, const char *rfmtp, void *arg)
+{
+	const struct vidcodec *vc = arg;
+	(void)lfmtp;
+
+	if (!vc)
+		return false;
+
+	return h264_packetization_mode(vc->variant) ==
+		h264_packetization_mode(rfmtp);
+}
diff -ruN a/modules/menu/dynamic_menu.c b/modules/menu/dynamic_menu.c
--- a/modules/menu/dynamic_menu.c	2022-03-27 11:22:42.000000000 +0300
+++ b/modules/menu/dynamic_menu.c	2023-01-26 19:14:52.915866100 +0300
@@ -355,8 +355,8 @@
 	if (!pl_isset(&argdir[1]))
 		argdir[1] = argdir[0];
 
-	adir = sdp_dir_decode(&argdir[0]);
-	vdir = sdp_dir_decode(&argdir[1]);
+	adir = decode_sdp_enum(&argdir[0]);
+	vdir = decode_sdp_enum(&argdir[1]);
 	if (adir == SDP_INACTIVE && vdir == SDP_INACTIVE) {
 		(void) re_hprintf(pf, "%s", usage);
 		return EINVAL;
diff -ruN a/modules/menu/menu.c b/modules/menu/menu.c
--- a/modules/menu/menu.c	2022-03-27 11:22:42.000000000 +0300
+++ b/modules/menu/menu.c	2023-01-26 19:17:29.575866100 +0300
@@ -928,6 +928,20 @@
 	return 0;
 }
 
+enum sdp_dir decode_sdp_enum(const struct pl *pl)
+{
+    if (!pl_strcmp(pl, "inactive")) {
+        return SDP_INACTIVE;
+    }
+    else if (!pl_strcmp(pl, "sendonly")) {
+        return  SDP_SENDONLY;
+    }
+    else if (!pl_strcmp(pl, "recvonly")) {
+        return SDP_RECVONLY;
+    }
+
+    return SDP_SENDRECV;
+}
 
 static int module_init(void)
 {
diff -ruN a/modules/menu/static_menu.c b/modules/menu/static_menu.c
--- a/modules/menu/static_menu.c	2022-03-27 11:22:42.000000000 +0300
+++ b/modules/menu/static_menu.c	2023-01-26 19:15:56.745866100 +0300
@@ -136,8 +136,8 @@
 	if (!pl_isset(&argdir[1]))
 		argdir[1] = argdir[0];
 
-	adir = sdp_dir_decode(&argdir[0]);
-	vdir = sdp_dir_decode(&argdir[1]);
+	adir = decode_sdp_enum(&argdir[0]);
+	vdir = decode_sdp_enum(&argdir[1]);
 
 	if (adir == SDP_INACTIVE && vdir == SDP_INACTIVE) {
 		(void) re_hprintf(pf, "%s", usage);
@@ -541,8 +541,8 @@
 	if (!pl_isset(&argdir[1]))
 		argdir[1] = argdir[0];
 
-	adir = sdp_dir_decode(&argdir[0]);
-	vdir = sdp_dir_decode(&argdir[1]);
+	adir = decode_sdp_enum(&argdir[0]);
+	vdir = decode_sdp_enum(&argdir[1]);
 
 	if (adir == SDP_INACTIVE && vdir == SDP_INACTIVE) {
 		(void)re_hprintf(pf, "%s", usage);
diff -ruN a/src/audio.c b/src/audio.c
--- a/src/audio.c	2022-03-27 11:22:42.000000000 +0300
+++ b/src/audio.c	2023-01-26 16:16:07.045866100 +0300
@@ -1,3 +1,4 @@
+#define _POSIX_C_SOURCE 200809L
 /**
  * @file src/audio.c  Audio stream
  *
diff -ruN a/src/main.c b/src/main.c
--- a/src/main.c	2022-03-27 11:22:42.000000000 +0300
+++ b/src/main.c	2023-01-26 18:49:09.115866100 +0300
@@ -13,6 +13,7 @@
 #include <re.h>
 #include <baresip.h>
 
+int verbose=0;
 
 static void signal_handler(int sig)
 {
diff -ruN a/src/sdp.c b/src/sdp.c
--- a/src/sdp.c	2022-03-27 11:22:42.000000000 +0300
+++ b/src/sdp.c	2023-01-28 18:44:16.019698100 +0300
@@ -63,8 +63,18 @@
 	bool has;
 
 	has = sdp_media_rformat(m, NULL) != NULL;
+
+    if( !has )
+        info("has_media: no codecs\n");
+
 	if (has)
-		return sdp_media_rport(m) != 0;
+    {
+		has = sdp_media_rport(m);
+        if( !has )
+            info("has_media: no rport\n");
+        return has != 0 ;
+    }
+
 
 	return false;
 }
diff -ruN a/src/stream.c b/src/stream.c
--- a/src/stream.c	2022-03-27 11:22:42.000000000 +0300
+++ b/src/stream.c	2023-01-28 18:25:24.999698100 +0300
@@ -1029,6 +1029,7 @@
 	s->tx.pt_enc = fmt ? fmt->pt : -1;
 
 	if (sdp_media_has_media(s->sdp)) {
+        info("stream: has media\n");
 
 		if (bundle_state(s->bundle) == BUNDLE_MUX) {
 
@@ -1043,6 +1044,10 @@
 			bundle_handle_extmap(s->bundle, s->sdp);
 		}
 	}
+    else
+    {
+        info("stream: has no media\n");
+    }
 
 	if (s->mencs && mnat_ready(s)) {
 
diff -ruN a/src/video.c b/src/video.c
--- a/src/video.c	2022-03-27 11:22:42.000000000 +0300
+++ b/src/video.c	2023-01-28 20:42:26.409698100 +0300
@@ -1169,12 +1169,18 @@
 
 	if (sc) {
 		if (dir & SDP_SENDONLY)
+        {
 			err = video_encoder_set(v, sc->data, sc->pt,
 				sc->params);
+        	debug("video: sendonly\n");
+        }
 
 		if (dir & SDP_RECVONLY)
+        {
 			err |= video_decoder_set(v, sc->data, sc->pt,
 				sc->rparams);
+           	debug("video: recvonly\n");
+        }
 
 		/* Stop / Start source & display*/
 		if (dir & SDP_SENDONLY)
@@ -1220,10 +1226,16 @@
 	int err;
 
 	if (!v)
+    {
+        printf("video_start_source EINVAL");
 		return EINVAL;
+    }
 
 	if (v->vtx.vsrc)
+    {
+        printf("vsrc is set, return\n");
 		return 0;
+    }
 
 	debug("video: start source\n");