Commit d0f64082 authored by Guillaume Beraudo's avatar Guillaume Beraudo

Added picture fast update requesting on video decoder error.

Timeout 5000s before next request.
Do not use "\n" in xml file as it is not supported by eConf.
parent ceb98cab
......@@ -166,6 +166,9 @@ void audio_stream_get_local_rtp_stats(AudioStream *stream, rtp_stats_t *stats);
*****************/
typedef void (*VideoStreamRenderCallback)(void *user_pointer, const MSPicture *local_view, const MSPicture *remote_view);
typedef void (*VideoStreamEventCallback)(void *user_pointer, const MSFilter *f, const unsigned int event_id, const void *args);
typedef enum _VideoStreamDir{
VideoStreamSendRecv,
......@@ -194,6 +197,8 @@ struct _VideoStream
int corner; /*for selfview*/
VideoStreamRenderCallback rendercb;
void *render_pointer;
VideoStreamEventCallback eventcb;
void *event_pointer;
char *display_name;
unsigned long window_id;
unsigned long preview_window_id;
......@@ -211,6 +216,7 @@ VideoStream *video_stream_new(int locport, bool_t use_ipv6);
void video_stream_set_direction(VideoStream *vs, VideoStreamDir dir);
void video_stream_enable_adaptive_bitrate_control(VideoStream *s, bool_t yesno);
void video_stream_set_render_callback(VideoStream *s, VideoStreamRenderCallback cb, void *user_pointer);
void video_stream_set_event_callback(VideoStream *s, VideoStreamEventCallback cb, void *user_pointer);
void video_stream_set_display_filter_name(VideoStream *s, const char *fname);
int video_stream_start(VideoStream * stream, RtpProfile *profile, const char *remip, int remport, int rem_rtcp_port,
int payload, int jitt_comp, MSWebCam *device);
......
......@@ -58,7 +58,7 @@ typedef int (*MSFilterMethodFunc)(struct _MSFilter *f, void *arg);
* Structure for filter's methods used as a callback to notify events.
* @var MSFilterNotifyFunc
*/
typedef void (*MSFilterNotifyFunc)(void *userdata , unsigned int id, void *arg);
typedef void (*MSFilterNotifyFunc)(void *userdata, struct _MSFilter *f, unsigned int id, void *arg);
struct _MSFilterMethod{
int id;
......@@ -515,7 +515,8 @@ enum _MSFilterInterfaceId{
MSFilterPlayerInterface,
MSFilterRecorderInterface,
MSFilterVideoDisplayInterface,
MSFilterEchoCancellerInterface
MSFilterEchoCancellerInterface,
MSFilterVideoDecoderInterface
};
typedef enum _MSFilterInterfaceId MSFilterInterfaceId;
......
......@@ -87,7 +87,7 @@ typedef enum _MSPlayerState MSPlayerState;
MS_FILTER_METHOD(MSFilterPlayerInterface,5,int)
/** Interface definitions for echo cancellers*/
/** Interface definitions for echo cancellers */
/** sets the echo delay in milliseconds*/
#define MS_ECHO_CANCELLER_SET_DELAY \
......@@ -100,4 +100,9 @@ typedef enum _MSPlayerState MSPlayerState;
#define MS_ECHO_CANCELLER_SET_TAIL_LENGTH \
MS_FILTER_METHOD(MSFilterEchoCancellerInterface,2,int)
/** Interface definitions for video decoders */
#define MS_VIDEO_DECODER_DECODING_ERRORS \
MS_FILTER_EVENT_NO_ARG(MSFilterVideoDecoderInterface,0)
#endif
......@@ -75,7 +75,7 @@ static bool_t read_event(MSEventQueue *q){
evsize=argsize+16;
data=q->rptr+16;
if (f->notify!=NULL)
f->notify(f->notify_ud,id,argsize>0 ? data : NULL);
f->notify(f->notify_ud,f,id,argsize>0 ? data : NULL);
q->rptr+=evsize;
if (q->rptr>=q->endptr){
q->rptr=q->buffer;
......@@ -121,7 +121,7 @@ void ms_filter_notify(MSFilter *f, unsigned int id, void *arg){
if (f->notify!=NULL){
if (ms_global_event_queue==NULL){
/* synchronous notification */
f->notify(f->notify_ud,id,arg);
f->notify(f->notify_ud,f,id,arg);
}else{
write_event(ms_global_event_queue,f,id,arg);
}
......
......@@ -21,11 +21,16 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include "mediastreamer2/msfilter.h"
#include "mediastreamer2/rfc3984.h"
#include "mediastreamer2/msvideo.h"
#include "mediastreamer2/msticker.h"
#include "ffmpeg-priv.h"
#include "ortp/b64.h"
static uint64_t fpu_last_requested_time=0;
typedef struct _DecData{
mblk_t *yuv_msg;
mblk_t *sps,*pps;
......@@ -130,36 +135,39 @@ static void update_pps(DecData *d, mblk_t *pps){
else d->pps=NULL;
}
static bool_t check_sps_pps_change(DecData *d, mblk_t *sps, mblk_t *pps){
bool_t ret1=FALSE,ret2=FALSE;
static bool_t check_sps_change(DecData *d, mblk_t *sps){
bool_t ret=FALSE;
if (d->sps){
if (sps){
ret1=(msgdsize(sps)!=msgdsize(d->sps)) || (memcmp(d->sps->b_rptr,sps->b_rptr,msgdsize(sps))!=0);
if (ret1) {
update_sps(d,sps);
ms_message("SPS changed !");
update_pps(d,NULL);
}
ret=(msgdsize(sps)!=msgdsize(d->sps)) || (memcmp(d->sps->b_rptr,sps->b_rptr,msgdsize(sps))!=0);
if (ret) {
ms_message("SPS changed ! %i,%i",msgdsize(sps),msgdsize(d->sps));
update_sps(d,sps);
update_pps(d,NULL);
}
}else if (sps) {
} else {
ms_message("Receiving first SPS");
update_sps(d,sps);
}
return ret;
}
static bool_t check_pps_change(DecData *d, mblk_t *pps){
bool_t ret=FALSE;
if (d->pps){
if (pps){
ret2=(msgdsize(pps)!=msgdsize(d->pps)) || (memcmp(d->pps->b_rptr,pps->b_rptr,msgdsize(pps))!=0);
if (ret2) {
ms_message("PPS changed ! %i,%i",msgdsize(pps),msgdsize(d->pps));
update_pps(d,pps);
}
ret=(msgdsize(pps)!=msgdsize(d->pps)) || (memcmp(d->pps->b_rptr,pps->b_rptr,msgdsize(pps))!=0);
if (ret) {
ms_message("PPS changed ! %i,%i",msgdsize(pps),msgdsize(d->pps));
update_pps(d,pps);
}
}else if (pps) {
}else {
ms_message("Receiving first PPS");
update_pps(d,pps);
}
return ret1 || ret2;
return ret;
}
static void enlarge_bitstream(DecData *d, int new_size){
d->bitstream_size=new_size;
d->bitstream=ms_realloc(d->bitstream,d->bitstream_size);
......@@ -184,9 +192,9 @@ static int nalusToFrame(DecData *d, MSQueue *naluq, bool_t *new_sps_pps){
}
nalu_type=(*src) & ((1<<5)-1);
if (nalu_type==7)
*new_sps_pps=check_sps_pps_change(d,im,NULL) || *new_sps_pps;
*new_sps_pps=check_sps_change(d,im) || *new_sps_pps;
if (nalu_type==8)
*new_sps_pps=check_sps_pps_change(d,NULL,im) || *new_sps_pps;
*new_sps_pps=check_pps_change(d,im) || *new_sps_pps;
if (start_picture || nalu_type==7/*SPS*/ || nalu_type==8/*PPS*/ ){
*dst++=0;
start_picture=FALSE;
......@@ -251,6 +259,10 @@ static void dec_process(MSFilter *f){
len=avcodec_decode_video2(&d->av_context,&orig,&got_picture,&pkt);
if (len<=0) {
ms_warning("ms_AVdecoder_process: error %i.",len);
if ((f->ticker->time - fpu_last_requested_time)>5000 || fpu_last_requested_time==0) {
fpu_last_requested_time=f->ticker->time;
ms_filter_notify_no_arg(f,MS_VIDEO_DECODER_DECODING_ERRORS);
}
break;
}
if (got_picture) {
......
......@@ -25,11 +25,15 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include "mediastreamer2/msfilter.h"
#include "mediastreamer2/msvideo.h"
#include "mediastreamer2/msticker.h"
#include "rfc2429.h"
extern void ms_ffmpeg_check_init();
static uint64_t fpu_last_requested_time=0;
typedef struct DecState{
AVCodecContext av_context;
AVCodec *av_codec;
......@@ -65,6 +69,7 @@ static void dec_init(MSFilter *f, enum CodecID cid){
if (s->av_codec==NULL){
ms_error("Could not find decoder %i!",s->codec);
}
/*
s->av_context.width=MS_VIDEO_SIZE_QCIF_W;
s->av_context.height=MS_VIDEO_SIZE_QCIF_H;
......@@ -668,6 +673,10 @@ static void dec_process_frame(MSFilter *f, mblk_t *inm){
len=avcodec_decode_video2(&s->av_context,&orig,&got_picture,&pkt);
if (len<=0) {
ms_warning("ms_AVdecoder_process: error %i.",len);
if ((f->ticker->time - fpu_last_requested_time)>5000 || fpu_last_requested_time==0) {
fpu_last_requested_time=f->ticker->time;
ms_filter_notify_no_arg(f,MS_VIDEO_DECODER_DECODING_ERRORS);
}
break;
}
if (got_picture) {
......@@ -690,6 +699,7 @@ static void dec_process(MSFilter *f){
}
static MSFilterMethod methods[]={
{ MS_FILTER_ADD_FMTP , dec_add_fmtp },
{ 0 , NULL }
......
......@@ -73,6 +73,14 @@ void video_stream_free (VideoStream * stream)
ms_free (stream);
}
static void event_cb(void *ud, MSFilter* f, unsigned int event, void *eventdata){
ms_message("event_cb called %u", event);
VideoStream *st=(VideoStream*)ud;
if (st->eventcb!=NULL){
st->eventcb(st->event_pointer,f,event,eventdata);
}
}
/*this function must be called from the MSTicker thread:
it replaces one filter by another one.
This is a dirty hack that works anyway.
......@@ -96,7 +104,7 @@ void video_stream_change_decoder(VideoStream *stream, int payload){
ms_filter_link (stream->rtprecv, 0, stream->decoder, 0);
ms_filter_link (stream->decoder,0 , stream->output, 0);
ms_filter_preprocess(stream->decoder,stream->ticker);
ms_filter_set_notify_callback(dec, event_cb, stream);
}else{
ms_warning("No decoder found for %s",pt->mime_type);
}
......@@ -223,6 +231,11 @@ void video_stream_set_render_callback (VideoStream *s, VideoStreamRenderCallback
s->render_pointer=user_pointer;
}
void video_stream_set_event_callback (VideoStream *s, VideoStreamEventCallback cb, void *user_pointer){
s->eventcb=cb;
s->event_pointer=user_pointer;
}
void video_stream_set_display_filter_name(VideoStream *s, const char *fname){
if (s->display_name!=NULL){
ms_free(s->display_name);
......@@ -232,7 +245,8 @@ void video_stream_set_display_filter_name(VideoStream *s, const char *fname){
s->display_name=ms_strdup(fname);
}
static void ext_display_cb(void *ud, unsigned int event, void *eventdata){
static void ext_display_cb(void *ud, MSFilter* f, unsigned int event, void *eventdata){
MSExtDisplayOutput *output=(MSExtDisplayOutput*)eventdata;
VideoStream *st=(VideoStream*)ud;
if (st->rendercb!=NULL){
......@@ -373,6 +387,8 @@ int video_stream_start (VideoStream *stream, RtpProfile *profile, const char *re
ms_error("videostream.c: No decoder available for payload %i:%s.",payload,pt->mime_type);
return -1;
}
ms_filter_set_notify_callback(stream->decoder, event_cb, stream);
stream->rtprecv = ms_filter_new (MS_RTP_RECV_ID);
ms_filter_call_method(stream->rtprecv,MS_RTP_RECV_SET_SESSION,stream->session);
......@@ -383,7 +399,7 @@ int video_stream_start (VideoStream *stream, RtpProfile *profile, const char *re
if (stream->rendercb!=NULL){
stream->output=ms_filter_new(MS_EXT_DISPLAY_ID);
ms_filter_set_notify_callback (stream->output,ext_display_cb,stream);
ms_filter_set_notify_callback(stream->output,ext_display_cb,stream);
}else{
stream->output=ms_filter_new_from_name (stream->display_name);
}
......@@ -472,6 +488,8 @@ void video_stream_send_vfu(VideoStream *stream){
void
video_stream_stop (VideoStream * stream)
{
stream->eventcb = NULL;
stream->event_pointer = NULL;
if (stream->ticker){
if (stream->source)
ms_ticker_detach(stream->ticker,stream->source);
......
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