Commit 4787dd46 authored by Ghislain MARY's avatar Ghislain MARY

Handle SLI and RPSI.

parent 2be49acd
......@@ -593,6 +593,23 @@ MS2_PUBLIC void video_stream_send_fir(VideoStream *stream);
*/
MS2_PUBLIC void video_stream_send_pli(VideoStream *stream);
/**
* Ask the video stream to send a Slice Loss Indication.
* @param[in] stream The videostream object.
* @param[in] first The address of the first lost macroblock.
* @param[in] number The number of lost macroblocks.
* @param[in] picture_id The six least significant bits of the picture ID.
*/
MS2_PUBLIC void video_stream_send_sli(VideoStream *stream, uint16_t first, uint16_t number, uint8_t picture_id);
/**
* Ask the video stream to send a Reference Picture Selection Indication.
* @param[in] stream The videostream object.
* @param[in] bit_string A pointer to the variable length native RPSI bit string to include in the RTCP FB message.
* @param[in] bit_string_len The length of the bit_string in bits.
*/
MS2_PUBLIC void video_stream_send_rpsi(VideoStream *stream, uint8_t *bit_string, uint16_t bit_string_len);
/**
* Ask the video stream to generate a Video Fast Update (generally after receiving a Full-Intra Request.
* @param[in] stream The videostream object.
......
......@@ -20,6 +20,21 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#ifndef msinterfaces_h
#define msinterfaces_h
typedef struct _MSVideoCodecSLI MSVideoCodecSLI;
struct _MSVideoCodecSLI {
uint16_t first;
uint16_t number;
uint8_t picture_id;
};
typedef struct _MSVideoCodecRPSI MSVideoCodecRPSI;
struct _MSVideoCodecRPSI {
uint8_t *bit_string;
uint16_t bit_string_len;
};
/**
* Interface definition for video display filters.
**/
......@@ -184,6 +199,10 @@ typedef enum _MSRecorderState MSRecorderState;
MS_FILTER_EVENT_NO_ARG(MSFilterVideoDecoderInterface,1)
#define MS_VIDEO_DECODER_SEND_PLI \
MS_FILTER_EVENT_NO_ARG(MSFilterVideoDecoderInterface, 2)
#define MS_VIDEO_DECODER_SEND_SLI \
MS_FILTER_EVENT(MSFilterVideoDecoderInterface, 3, const MSVideoCodecSLI *)
#define MS_VIDEO_DECODER_SEND_RPSI \
MS_FILTER_EVENT(MSFilterVideoDecoderInterface, 4, const MSVideoCodecRPSI *)
#define MS_VIDEO_DECODER_RESET_FIRST_IMAGE_NOTIFICATION \
MS_FILTER_METHOD_NO_ARG(MSFilterVideoDecoderInterface, 0)
......@@ -200,7 +219,10 @@ typedef enum _MSRecorderState MSRecorderState;
#define MS_DECODER_HAVE_PLC MS_AUDIO_DECODER_HAVE_PLC /*for backward compatibility*/
/** Interface definitions for video encoders */
/**
* Interface definition for video encoders.
**/
#define MS_VIDEO_ENCODER_HAS_BUILTIN_CONVERTER \
MS_FILTER_METHOD(MSFilterVideoEncoderInterface, 0, bool_t)
/* request a video-fast-update (=I frame for H263,MP4V-ES) to a video encoder*/
......@@ -214,6 +236,10 @@ typedef enum _MSRecorderState MSRecorderState;
MS_FILTER_METHOD_NO_ARG(MSFilterVideoEncoderInterface, 4)
#define MS_VIDEO_ENCODER_NOTIFY_FIR \
MS_FILTER_METHOD(MSFilterVideoEncoderInterface, 5, uint8_t *)
#define MS_VIDEO_ENCODER_NOTIFY_SLI \
MS_FILTER_METHOD(MSFilterVideoEncoderInterface, 6, const MSVideoCodecSLI *)
#define MS_VIDEO_ENCODER_NOTIFY_RPSI \
MS_FILTER_METHOD(MSFilterVideoEncoderInterface, 7, const MSVideoCodecRPSI *)
/** Interface definitions for audio capture */
/* Start numbering from the end for hacks */
......
......@@ -72,17 +72,18 @@ static void event_cb(void *ud, MSFilter* f, unsigned int event, void *eventdata)
static void video_stream_process_rtcp(MediaStream *media_stream, mblk_t *m){
VideoStream *stream = (VideoStream *)media_stream;
unsigned int i;
do{
if (rtcp_is_SR(m)){
const report_block_t *rb;
rb=rtcp_SR_get_report_block(m,0);
if (rb){
unsigned int ij;
float rt=rtp_session_get_round_trip_propagation(stream->ms.sessions.rtp_session);
float flost;
ij=report_block_get_interarrival_jitter(rb);
i=report_block_get_interarrival_jitter(rb);
flost=(float)(100.0*report_block_get_fraction_lost(rb)/256.0);
ms_message("video_stream_process_rtcp[%p]: interarrival jitter=%u , lost packets percentage since last report=%f, round trip time=%f seconds",stream,ij,flost,rt);
ms_message("video_stream_process_rtcp[%p]: interarrival jitter=%u , lost packets percentage since last report=%f, round trip time=%f seconds",stream,i,flost,rt);
if (stream->ms.rc)
ms_bitrate_controller_process_rtcp(stream->ms.rc,m);
}
......@@ -91,12 +92,11 @@ static void video_stream_process_rtcp(MediaStream *media_stream, mblk_t *m){
/* Special case for FIR where the packet sender ssrc must be equal to 0. */
if ((rtcp_PSFB_get_media_source_ssrc(m) == rtp_session_get_recv_ssrc(stream->ms.sessions.rtp_session))
&& (rtcp_PSFB_get_packet_sender_ssrc(m) == 0)) {
unsigned int i;
for (i = 0; ; i++) {
rtcp_fb_fir_fci_t *fci = rtcp_PSFB_fir_get_fci(m, i);
if (fci == NULL) break;
if (rtcp_PSFB_fir_fci_get_ssrc(fci) == rtp_session_get_send_ssrc(stream->ms.sessions.rtp_session)) {
uint8_t seq_nr = rtcp_PSFB_fir_fci_get_seq_nr(fci);
if (rtcp_fb_fir_fci_get_ssrc(fci) == rtp_session_get_send_ssrc(stream->ms.sessions.rtp_session)) {
uint8_t seq_nr = rtcp_fb_fir_fci_get_seq_nr(fci);
ms_filter_call_method(stream->ms.encoder, MS_VIDEO_ENCODER_NOTIFY_FIR, &seq_nr);
break;
}
......@@ -109,6 +109,26 @@ static void video_stream_process_rtcp(MediaStream *media_stream, mblk_t *m){
case RTCP_PSFB_PLI:
ms_filter_call_method_noarg(stream->ms.encoder, MS_VIDEO_ENCODER_NOTIFY_PLI);
break;
case RTCP_PSFB_SLI:
for (i = 0; ; i++) {
rtcp_fb_sli_fci_t *fci = rtcp_PSFB_sli_get_fci(m, i);
MSVideoCodecSLI sli;
if (fci == NULL) break;
sli.first = rtcp_fb_sli_fci_get_first(fci);
sli.number = rtcp_fb_sli_fci_get_number(fci);
sli.picture_id = rtcp_fb_sli_fci_get_picture_id(fci);
ms_filter_call_method(stream->ms.encoder, MS_VIDEO_ENCODER_NOTIFY_SLI, &sli);
}
break;
case RTCP_PSFB_RPSI:
{
rtcp_fb_rpsi_fci_t *fci = rtcp_PSFB_rpsi_get_fci(m);
MSVideoCodecRPSI rpsi;
rpsi.bit_string = rtcp_fb_rpsi_fci_get_bit_string(fci);
rpsi.bit_string_len = rtcp_PSFB_rpsi_get_fci_bit_string_len(m);
ms_filter_call_method(stream->ms.encoder, MS_VIDEO_ENCODER_NOTIFY_RPSI, &rpsi);
}
break;
default:
break;
}
......@@ -639,6 +659,18 @@ void video_stream_send_pli(VideoStream *stream) {
}
}
void video_stream_send_sli(VideoStream *stream, uint16_t first, uint16_t number, uint8_t picture_id) {
if (stream->ms.sessions.rtp_session != NULL) {
rtp_session_send_rtcp_fb_sli(stream->ms.sessions.rtp_session, first, number, picture_id);
}
}
void video_stream_send_rpsi(VideoStream *stream, uint8_t *bit_string, uint16_t bit_string_len) {
if (stream->ms.sessions.rtp_session != NULL) {
rtp_session_send_rtcp_fb_rpsi(stream->ms.sessions.rtp_session, bit_string, bit_string_len);
}
}
void video_stream_send_vfu(VideoStream *stream){
if (stream->ms.encoder)
ms_filter_call_method_noarg(stream->ms.encoder, MS_VIDEO_ENCODER_REQ_VFU);
......
......@@ -533,18 +533,32 @@ static void video_stream_event_cb(void *user_pointer, const MSFilter *f, const u
MediastreamDatas *md = (MediastreamDatas *)user_pointer;
switch (event_id) {
case MS_VIDEO_DECODER_DECODING_ERRORS:
ms_warning("Video decoding error");
ms_warning("Decoding error on videostream [%p]", md->video);
video_stream_send_pli(md->video);
break;
case MS_VIDEO_DECODER_SEND_PLI:
ms_message("Send PLI");
ms_message("Send PLI on videostream [%p]", md->video);
video_stream_send_pli(md->video);
break;
case MS_VIDEO_DECODER_SEND_SLI:
{
const MSVideoCodecSLI *sli = (const MSVideoCodecSLI *)args;
ms_message("Send SLI on videostream [%p]", md->video);
video_stream_send_sli(md->video, sli->first, sli->number, sli->picture_id);
}
break;
case MS_VIDEO_DECODER_SEND_RPSI:
{
const MSVideoCodecRPSI *rpsi = (const MSVideoCodecRPSI *)args;
ms_message("Send RPSI on videostream [%p]", md->video);
video_stream_send_rpsi(md->video, rpsi->bit_string, rpsi->bit_string_len);
}
break;
case MS_VIDEO_DECODER_FIRST_IMAGE_DECODED:
ms_message("First video frame decoded successfully");
ms_message("First video frame decoded successfully on videostream [%p]", md->video);
break;
default:
ms_warning("Unhandled event %i", event_id);
ms_warning("Unhandled event %i for videostream [%p]", event_id, md->video);
break;
}
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment