video: reverse logic for decoding + rendering filters

Replaced the concept of 'rendering filter capable of decoding'
by 'decoding filter capable of rendering'.
It's similar but allows to choose the decoder first (based on
video type) and then let it do the rendering if it can.
parent 7e44142c
...@@ -89,7 +89,7 @@ enum _MSFilterInterfaceId{ ...@@ -89,7 +89,7 @@ enum _MSFilterInterfaceId{
/** /**
* Interface IDs, used to generate method names (see MS_FILTER_METHOD macro). * Interface IDs, used to generate method names (see MS_FILTER_METHOD macro).
* *
**/ **/
typedef enum _MSFilterInterfaceId MSFilterInterfaceId; typedef enum _MSFilterInterfaceId MSFilterInterfaceId;
...@@ -111,8 +111,8 @@ enum _MSFilterCategory{ ...@@ -111,8 +111,8 @@ enum _MSFilterCategory{
MS_FILTER_DECODER, MS_FILTER_DECODER,
/**used by capture filters that perform encoding*/ /**used by capture filters that perform encoding*/
MS_FILTER_ENCODING_CAPTURER, MS_FILTER_ENCODING_CAPTURER,
/**used by render filters that perform decoding*/ /**used by filters that perform decoding and rendering */
MS_FILTER_DECODING_RENDERER MS_FILTER_DECODER_RENDERER
}; };
/** /**
...@@ -589,7 +589,7 @@ the method index (_cnt_) and the argument size */ ...@@ -589,7 +589,7 @@ the method index (_cnt_) and the argument size */
( (((unsigned long)(_id_)) & 0xFFFF)<<16 | (_cnt_<<8) | (_argsize_ & 0xFF )) ( (((unsigned long)(_id_)) & 0xFFFF)<<16 | (_cnt_<<8) | (_argsize_ & 0xFF ))
/** /**
* Macro to create a method id, unique per filter. * Macro to create a method id, unique per filter.
* First argument shall be the filter's ID (MSFilterId) or interface ID (MSFilterInterfaceId). * First argument shall be the filter's ID (MSFilterId) or interface ID (MSFilterInterfaceId).
* Second argument is the method index within the context of the filter. It should start from 0 and increment for each new method. * Second argument is the method index within the context of the filter. It should start from 0 and increment for each new method.
* Third argument is the argument type of the method, for example "int", "float" or any structure. * Third argument is the argument type of the method, for example "int", "float" or any structure.
......
...@@ -87,9 +87,6 @@ struct _MSVideoDisplayDecodingSupport { ...@@ -87,9 +87,6 @@ struct _MSVideoDisplayDecodingSupport {
#define MS_VIDEO_DISPLAY_SET_DEVICE_ORIENTATION \ #define MS_VIDEO_DISPLAY_SET_DEVICE_ORIENTATION \
MS_FILTER_METHOD(MSFilterVideoDisplayInterface,11,int) MS_FILTER_METHOD(MSFilterVideoDisplayInterface,11,int)
#define MS_VIDEO_DISPLAY_SUPPORT_DECODING \
MS_FILTER_METHOD(MSFilterVideoDisplayInterface, 12, MSVideoDisplayDecodingSupport*)
/** /**
* Interface definitions for players * Interface definitions for players
**/ **/
...@@ -158,8 +155,8 @@ typedef enum _MSRecorderState MSRecorderState; ...@@ -158,8 +155,8 @@ typedef enum _MSRecorderState MSRecorderState;
#define MS_RECORDER_GET_STATE \ #define MS_RECORDER_GET_STATE \
MS_FILTER_METHOD(MSFilterRecorderInterface,5,MSRecorderState) MS_FILTER_METHOD(MSFilterRecorderInterface,5,MSRecorderState)
/** Interface definitions for echo cancellers */ /** Interface definitions for echo cancellers */
...@@ -204,9 +201,11 @@ typedef enum _MSRecorderState MSRecorderState; ...@@ -204,9 +201,11 @@ typedef enum _MSRecorderState MSRecorderState;
#define MS_VIDEO_DECODER_SEND_RPSI \ #define MS_VIDEO_DECODER_SEND_RPSI \
MS_FILTER_EVENT(MSFilterVideoDecoderInterface, 4, const MSVideoCodecRPSI *) MS_FILTER_EVENT(MSFilterVideoDecoderInterface, 4, const MSVideoCodecRPSI *)
#define MS_VIDEO_DECODER_RESET_FIRST_IMAGE_NOTIFICATION \ #define MS_VIDEO_DECODER_RESET_FIRST_IMAGE_NOTIFICATION \
MS_FILTER_METHOD_NO_ARG(MSFilterVideoDecoderInterface, 0) MS_FILTER_METHOD_NO_ARG(MSFilterVideoDecoderInterface, 5)
#define MS_VIDEO_DECODER_ENABLE_AVPF \ #define MS_VIDEO_DECODER_ENABLE_AVPF \
MS_FILTER_METHOD(MSFilterVideoDecoderInterface, 1, bool_t) MS_FILTER_METHOD(MSFilterVideoDecoderInterface, 6, bool_t)
#define MS_VIDEO_DECODER_SUPPORT_RENDERING \
MS_FILTER_METHOD(MSFilterVideoDecoderInterface, 7, MSVideoDisplayDecodingSupport*)
/** Interface definitions for video capture */ /** Interface definitions for video capture */
#define MS_VIDEO_CAPTURE_SET_DEVICE_ORIENTATION \ #define MS_VIDEO_CAPTURE_SET_DEVICE_ORIENTATION \
...@@ -218,7 +217,7 @@ typedef enum _MSRecorderState MSRecorderState; ...@@ -218,7 +217,7 @@ typedef enum _MSRecorderState MSRecorderState;
#define MS_AUDIO_DECODER_HAVE_PLC \ #define MS_AUDIO_DECODER_HAVE_PLC \
MS_FILTER_METHOD(MSFilterAudioDecoderInterface,0,int) MS_FILTER_METHOD(MSFilterAudioDecoderInterface,0,int)
#define MS_DECODER_HAVE_PLC MS_AUDIO_DECODER_HAVE_PLC /*for backward compatibility*/ #define MS_DECODER_HAVE_PLC MS_AUDIO_DECODER_HAVE_PLC /*for backward compatibility*/
/** /**
...@@ -253,7 +252,7 @@ typedef enum _MSRecorderState MSRecorderState; ...@@ -253,7 +252,7 @@ typedef enum _MSRecorderState MSRecorderState;
/** Interface definitions for audio encoder */ /** Interface definitions for audio encoder */
#define MS_AUDIO_ENCODER_SET_PTIME \ #define MS_AUDIO_ENCODER_SET_PTIME \
MS_FILTER_METHOD(MSFilterAudioEncoderInterface,0,int) MS_FILTER_METHOD(MSFilterAudioEncoderInterface,0,int)
#define MS_AUDIO_ENCODER_GET_PTIME \ #define MS_AUDIO_ENCODER_GET_PTIME \
MS_FILTER_METHOD(MSFilterAudioEncoderInterface,1,int) MS_FILTER_METHOD(MSFilterAudioEncoderInterface,1,int)
......
...@@ -21,7 +21,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. ...@@ -21,7 +21,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include "mediastreamer2/msticker.h" #include "mediastreamer2/msticker.h"
#define MS_FILTER_METHOD_GET_FID(id) (((id)>>16) & 0xFFFF) #define MS_FILTER_METHOD_GET_FID(id) (((id)>>16) & 0xFFFF)
#define MS_FILTER_METHOD_GET_INDEX(id) ( ((id)>>8) & 0XFF) #define MS_FILTER_METHOD_GET_INDEX(id) ( ((id)>>8) & 0XFF)
static MSList *desc_list=NULL; static MSList *desc_list=NULL;
static bool_t statistics_enabled=FALSE; static bool_t statistics_enabled=FALSE;
...@@ -104,7 +104,7 @@ MSFilterDesc * ms_filter_get_decoding_renderer(const char *mime) { ...@@ -104,7 +104,7 @@ MSFilterDesc * ms_filter_get_decoding_renderer(const char *mime) {
for (elem = desc_list; elem != NULL; elem = ms_list_next(elem)) { for (elem = desc_list; elem != NULL; elem = ms_list_next(elem)) {
MSFilterDesc *desc = (MSFilterDesc *)elem->data; MSFilterDesc *desc = (MSFilterDesc *)elem->data;
if (desc->category == MS_FILTER_DECODING_RENDERER) { if (desc->category == MS_FILTER_DECODER_RENDERER) {
char *saveptr=NULL; char *saveptr=NULL;
char *enc_fmt = ms_strdup(desc->enc_fmt); char *enc_fmt = ms_strdup(desc->enc_fmt);
char *token = strtok_r(enc_fmt, " ", &saveptr); char *token = strtok_r(enc_fmt, " ", &saveptr);
...@@ -126,7 +126,7 @@ MSFilterDesc * ms_filter_get_encoder(const char *mime){ ...@@ -126,7 +126,7 @@ MSFilterDesc * ms_filter_get_encoder(const char *mime){
MSList *elem; MSList *elem;
for (elem=desc_list;elem!=NULL;elem=ms_list_next(elem)){ for (elem=desc_list;elem!=NULL;elem=ms_list_next(elem)){
MSFilterDesc *desc=(MSFilterDesc*)elem->data; MSFilterDesc *desc=(MSFilterDesc*)elem->data;
if (desc->category==MS_FILTER_ENCODER && if (desc->category==MS_FILTER_ENCODER &&
strcasecmp(desc->enc_fmt,mime)==0){ strcasecmp(desc->enc_fmt,mime)==0){
return desc; return desc;
} }
...@@ -138,7 +138,7 @@ MSFilterDesc * ms_filter_get_decoder(const char *mime){ ...@@ -138,7 +138,7 @@ MSFilterDesc * ms_filter_get_decoder(const char *mime){
MSList *elem; MSList *elem;
for (elem=desc_list;elem!=NULL;elem=ms_list_next(elem)){ for (elem=desc_list;elem!=NULL;elem=ms_list_next(elem)){
MSFilterDesc *desc=(MSFilterDesc*)elem->data; MSFilterDesc *desc=(MSFilterDesc*)elem->data;
if (desc->category==MS_FILTER_DECODER && if (desc->category==MS_FILTER_DECODER &&
strcasecmp(desc->enc_fmt,mime)==0){ strcasecmp(desc->enc_fmt,mime)==0){
return desc; return desc;
} }
...@@ -464,7 +464,7 @@ const MSList * ms_filter_get_statistics(void){ ...@@ -464,7 +464,7 @@ const MSList * ms_filter_get_statistics(void){
void ms_filter_reset_statistics(void){ void ms_filter_reset_statistics(void){
MSList *elem; MSList *elem;
for(elem=stats_list;elem!=NULL;elem=elem->next){ for(elem=stats_list;elem!=NULL;elem=elem->next){
MSFilterStats *stats=(MSFilterStats *)elem->data; MSFilterStats *stats=(MSFilterStats *)elem->data;
stats->elapsed=0; stats->elapsed=0;
......
...@@ -466,13 +466,36 @@ int video_stream_start (VideoStream *stream, RtpProfile *profile, const char *re ...@@ -466,13 +466,36 @@ int video_stream_start (VideoStream *stream, RtpProfile *profile, const char *re
} }
if (stream->dir==VideoStreamSendRecv || stream->dir==VideoStreamRecvOnly){ if (stream->dir==VideoStreamSendRecv || stream->dir==VideoStreamRecvOnly){
MSConnectionHelper ch; MSConnectionHelper ch;
MSVideoDisplayDecodingSupport decoding_support;
/* create decoder first */
stream->ms.decoder=ms_filter_create_decoder(pt->mime_type);
if (stream->ms.decoder==NULL){
/* big problem: we don't have a registered decoderfor this payload...*/
ms_error("videostream.c: No decoder available for payload %i:%s.",payload,pt->mime_type);
return -1;
}
/* display logic */
if (stream->rendercb!=NULL){ if (stream->rendercb!=NULL){
/* rendering logic delegated to user supplied callback */
stream->output=ms_filter_new(MS_EXT_DISPLAY_ID); stream->output=ms_filter_new(MS_EXT_DISPLAY_ID);
ms_filter_add_notify_callback(stream->output,ext_display_cb,stream,TRUE); ms_filter_add_notify_callback(stream->output,ext_display_cb,stream,TRUE);
}else{ }else{
stream->output=ms_filter_new_from_name (stream->display_name); /* no user supplied callback -> create filter */
MSVideoDisplayDecodingSupport decoding_support;
/* Check if the decoding filter can perform the rendering */
decoding_support.mime_type = pt->mime_type;
decoding_support.supported = FALSE;
ms_filter_call_method(stream->ms.decoder, MS_VIDEO_DECODER_SUPPORT_RENDERING, &decoding_support);
stream->output_performs_decoding = decoding_support.supported;
if (stream->output_performs_decoding) {
stream->output = stream->ms.decoder;
} else {
/* Create default display filter */
stream->output = ms_filter_new_from_name (stream->display_name);
}
} }
/* Don't allow null output */ /* Don't allow null output */
...@@ -480,24 +503,6 @@ int video_stream_start (VideoStream *stream, RtpProfile *profile, const char *re ...@@ -480,24 +503,6 @@ int video_stream_start (VideoStream *stream, RtpProfile *profile, const char *re
ms_fatal("No video display filter could be instantiated. Please check build-time configuration"); ms_fatal("No video display filter could be instantiated. Please check build-time configuration");
} }
/* Check if the output filter can perform the decoding process */
decoding_support.mime_type = pt->mime_type;
decoding_support.supported = FALSE;
ms_filter_call_method(stream->output, MS_VIDEO_DISPLAY_SUPPORT_DECODING, &decoding_support);
stream->output_performs_decoding = decoding_support.supported;
/*plumb the incoming stream */
if (stream->output_performs_decoding == TRUE) {
stream->ms.decoder = stream->output; /* Consider the decoder is the output */
} else {
stream->ms.decoder=ms_filter_create_decoder(pt->mime_type);
if (stream->ms.decoder==NULL){
/* big problem: we don't have a registered decoderfor this payload...*/
ms_error("videostream.c: No decoder available for payload %i:%s.",payload,pt->mime_type);
ms_filter_destroy(stream->output);
return -1;
}
}
ms_filter_add_notify_callback(stream->ms.decoder, event_cb, stream,FALSE); ms_filter_add_notify_callback(stream->ms.decoder, event_cb, stream,FALSE);
stream->ms.rtprecv = ms_filter_new (MS_RTP_RECV_ID); stream->ms.rtprecv = ms_filter_new (MS_RTP_RECV_ID);
...@@ -563,7 +568,7 @@ int video_stream_start (VideoStream *stream, RtpProfile *profile, const char *re ...@@ -563,7 +568,7 @@ int video_stream_start (VideoStream *stream, RtpProfile *profile, const char *re
/* create the ticker */ /* create the ticker */
if (stream->ms.sessions.ticker==NULL) media_stream_start_ticker(&stream->ms); if (stream->ms.sessions.ticker==NULL) media_stream_start_ticker(&stream->ms);
stream->ms.start_time=ms_time(NULL); stream->ms.start_time=ms_time(NULL);
stream->ms.is_beginning=TRUE; stream->ms.is_beginning=TRUE;
...@@ -572,7 +577,7 @@ int video_stream_start (VideoStream *stream, RtpProfile *profile, const char *re ...@@ -572,7 +577,7 @@ int video_stream_start (VideoStream *stream, RtpProfile *profile, const char *re
ms_ticker_attach (stream->ms.sessions.ticker, stream->source); ms_ticker_attach (stream->ms.sessions.ticker, stream->source);
if (stream->ms.rtprecv) if (stream->ms.rtprecv)
ms_ticker_attach (stream->ms.sessions.ticker, stream->ms.rtprecv); ms_ticker_attach (stream->ms.sessions.ticker, stream->ms.rtprecv);
stream->ms.state=MSStreamStarted; stream->ms.state=MSStreamStarted;
return 0; return 0;
} }
...@@ -769,7 +774,7 @@ void video_stream_set_native_window_id(VideoStream *stream, unsigned long id){ ...@@ -769,7 +774,7 @@ void video_stream_set_native_window_id(VideoStream *stream, unsigned long id){
void video_stream_set_native_preview_window_id(VideoStream *stream, unsigned long id){ void video_stream_set_native_preview_window_id(VideoStream *stream, unsigned long id){
stream->preview_window_id=id; stream->preview_window_id=id;
#ifndef __ios #ifndef __ios
if (stream->output2){ if (stream->output2){
ms_filter_call_method(stream->output2,MS_VIDEO_DISPLAY_SET_NATIVE_WINDOW_ID,&id); ms_filter_call_method(stream->output2,MS_VIDEO_DISPLAY_SET_NATIVE_WINDOW_ID,&id);
} }
...@@ -786,7 +791,7 @@ unsigned long video_stream_get_native_preview_window_id(VideoStream *stream){ ...@@ -786,7 +791,7 @@ unsigned long video_stream_get_native_preview_window_id(VideoStream *stream){
return id; return id;
} }
if (stream->source){ if (stream->source){
if (ms_filter_has_method(stream->source,MS_VIDEO_DISPLAY_GET_NATIVE_WINDOW_ID) if (ms_filter_has_method(stream->source,MS_VIDEO_DISPLAY_GET_NATIVE_WINDOW_ID)
&& ms_filter_call_method(stream->source,MS_VIDEO_DISPLAY_GET_NATIVE_WINDOW_ID,&id)==0) && ms_filter_call_method(stream->source,MS_VIDEO_DISPLAY_GET_NATIVE_WINDOW_ID,&id)==0)
return id; return id;
} }
......
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