Ejemplo n.º 1
0
/**
 * @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;
    }
}
Ejemplo n.º 2
0
/**
 * @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;
}
Ejemplo n.º 3
0
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;
}
Ejemplo n.º 4
0
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);
        }
    }