/** * @brief Send RTP payload. * * @param av Handler. * @param type Type of payload. * @param payload The payload. * @param length Size of it. * @return int * @retval 0 Success. * @retval -1 Failure. */ static int toxav_send_rtp_payload(ToxAv *av, int32_t call_index, ToxAvCallType type, const uint8_t *payload, unsigned int length) { CallSpecific *call = &av->calls[call_index]; if (call->crtps[type - TypeAudio]) { if (type == TypeAudio) { return rtp_send_msg(call->crtps[type - TypeAudio], av->messenger, payload, length); } else { if (length == 0 || length > MAX_VIDEOFRAME_SIZE) { LOGGER_ERROR("Invalid video frame size: %u\n", length); return ErrorInternal; } /* number of pieces - 1*/ uint8_t numparts = (length - 1) / VIDEOFRAME_PIECE_SIZE; uint8_t load[2 + VIDEOFRAME_PIECE_SIZE]; load[0] = call->frame_outid++; load[1] = 0; int i; for (i = 0; i < numparts; i++) { memcpy(load + VIDEOFRAME_HEADER_SIZE, payload, VIDEOFRAME_PIECE_SIZE); payload += VIDEOFRAME_PIECE_SIZE; if (rtp_send_msg(call->crtps[type - TypeAudio], av->messenger, load, VIDEOFRAME_HEADER_SIZE + VIDEOFRAME_PIECE_SIZE) != 0) { return ErrorInternal; } load[1]++; } /* remainder = length % VIDEOFRAME_PIECE_SIZE, VIDEOFRAME_PIECE_SIZE if = 0 */ length = ((length - 1) % VIDEOFRAME_PIECE_SIZE) + 1; memcpy(load + VIDEOFRAME_HEADER_SIZE, payload, length); return rtp_send_msg(call->crtps[type - TypeAudio], av->messenger, load, VIDEOFRAME_HEADER_SIZE + length); } } else { return ErrorNoRtpSession; } }
/** * @brief Send RTP payload. * * @param av Handler. * @param type Type of payload. * @param payload The payload. * @param length Size of it. * @return int * @retval 0 Success. * @retval -1 Failure. */ inline__ int toxav_send_rtp_payload ( ToxAv *av, int32_t call_index, ToxAvCallType type, const uint8_t *payload, uint16_t length ) { if ( av->calls[call_index].crtps[type - TypeAudio] ) return rtp_send_msg ( av->calls[call_index].crtps[type - TypeAudio], av->msi_session->messenger_handle, payload, length ); else return -1; }
int main( int argc, char* argv[] ) { int status; tox_IP_Port Ip_port; const char* ip, *psend, *plisten; uint16_t port_send, port_listen; const uint8_t* test_bytes = "0123456789012345678901234567890123456789012345678901234567890123456789" "0123456789012345678901234567890123456789012345678901234567890123456789" "0123456789012345678901234567890123456789012345678901234567890123456789" "0123456789012345678901234567890123456789012345678901234567890123456789"; rtp_session_t* _m_session; rtp_msg_t *_m_msg_R, *_m_msg_S; arg_t* _list = parse_args ( argc, argv ); ip = find_arg_duble(_list, "-d"); psend = find_arg_duble(_list, "-p"); plisten = find_arg_duble(_list, "-l"); if ( !ip || !plisten || !psend ) return _print_help(argv[0]); port_send = atoi(psend); port_listen = atoi(plisten); IP_Port local, remote; /* * This is the Local ip. We initiate networking on * this value for it's the local one. To make stuff simpler we receive over this value * and send on the other one ( see remote ) */ local.ip.i = htonl(INADDR_ANY); local.port = port_listen; Networking_Core* _networking = new_networking(local.ip, port_listen); if ( !_networking ) return FAILURE; int _socket = _networking->sock; /* * Now this is the remote. It's used by rtp_session_t to determine the receivers ip etc. */ t_setipport ( ip, port_send, &remote ); _m_session = rtp_init_session(-1, -1); rtp_add_receiver( _m_session, &remote ); /* Now let's start our main loop in both recv and send mode */ for ( ;; ) { /* * This part checks for received messages and if gotten one * display 'Received msg!' indicator and free message */ _m_msg_R = rtp_recv_msg ( _m_session ); if ( _m_msg_R ) { puts ( "Received msg!" ); rtp_free_msg(_m_session, _m_msg_R); } /* -------------------- */ /* * This one makes a test msg and sends that message to the 'remote' */ _m_msg_S = rtp_msg_new ( _m_session, test_bytes, 280 ) ; rtp_send_msg ( _m_session, _m_msg_S, _socket ); usleep ( 10000 ); /* -------------------- */ } return SUCCESS; }
void *encode_video_thread(void *arg) { codec_state *cs = (codec_state *)arg; AVPacket pkt1, *packet = &pkt1; int p = 0; int err; int got_packet; rtp_msg_t *s_video_msg; int video_frame_finished; AVFrame *s_video_frame; AVFrame *webcam_frame; s_video_frame = avcodec_alloc_frame(); webcam_frame = avcodec_alloc_frame(); AVPacket enc_video_packet; uint8_t *buffer; int numBytes; /* Determine required buffer size and allocate buffer */ numBytes = avpicture_get_size(PIX_FMT_YUV420P, cs->webcam_decoder_ctx->width, cs->webcam_decoder_ctx->height); buffer = (uint8_t *)av_calloc(numBytes * sizeof(uint8_t),1); avpicture_fill((AVPicture *)s_video_frame, buffer, PIX_FMT_YUV420P, cs->webcam_decoder_ctx->width, cs->webcam_decoder_ctx->height); cs->sws_ctx = sws_getContext(cs->webcam_decoder_ctx->width, cs->webcam_decoder_ctx->height, cs->webcam_decoder_ctx->pix_fmt, cs->webcam_decoder_ctx->width, cs->webcam_decoder_ctx->height, PIX_FMT_YUV420P, SWS_BILINEAR, NULL, NULL, NULL); while (!cs->quit && cs->send_video) { if (av_read_frame(cs->video_format_ctx, packet) < 0) { printf("error reading frame\n"); if (cs->video_format_ctx->pb->error != 0) break; continue; } if (packet->stream_index == cs->video_stream) { if (avcodec_decode_video2(cs->webcam_decoder_ctx, webcam_frame, &video_frame_finished, packet) < 0) { printf("couldn't decode\n"); continue; } av_free_packet(packet); sws_scale(cs->sws_ctx, (uint8_t const * const *)webcam_frame->data, webcam_frame->linesize, 0, cs->webcam_decoder_ctx->height, s_video_frame->data, s_video_frame->linesize); /* create a new I-frame every 60 frames */ ++p; if (p == 60) { s_video_frame->pict_type = AV_PICTURE_TYPE_BI ; } else if (p == 61) { s_video_frame->pict_type = AV_PICTURE_TYPE_I ; p = 0; } else { s_video_frame->pict_type = AV_PICTURE_TYPE_P ; } if (video_frame_finished) { err = avcodec_encode_video2(cs->video_encoder_ctx, &enc_video_packet, s_video_frame, &got_packet); if (err < 0) { printf("could not encode video frame\n"); continue; } if (!got_packet) { continue; } pthread_mutex_lock(&cs->rtp_msg_mutex_lock); THREADLOCK() if (!enc_video_packet.data) fprintf(stderr, "video packet data is NULL\n"); s_video_msg = rtp_msg_new ( cs->_rtp_video, enc_video_packet.data, enc_video_packet.size ) ; if (!s_video_msg) { printf("invalid message\n"); } rtp_send_msg ( cs->_rtp_video, s_video_msg, cs->_networking ); THREADUNLOCK() pthread_mutex_unlock(&cs->rtp_msg_mutex_lock); av_free_packet(&enc_video_packet); } } else { av_free_packet(packet); } }