static bool recv_handler(struct sa *src, struct mbuf *mb, void *arg) { struct menc_st *st = arg; err_status_t e; int len; (void)src; if (!st->use_srtp || !is_rtp_or_rtcp(mb)) return false; len = (int)mbuf_get_left(mb); if (is_rtcp_packet(mb)) { e = srtp_unprotect_rtcp(st->srtp_rx, mbuf_buf(mb), &len); } else { e = srtp_unprotect(st->srtp_rx, mbuf_buf(mb), &len); } if (e != err_status_ok) { DEBUG_WARNING("recv: failed to unprotect %s-packet" " with %d bytes (%H)\n", is_rtcp_packet(mb) ? "RTCP" : "RTP", len, errstatus_print, e); return true; /* error - drop packet */ } mbuf_set_end(mb, mb->pos + len); return false; /* continue processing */ }
static bool raw_handler(int proto, const struct sa *src, const struct sa *dst, struct mbuf *mb) { struct allocation *al; uint16_t numb, len; struct perm *perm; struct chan *chan; int err; al = allocation_find(proto, src, dst); if (!al) return false; if (mbuf_get_left(mb) < 4) return false; numb = ntohs(mbuf_read_u16(mb)); len = ntohs(mbuf_read_u16(mb)); if (mbuf_get_left(mb) < len) return false; // strip any optional padding if (len != mbuf_get_left(mb)) mbuf_set_end(mb, mb->pos + len); chan = chan_numb_find(al->chans, numb); if (!chan) return false; perm = perm_find(al->perms, chan_peer(chan)); if (!perm) { ++al->dropc_tx; return false; } err = udp_send(al->rel_us, chan_peer(chan), mb); if (err) turnd.errc_tx++; else { const size_t bytes = mbuf_get_left(mb); perm_tx_stat(perm, bytes); turnd.bytec_tx += bytes; } return true; }
static bool send_handler(int *err, struct sa *dst, struct mbuf *mb, void *arg) { struct menc_st *st = arg; err_status_t e; int len; (void)dst; if (!st->use_srtp || !is_rtp_or_rtcp(mb)) return false; len = (int)mbuf_get_left(mb); if (mbuf_get_space(mb) < ((size_t)len + SRTP_MAX_TRAILER_LEN)) { mbuf_resize(mb, mb->pos + len + SRTP_MAX_TRAILER_LEN); } if (is_rtcp_packet(mb)) { e = srtp_protect_rtcp(st->srtp_tx, mbuf_buf(mb), &len); } else { e = srtp_protect(st->srtp_tx, mbuf_buf(mb), &len); } if (err_status_ok != e) { DEBUG_WARNING("send: failed to protect %s-packet" " with %d bytes (%H)\n", is_rtcp_packet(mb) ? "RTCP" : "RTP", len, errstatus_print, e); *err = EPROTO; return false; } mbuf_set_end(mb, mb->pos + len); return false; /* continue processing */ }
int encode(struct videnc_state *st, bool update, const struct vidframe *frame) { int i, err, ret; int pix_fmt; if (!st || !frame) return EINVAL; switch (frame->fmt) { case VID_FMT_YUV420P: pix_fmt = AV_PIX_FMT_YUV420P; break; case VID_FMT_NV12: pix_fmt = AV_PIX_FMT_NV12; break; default: warning("avcodec: pixel format not supported (%s)\n", vidfmt_name(frame->fmt)); return ENOTSUP; } if (!st->ctx || !vidsz_cmp(&st->encsize, &frame->size)) { err = open_encoder(st, &st->encprm, &frame->size, pix_fmt); if (err) { warning("avcodec: open_encoder: %m\n", err); return err; } } for (i=0; i<4; i++) { st->pict->data[i] = frame->data[i]; st->pict->linesize[i] = frame->linesize[i]; } st->pict->pts = st->pts++; if (update) { debug("avcodec: encoder picture update\n"); st->pict->key_frame = 1; #ifdef FF_I_TYPE st->pict->pict_type = FF_I_TYPE; /* Infra Frame */ #else st->pict->pict_type = AV_PICTURE_TYPE_I; #endif } else { st->pict->key_frame = 0; st->pict->pict_type = 0; } mbuf_rewind(st->mb); #if LIBAVCODEC_VERSION_INT >= ((54<<16)+(1<<8)+0) do { AVPacket avpkt; int got_packet; av_init_packet(&avpkt); avpkt.data = st->mb->buf; avpkt.size = (int)st->mb->size; ret = avcodec_encode_video2(st->ctx, &avpkt, st->pict, &got_packet); if (ret < 0) return EBADMSG; if (!got_packet) return 0; mbuf_set_end(st->mb, avpkt.size); } while (0); #else ret = avcodec_encode_video(st->ctx, st->mb->buf, (int)st->mb->size, st->pict); if (ret < 0 ) return EBADMSG; /* todo: figure out proper buffer size */ if (ret > (int)st->sz_max) { debug("avcodec: grow encode buffer %u --> %d\n", st->sz_max, ret); st->sz_max = ret; } mbuf_set_end(st->mb, ret); #endif switch (st->codec_id) { case AV_CODEC_ID_H263: err = h263_packetize(st, st->mb, st->pkth, st->arg); break; case AV_CODEC_ID_H264: err = h264_packetize(st->mb->buf, st->mb->end, st->encprm.pktsize, st->pkth, st->arg); break; case AV_CODEC_ID_MPEG4: err = general_packetize(st->mb, st->encprm.pktsize, st->pkth, st->arg); break; default: err = EPROTO; break; } return err; }
static int enc(struct vidcodec_st *st, bool update, const struct vidframe *frame) { int i, err, ret; if (!st->enc.ctx || !vidsz_cmp(&st->encsize, &frame->size)) { err = open_encoder(st, &st->encprm, &frame->size); if (err) { DEBUG_WARNING("open_encoder: %m\n", err); return err; } } for (i=0; i<4; i++) { st->enc.pict->data[i] = frame->data[i]; st->enc.pict->linesize[i] = frame->linesize[i]; } st->enc.pict->pts = st->pts++; if (update) { re_printf("avcodec encoder picture update\n"); st->enc.pict->key_frame = 1; #ifdef FF_I_TYPE st->enc.pict->pict_type = FF_I_TYPE; /* Infra Frame */ #else st->enc.pict->pict_type = AV_PICTURE_TYPE_I; #endif } else { st->enc.pict->key_frame = 0; st->enc.pict->pict_type = 0; } mbuf_rewind(st->enc.mb); #if LIBAVCODEC_VERSION_INT >= ((54<<16)+(1<<8)+0) do { AVPacket avpkt; int got_packet; avpkt.data = st->enc.mb->buf; avpkt.size = (int)st->enc.mb->size; ret = avcodec_encode_video2(st->enc.ctx, &avpkt, st->enc.pict, &got_packet); if (ret < 0) return EBADMSG; if (!got_packet) return 0; mbuf_set_end(st->enc.mb, avpkt.size); } while (0); #else ret = avcodec_encode_video(st->enc.ctx, st->enc.mb->buf, (int)st->enc.mb->size, st->enc.pict); if (ret < 0 ) return EBADMSG; /* todo: figure out proper buffer size */ if (ret > (int)st->enc.sz_max) { re_printf("note: grow encode buffer %u --> %d\n", st->enc.sz_max, ret); st->enc.sz_max = ret; } mbuf_set_end(st->enc.mb, ret); #endif switch (st->codec_id) { case CODEC_ID_H263: err = h263_packetize(st, st->enc.mb); break; case CODEC_ID_H264: err = h264_packetize(st, st->enc.mb); break; case CODEC_ID_MPEG4: err = general_packetize(st, st->enc.mb); break; default: err = EPROTO; break; } return err; }
static bool recv_handler(int *err, struct mbuf *mb, bool *estab, void *arg) { struct tls_conn *tc = arg; int r; /* feed SSL data to the BIO */ r = BIO_write(tc->sbio_in, mbuf_buf(mb), (int)mbuf_get_left(mb)); if (r <= 0) { DEBUG_WARNING("recv: BIO_write %d\n", r); *err = ENOMEM; return true; } if (SSL_state(tc->ssl) != SSL_ST_OK) { if (tc->up) { *err = EPROTO; return true; } if (tc->active) { *err = tls_connect(tc); } else { *err = tls_accept(tc); } DEBUG_INFO("state=0x%04x\n", SSL_state(tc->ssl)); /* TLS connection is established */ if (SSL_state(tc->ssl) != SSL_ST_OK) return true; *estab = true; tc->up = true; } mbuf_set_pos(mb, 0); for (;;) { int n; if (mbuf_get_space(mb) < 4096) { *err = mbuf_resize(mb, mb->size + 8192); if (*err) return true; } n = SSL_read(tc->ssl, mbuf_buf(mb), (int)mbuf_get_space(mb)); if (n < 0) { const int ssl_err = SSL_get_error(tc->ssl, n); switch (ssl_err) { case SSL_ERROR_WANT_READ: break; default: *err = EPROTO; return true; } break; } else if (n == 0) break; mb->pos += n; } mbuf_set_end(mb, mb->pos); mbuf_set_pos(mb, 0); return false; }
static bool recv_handler(struct sa *src, struct mbuf *mb, void *arg) { struct tls_sock *ts = arg; struct tls_conn *tc; int r; tc = tls_udp_conn(ts, src); if (!tc) { /* No connection found, assuming Server role */ tc = conn_alloc(ts, src); if (!tc) return true; SSL_set_verify(tc->ssl, 0, 0); SSL_set_accept_state(tc->ssl); } /* feed SSL data to the BIO */ r = BIO_write(tc->sbio_in, mbuf_buf(mb), (int)mbuf_get_left(mb)); if (r <= 0) return true; check_timer(tc); mbuf_set_pos(mb, 0); for (;;) { int n; if (mbuf_get_space(mb) < 4096) { if (mbuf_resize(mb, mb->size + 8192)) return true; } n = SSL_read(tc->ssl, mbuf_buf(mb), (int)mbuf_get_space(mb)); if (n < 0) { const int ssl_err = SSL_get_error(tc->ssl, n); switch (ssl_err) { case SSL_ERROR_WANT_READ: break; default: return true; } break; } else if (n == 0) break; mb->pos += n; } if (!mb->pos) return true; mbuf_set_end(mb, mb->pos); mbuf_set_pos(mb, 0); return false; }