/** * @brief Signal to all peers that we're not sending video anymore. * @note The next frame sent cancels this. */ void CoreAV::sendNoVideo() { // We don't change the audio bitrate, but we signal that we're not sending video anymore qDebug() << "CoreAV: Signaling end of video sending"; for (ToxFriendCall& call : calls) { toxav_bit_rate_set(toxav, call.callId, -1, 0, nullptr); call.nullVideoBitrate = true; } }
void CoreAV::sendCallVideo(uint32_t callId, std::shared_ptr<VideoFrame> vframe) { // We might be running in the FFmpeg thread and holding the CameraSource lock // So be careful not to deadlock with anything while toxav locks in toxav_video_send_frame auto it = calls.find(callId); if (it == calls.end()) { return; } ToxFriendCall& call = it->second; if (!call.getVideoEnabled() || !call.isActive() || !(call.getState() & TOXAV_FRIEND_CALL_STATE_ACCEPTING_V)) { return; } if (call.getNullVideoBitrate()) { qDebug() << "Restarting video stream to friend" << callId; #if TOX_VERSION_IS_API_COMPATIBLE(0, 2, 0) toxav_video_set_bit_rate(toxav, callId, VIDEO_DEFAULT_BITRATE, nullptr); #else toxav_bit_rate_set(toxav, callId, -1, VIDEO_DEFAULT_BITRATE, nullptr); #endif call.setNullVideoBitrate(false); } ToxYUVFrame frame = vframe->toToxYUVFrame(); if (!frame) { return; } // TOXAV_ERR_SEND_FRAME_SYNC means toxav failed to lock, retry 5 times in this case // We don't want to be dropping iframes because of some lock held by toxav_iterate TOXAV_ERR_SEND_FRAME err; int retries = 0; do { if (!toxav_video_send_frame(toxav, callId, frame.width, frame.height, frame.y, frame.u, frame.v, &err)) { if (err == TOXAV_ERR_SEND_FRAME_SYNC) { ++retries; QThread::usleep(500); } else { qDebug() << "toxav_video_send_frame error: " << err; } } } while (err == TOXAV_ERR_SEND_FRAME_SYNC && retries < 5); if (err == TOXAV_ERR_SEND_FRAME_SYNC) { qDebug() << "toxav_video_send_frame error: Lock busy, dropping frame"; } }
/** * @brief Signal to all peers that we're not sending video anymore. * @note The next frame sent cancels this. */ void CoreAV::sendNoVideo() { // We don't change the audio bitrate, but we signal that we're not sending video anymore qDebug() << "CoreAV: Signaling end of video sending"; for (auto& kv : calls) { ToxFriendCall& call = kv.second; #if TOX_VERSION_IS_API_COMPATIBLE(0, 2, 0) toxav_video_set_bit_rate(toxav, kv.first, 0, nullptr); #else toxav_bit_rate_set(toxav, kv.first, -1, 0, nullptr); #endif call.setNullVideoBitrate(true); } }
void utox_av_local_call_control(ToxAV *av, uint32_t friend_number, TOXAV_CALL_CONTROL control) { TOXAV_ERR_CALL_CONTROL err = 0; toxav_call_control(av, friend_number, control, &err); if (err) { debug("uToxAV:\tLocal call control error!\n"); } else { TOXAV_ERR_BIT_RATE_SET bitrate_err = 0; switch (control) { case TOXAV_CALL_CONTROL_HIDE_VIDEO: { toxav_bit_rate_set(av, friend_number, -1, 0, &bitrate_err); toxvideo_postmessage(VIDEO_RECORD_STOP, friend_number, 0, NULL); friend[friend_number].call_state_self &= (0xFF ^ TOXAV_FRIEND_CALL_STATE_SENDING_V); break; } case TOXAV_CALL_CONTROL_SHOW_VIDEO: { toxav_bit_rate_set(av, friend_number, -1, UTOX_DEFAULT_BITRATE_V, &bitrate_err); toxvideo_postmessage(VIDEO_RECORD_START, friend_number, 0, NULL); friend[friend_number].call_state_self |= TOXAV_FRIEND_CALL_STATE_SENDING_V; break; } default: { debug("uToxAV:\tUnhandled local call control\n"); } // TODO // TOXAV_CALL_CONTROL_RESUME, // TOXAV_CALL_CONTROL_PAUSE, // TOXAV_CALL_CONTROL_CANCEL, // TOXAV_CALL_CONTROL_MUTE_AUDIO, // TOXAV_CALL_CONTROL_UNMUTE_AUDIO, } if (bitrate_err) { debug("uToxAV:\tError setting/changing video bitrate\n"); } } return; }
void CoreAV::sendCallVideo(uint32_t callId, std::shared_ptr<VideoFrame> vframe) { // We might be running in the FFmpeg thread and holding the CameraSource lock // So be careful not to deadlock with anything while toxav locks in toxav_video_send_frame if (!calls.contains(callId)) return; ToxFriendCall& call = calls[callId]; if (!call.videoEnabled || call.inactive || !(call.state & TOXAV_FRIEND_CALL_STATE_ACCEPTING_V)) return; if (call.nullVideoBitrate) { qDebug() << "Restarting video stream to friend"<<callId; toxav_bit_rate_set(toxav, call.callId, -1, VIDEO_DEFAULT_BITRATE, nullptr); call.nullVideoBitrate = false; } ToxYUVFrame frame = vframe->toToxYUVFrame(); if(!frame) { return; } // TOXAV_ERR_SEND_FRAME_SYNC means toxav failed to lock, retry 5 times in this case // We don't want to be dropping iframes because of some lock held by toxav_iterate TOXAV_ERR_SEND_FRAME err; int retries = 0; do { if (!toxav_video_send_frame(toxav, callId, frame.width, frame.height, frame.y, frame.u, frame.v, &err)) { if (err == TOXAV_ERR_SEND_FRAME_SYNC) { ++retries; QThread::usleep(500); } else { qDebug() << "toxav_video_send_frame error: "<<err; } } } while (err == TOXAV_ERR_SEND_FRAME_SYNC && retries < 5); if (err == TOXAV_ERR_SEND_FRAME_SYNC) qDebug() << "toxav_video_send_frame error: Lock busy, dropping frame"; }