Commit 82376ef6 authored by Simon Morlat's avatar Simon Morlat

RingStream: add capability to play mkv files

parent c04a7920
...@@ -57,6 +57,8 @@ struct _RingStream ...@@ -57,6 +57,8 @@ struct _RingStream
MSFilter *gendtmf; MSFilter *gendtmf;
MSFilter *write_resampler; MSFilter *write_resampler;
MSFilter *sndwrite; MSFilter *sndwrite;
MSFilter *decoder;
int srcpin;
}; };
typedef struct _RingStream RingStream; typedef struct _RingStream RingStream;
......
...@@ -436,6 +436,13 @@ static int player_get_nch(MSFilter *f, void *arg){ ...@@ -436,6 +436,13 @@ static int player_get_nch(MSFilter *f, void *arg){
return 0; return 0;
} }
static int player_get_fmtp(MSFilter *f, void *arg){
PlayerData *d=(PlayerData*)f->data;
MSPinFormat *pinfmt = (MSPinFormat*)arg;
pinfmt->fmt = ms_factory_get_audio_format(f->factory, "pcm", d->rate, d->nchannels, NULL);
return 0;
}
static MSFilterMethod player_methods[]={ static MSFilterMethod player_methods[]={
{ MS_FILE_PLAYER_OPEN, player_open }, { MS_FILE_PLAYER_OPEN, player_open },
{ MS_FILE_PLAYER_START, player_start }, { MS_FILE_PLAYER_START, player_start },
...@@ -453,6 +460,7 @@ static MSFilterMethod player_methods[]={ ...@@ -453,6 +460,7 @@ static MSFilterMethod player_methods[]={
{ MS_PLAYER_CLOSE, player_close }, { MS_PLAYER_CLOSE, player_close },
{ MS_PLAYER_GET_STATE, player_get_state }, { MS_PLAYER_GET_STATE, player_get_state },
{ MS_PLAYER_SET_LOOP, player_loop }, { MS_PLAYER_SET_LOOP, player_loop },
{ MS_FILTER_GET_OUTPUT_FMT, player_get_fmtp },
{ 0, NULL } { 0, NULL }
}; };
......
...@@ -2441,6 +2441,7 @@ static int player_open_file(MSFilter *f, void *arg) { ...@@ -2441,6 +2441,7 @@ static int player_open_file(MSFilter *f, void *arg) {
obj->state = MSPlayerPaused; obj->state = MSPlayerPaused;
ms_filter_unlock(f); ms_filter_unlock(f);
ms_filter_notify_no_arg(f,MS_FILTER_OUTPUT_FMT_CHANGED);
return 0; return 0;
fail: fail:
......
...@@ -374,7 +374,7 @@ static bool_t ci_ends_with(const char *filename, const char*suffix){ ...@@ -374,7 +374,7 @@ static bool_t ci_ends_with(const char *filename, const char*suffix){
return strcasecmp(filename+filename_len-suffix_len,suffix)==0; return strcasecmp(filename+filename_len-suffix_len,suffix)==0;
} }
static MSFilter *create_av_player(const char *filename){ MSFilter *_ms_create_av_player(const char *filename){
if (ci_ends_with(filename,".mkv")) if (ci_ends_with(filename,".mkv"))
return ms_filter_new(MS_MKV_PLAYER_ID); return ms_filter_new(MS_MKV_PLAYER_ID);
else if (ci_ends_with(filename,".wav")) else if (ci_ends_with(filename,".wav"))
...@@ -492,7 +492,7 @@ static int open_av_player(AudioStream *stream, const char *filename){ ...@@ -492,7 +492,7 @@ static int open_av_player(AudioStream *stream, const char *filename){
MSPinFormat *videofmt=NULL; MSPinFormat *videofmt=NULL;
if (player->player) close_av_player(stream); if (player->player) close_av_player(stream);
player->player=create_av_player(filename); player->player=_ms_create_av_player(filename);
if (player->player==NULL){ if (player->player==NULL){
ms_warning("AudioStream[%p]: no way to open [%s].",stream,filename); ms_warning("AudioStream[%p]: no way to open [%s].",stream,filename);
return -1; return -1;
......
...@@ -115,6 +115,7 @@ void ms_srtp_context_delete(MSSrtpCtx *session); ...@@ -115,6 +115,7 @@ void ms_srtp_context_delete(MSSrtpCtx *session);
void register_video_preset_high_fps(MSVideoPresetsManager *manager); void register_video_preset_high_fps(MSVideoPresetsManager *manager);
MSFilter *_ms_create_av_player(const char *filename);
#ifdef __cplusplus #ifdef __cplusplus
} }
......
...@@ -22,21 +22,27 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. ...@@ -22,21 +22,27 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include "mediastreamer2/mediastream.h" #include "mediastreamer2/mediastream.h"
#include "mediastreamer2/dtmfgen.h" #include "mediastreamer2/dtmfgen.h"
#include "mediastreamer2/msfileplayer.h" #include "mediastreamer2/msfileplayer.h"
#include "private.h"
static void ring_player_event_handler(void *ud, MSFilter *f, unsigned int evid, void *arg){ static void ring_player_event_handler(void *ud, MSFilter *f, unsigned int evid, void *arg){
RingStream *stream=(RingStream*)ud; RingStream *stream=(RingStream*)ud;
int channels,rate;
if (evid==MS_FILTER_OUTPUT_FMT_CHANGED){ if (evid==MS_FILTER_OUTPUT_FMT_CHANGED){
ms_filter_call_method(stream->source,MS_FILTER_GET_NCHANNELS,&channels); MSPinFormat pinfmt={0};
ms_filter_call_method(stream->source,MS_FILTER_GET_SAMPLE_RATE,&rate); ms_filter_call_method(stream->source, MS_FILTER_GET_OUTPUT_FMT, &pinfmt);
if (pinfmt.fmt == NULL){
pinfmt.pin = 1;
ms_filter_call_method(stream->source, MS_FILTER_GET_OUTPUT_FMT, &pinfmt);
}
if (stream->write_resampler){ if (stream->write_resampler){
ms_message("Configuring resampler input with rate=[%i], nchannels=[%i]",rate,channels); ms_message("Configuring resampler input with rate=[%i], nchannels=[%i]",pinfmt.fmt->rate, pinfmt.fmt->nchannels);
ms_filter_call_method(stream->write_resampler,MS_FILTER_SET_NCHANNELS,&channels); ms_filter_call_method(stream->write_resampler,MS_FILTER_SET_NCHANNELS,(void*)&pinfmt.fmt->nchannels);
ms_filter_call_method(stream->write_resampler,MS_FILTER_SET_SAMPLE_RATE,&rate); ms_filter_call_method(stream->write_resampler,MS_FILTER_SET_SAMPLE_RATE,(void*)&pinfmt.fmt->rate);
} }
ms_filter_call_method(stream->gendtmf,MS_FILTER_SET_SAMPLE_RATE,&rate); ms_filter_call_method(stream->gendtmf,MS_FILTER_SET_SAMPLE_RATE, (void*)&pinfmt.fmt->rate);
ms_filter_call_method(stream->gendtmf,MS_FILTER_SET_NCHANNELS,&channels); ms_filter_call_method(stream->gendtmf,MS_FILTER_SET_NCHANNELS, (void*)&pinfmt.fmt->nchannels);
} }
} }
...@@ -51,9 +57,10 @@ RingStream * ring_start_with_cb(const char *file,int interval,MSSndCard *sndcard ...@@ -51,9 +57,10 @@ RingStream * ring_start_with_cb(const char *file,int interval,MSSndCard *sndcard
int srcrate,dstrate; int srcrate,dstrate;
MSConnectionHelper h; MSConnectionHelper h;
MSTickerParams params={0}; MSTickerParams params={0};
MSPinFormat pinfmt={0};
stream=(RingStream *)ms_new0(RingStream,1); stream=(RingStream *)ms_new0(RingStream,1);
stream->source=ms_filter_new(MS_FILE_PLAYER_ID); stream->source=_ms_create_av_player(file);
ms_filter_add_notify_callback(stream->source,ring_player_event_handler,stream,TRUE); ms_filter_add_notify_callback(stream->source,ring_player_event_handler,stream,TRUE);
if (func!=NULL) if (func!=NULL)
ms_filter_add_notify_callback(stream->source,func,user_data,FALSE); ms_filter_add_notify_callback(stream->source,func,user_data,FALSE);
...@@ -62,19 +69,39 @@ RingStream * ring_start_with_cb(const char *file,int interval,MSSndCard *sndcard ...@@ -62,19 +69,39 @@ RingStream * ring_start_with_cb(const char *file,int interval,MSSndCard *sndcard
stream->write_resampler=ms_filter_new(MS_RESAMPLE_ID); stream->write_resampler=ms_filter_new(MS_RESAMPLE_ID);
if (file){ if (file){
ms_filter_call_method(stream->source,MS_FILE_PLAYER_OPEN,(void*)file); ms_filter_call_method(stream->source,MS_PLAYER_OPEN,(void*)file);
ms_filter_call_method(stream->source,MS_FILE_PLAYER_LOOP,&interval); ms_filter_call_method(stream->source,MS_PLAYER_SET_LOOP,&interval);
ms_filter_call_method_noarg(stream->source,MS_FILE_PLAYER_START); ms_filter_call_method_noarg(stream->source,MS_PLAYER_START);
}
/*configure sound output filter*/
ms_filter_call_method(stream->source, MS_FILTER_GET_OUTPUT_FMT, &pinfmt);
if (pinfmt.fmt == NULL){
pinfmt.pin = 1;
ms_filter_call_method(stream->source, MS_FILTER_GET_OUTPUT_FMT, &pinfmt);
if (pinfmt.fmt == NULL){
/*probably no file is being played, assume pcm*/
pinfmt.fmt = ms_factory_get_audio_format(ms_factory_get_fallback(), "pcm", 8000, 1, NULL);
}
} }
srcrate = pinfmt.fmt->rate;
srcchannels = pinfmt.fmt->nchannels;
/*configure sound outputfilter*/
ms_filter_call_method(stream->source,MS_FILTER_GET_SAMPLE_RATE,&srcrate);
ms_filter_call_method(stream->source,MS_FILTER_GET_NCHANNELS,&srcchannels);
ms_filter_call_method(stream->sndwrite,MS_FILTER_SET_SAMPLE_RATE,&srcrate); ms_filter_call_method(stream->sndwrite,MS_FILTER_SET_SAMPLE_RATE,&srcrate);
ms_filter_call_method(stream->sndwrite,MS_FILTER_GET_SAMPLE_RATE,&dstrate); ms_filter_call_method(stream->sndwrite,MS_FILTER_GET_SAMPLE_RATE,&dstrate);
ms_filter_call_method(stream->sndwrite,MS_FILTER_SET_NCHANNELS,&srcchannels); ms_filter_call_method(stream->sndwrite,MS_FILTER_SET_NCHANNELS,&srcchannels);
ms_filter_call_method(stream->sndwrite,MS_FILTER_GET_NCHANNELS,&dstchannels); ms_filter_call_method(stream->sndwrite,MS_FILTER_GET_NCHANNELS,&dstchannels);
/*eventually create a decoder*/
if (strcasecmp(pinfmt.fmt->encoding, "pcm") != 0){
stream->decoder = ms_filter_create_decoder(pinfmt.fmt->encoding);
if (!stream->decoder){
ms_error("RingStream: could not create decoder for '%s'", pinfmt.fmt->encoding);
ring_stop(stream);
return NULL;
}
}
/*configure output of resampler*/ /*configure output of resampler*/
if (stream->write_resampler){ if (stream->write_resampler){
ms_filter_call_method(stream->write_resampler,MS_FILTER_SET_OUTPUT_SAMPLE_RATE,&dstrate); ms_filter_call_method(stream->write_resampler,MS_FILTER_SET_OUTPUT_SAMPLE_RATE,&dstrate);
...@@ -82,7 +109,6 @@ RingStream * ring_start_with_cb(const char *file,int interval,MSSndCard *sndcard ...@@ -82,7 +109,6 @@ RingStream * ring_start_with_cb(const char *file,int interval,MSSndCard *sndcard
/*the input of the resampler, as well as dtmf generator are configured within the ring_player_event_handler() /*the input of the resampler, as well as dtmf generator are configured within the ring_player_event_handler()
* callback triggered during the open of the file player*/ * callback triggered during the open of the file player*/
ms_message("configuring resampler output to rate=[%i], nchannels=[%i]",dstrate,dstchannels); ms_message("configuring resampler output to rate=[%i], nchannels=[%i]",dstrate,dstchannels);
} }
...@@ -91,11 +117,16 @@ RingStream * ring_start_with_cb(const char *file,int interval,MSSndCard *sndcard ...@@ -91,11 +117,16 @@ RingStream * ring_start_with_cb(const char *file,int interval,MSSndCard *sndcard
stream->ticker=ms_ticker_new_with_params(&params); stream->ticker=ms_ticker_new_with_params(&params);
ms_connection_helper_start(&h); ms_connection_helper_start(&h);
ms_connection_helper_link(&h,stream->source,-1,0); ms_connection_helper_link(&h,stream->source, -1, pinfmt.pin);
stream->srcpin = pinfmt.pin;
if (stream->decoder){
ms_filter_call_method(stream->decoder, MS_FILTER_SET_NCHANNELS, &srcchannels);
ms_connection_helper_link(&h, stream->decoder, 0, 0);
}
ms_connection_helper_link(&h,stream->gendtmf,0,0); ms_connection_helper_link(&h,stream->gendtmf,0,0);
if (stream->write_resampler) if (stream->write_resampler)
ms_connection_helper_link(&h,stream->write_resampler,0,0); ms_connection_helper_link(&h,stream->write_resampler,0,0);
ms_connection_helper_link(&h,stream->sndwrite,0,-1); ms_connection_helper_link(&h, stream->sndwrite, 0, -1);
ms_ticker_attach(stream->ticker,stream->source); ms_ticker_attach(stream->ticker,stream->source);
return stream; return stream;
...@@ -113,19 +144,25 @@ void ring_stop_dtmf(RingStream *stream){ ...@@ -113,19 +144,25 @@ void ring_stop_dtmf(RingStream *stream){
void ring_stop(RingStream *stream){ void ring_stop(RingStream *stream){
MSConnectionHelper h; MSConnectionHelper h;
if (stream->ticker){
ms_ticker_detach(stream->ticker,stream->source); ms_ticker_detach(stream->ticker,stream->source);
ms_connection_helper_start(&h); ms_connection_helper_start(&h);
ms_connection_helper_unlink(&h,stream->source,-1,0); ms_connection_helper_unlink(&h,stream->source,-1, stream->srcpin);
if (stream->decoder){
ms_connection_helper_unlink(&h,stream->decoder, 0, 0);
}
ms_connection_helper_unlink(&h,stream->gendtmf,0,0); ms_connection_helper_unlink(&h,stream->gendtmf,0,0);
if (stream->write_resampler) if (stream->write_resampler)
ms_connection_helper_unlink(&h,stream->write_resampler,0,0); ms_connection_helper_unlink(&h,stream->write_resampler,0,0);
ms_connection_helper_unlink(&h,stream->sndwrite,0,-1); ms_connection_helper_unlink(&h,stream->sndwrite,0,-1);
ms_ticker_destroy(stream->ticker); ms_ticker_destroy(stream->ticker);
ms_filter_destroy(stream->source); }
ms_filter_destroy(stream->gendtmf); if (stream->source) ms_filter_destroy(stream->source);
ms_filter_destroy(stream->sndwrite); if (stream->gendtmf) ms_filter_destroy(stream->gendtmf);
if (stream->sndwrite) ms_filter_destroy(stream->sndwrite);
if (stream->decoder) ms_filter_destroy(stream->decoder);
if (stream->write_resampler) if (stream->write_resampler)
ms_filter_destroy(stream->write_resampler); ms_filter_destroy(stream->write_resampler);
ms_free(stream); ms_free(stream);
......
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