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 +#include +#include +#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 ; e.g. h264_nvenc, h264_videotoolbox + avcodec_h264dec ; 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 + * and Divus GmbH + */ +#include +#include +#include +#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 + * and Divus GmbH + */ + +#include +#include +#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 #include +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");