Commit b7313fc8 authored by Simon Morlat's avatar Simon Morlat

video recording ready for test

parent c580962d
......@@ -165,7 +165,8 @@ typedef enum _MSRecorderState MSRecorderState;
#define MS_RECORDER_GET_STATE \
MS_FILTER_METHOD(MSFilterRecorderInterface,5,MSRecorderState)
#define MS_RECORDER_NEEDS_FIR \
MS_FILTER_EVENT_NO_ARG(MSFilterRecorderInterface,0)
/** Interface definitions for echo cancellers */
......
......@@ -25,6 +25,7 @@ typedef struct SourceState{
int rate;
int nchannels;
MSQueue q;
const MSFmtDescriptor *fmt;
}SourceState;
static void itc_source_init(MSFilter *f){
......@@ -72,6 +73,12 @@ static int itc_source_get_rate(MSFilter *f, void *data){
return 0;
}
static int itc_source_set_fmt(MSFilter *f, void *data){
SourceState *s=(SourceState *)f->data;
s->fmt=((MSPinFormat*)data)->fmt;
return 0;
}
static void itc_source_process(MSFilter *f){
SourceState *s=(SourceState *)f->data;
mblk_t *m;
......@@ -84,9 +91,16 @@ static void itc_source_process(MSFilter *f){
ms_mutex_unlock(&s->mutex);
}
static int itc_source_get_out_fmt(MSFilter *f, void *data){
SourceState *s=(SourceState *)f->data;
((MSPinFormat*)data)->fmt=s->fmt;
return 0;
}
static MSFilterMethod source_methods[]={
{ MS_FILTER_GET_SAMPLE_RATE , itc_source_get_rate },
{ MS_FILTER_GET_NCHANNELS , itc_source_get_nchannels },
{ MS_FILTER_GET_OUTPUT_FMT, itc_source_get_out_fmt },
{ 0,NULL}
};
......@@ -181,12 +195,22 @@ static int itc_sink_get_sr(MSFilter *f , void *data){
return itc_source_get_rate (other,data);
}
static int itc_sink_set_fmt(MSFilter *f, void *data){
MSFilter *other=(MSFilter *)f->data;
if (other==NULL){
ms_error("MSItcSink not connected to any source !");
return -1;
}
return itc_source_set_fmt(other,data);
}
static MSFilterMethod sink_methods[]={
{ MS_ITC_SINK_CONNECT , itc_sink_connect },
{ MS_FILTER_SET_NCHANNELS , itc_sink_set_nchannels },
{ MS_FILTER_SET_SAMPLE_RATE , itc_sink_set_sr },
{ MS_FILTER_SET_NCHANNELS , itc_sink_set_nchannels },
{ MS_FILTER_SET_SAMPLE_RATE , itc_sink_set_sr },
{ MS_FILTER_GET_NCHANNELS, itc_sink_get_nchannels },
{ MS_FILTER_GET_SAMPLE_RATE, itc_sink_get_sr },
{ MS_FILTER_SET_INPUT_FMT, itc_sink_set_fmt },
{ 0, NULL }
};
......
......@@ -30,6 +30,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include "mediastreamer2/mstee.h"
#include "mediastreamer2/msaudiomixer.h"
#include "mediastreamer2/mscodecutils.h"
#include "mediastreamer2/msitc.h"
#include "private.h"
#ifdef HAVE_CONFIG_H
......@@ -293,6 +294,7 @@ static void setup_av_recorder(AudioStream *stream, int sample_rate, int nchannel
stream->av_recorder.recorder=ms_filter_new(MS_MKV_WRITER_ID);
if (stream->av_recorder.recorder){
MSPinFormat pinfmt={0};
stream->av_recorder.video_input=ms_filter_new(MS_ITC_SOURCE_ID);
stream->av_recorder.resampler=ms_filter_new(MS_RESAMPLE_ID);
stream->av_recorder.encoder=ms_filter_new(MS_OPUS_ENC_ID);
......@@ -304,6 +306,7 @@ static void setup_av_recorder(AudioStream *stream, int sample_rate, int nchannel
ms_filter_call_method(stream->av_recorder.resampler,MS_FILTER_SET_OUTPUT_SAMPLE_RATE,&g711_rate);
ms_filter_call_method(stream->av_recorder.resampler,MS_FILTER_SET_NCHANNELS,&nchannels);
ms_filter_call_method(stream->av_recorder.resampler,MS_FILTER_SET_OUTPUT_NCHANNELS,&g711_nchannels);
pinfmt.fmt=ms_factory_get_audio_format(ms_factory_get_fallback(),"pcmu",g711_rate,g711_nchannels,NULL);
}else{
int got_sr=0;
......@@ -314,7 +317,11 @@ static void setup_av_recorder(AudioStream *stream, int sample_rate, int nchannel
ms_filter_call_method(stream->av_recorder.resampler,MS_FILTER_SET_OUTPUT_SAMPLE_RATE,&got_sr);
ms_filter_call_method(stream->av_recorder.resampler,MS_FILTER_SET_NCHANNELS,&nchannels);
ms_filter_call_method(stream->av_recorder.resampler,MS_FILTER_SET_OUTPUT_NCHANNELS,&nchannels);
pinfmt.fmt=ms_factory_get_audio_format(ms_factory_get_fallback(),"opus",48000,nchannels,NULL);
}
pinfmt.pin=1;
ms_message("Configuring av recorder with audio format %s",ms_fmt_descriptor_to_string(pinfmt.fmt));
ms_filter_call_method(stream->av_recorder.recorder,MS_FILTER_SET_INPUT_FMT,&pinfmt);
}
}
......@@ -779,16 +786,34 @@ int audio_stream_mixed_record_open(AudioStream *st, const char* filename){
return 0;
}
static MSFilter *get_recorder(AudioStream *stream){
const char *fname=stream->recorder_file;
int len=strlen(fname);
if (strstr(fname,".mkv")==fname+len-4){
if (stream->av_recorder.recorder){
return stream->av_recorder.recorder;
}else{
ms_error("Cannot record in mkv format, not supported in this build.");
return NULL;
}
}
return stream->recorder;
}
int audio_stream_mixed_record_start(AudioStream *st){
if (st->recorder && st->recorder_file){
int pin=1;
MSRecorderState state;
ms_filter_call_method(st->recorder,MS_RECORDER_GET_STATE,&state);
MSFilter *recorder=get_recorder(st);
if (recorder==NULL) return -1;
ms_filter_call_method(recorder,MS_RECORDER_GET_STATE,&state);
if (state==MSRecorderClosed){
if (ms_filter_call_method(st->recorder,MS_RECORDER_OPEN,st->recorder_file)==-1)
if (ms_filter_call_method(recorder,MS_RECORDER_OPEN,st->recorder_file)==-1)
return -1;
}
ms_filter_call_method_noarg(st->recorder,MS_RECORDER_START);
ms_filter_call_method_noarg(recorder,MS_RECORDER_START);
ms_filter_call_method(st->recv_tee,MS_TEE_UNMUTE,&pin);
ms_filter_call_method(st->send_tee,MS_TEE_UNMUTE,&pin);
return 0;
......@@ -799,10 +824,13 @@ int audio_stream_mixed_record_start(AudioStream *st){
int audio_stream_mixed_record_stop(AudioStream *st){
if (st->recorder && st->recorder_file){
int pin=1;
ms_filter_call_method_noarg(st->recorder,MS_RECORDER_PAUSE);
MSFilter *recorder=get_recorder(st);
if (recorder==NULL) return -1;
ms_filter_call_method(st->recv_tee,MS_TEE_MUTE,&pin);
ms_filter_call_method(st->send_tee,MS_TEE_MUTE,&pin);
ms_filter_call_method_noarg(st->recorder,MS_RECORDER_CLOSE);
ms_filter_call_method_noarg(recorder,MS_RECORDER_PAUSE);
ms_filter_call_method_noarg(recorder,MS_RECORDER_CLOSE);
}
return 0;
}
......@@ -1065,11 +1093,29 @@ bool_t audio_stream_zrtp_enabled(const AudioStream *stream) {
return stream->ms.sessions.zrtp_context!=NULL;
}
static void configure_av_recorder(AudioStream *stream){
if (stream->av_recorder.video_input){
MSPinFormat pinfmt={0};
ms_filter_call_method(stream->av_recorder.video_input,MS_FILTER_GET_OUTPUT_FMT,&pinfmt);
if (pinfmt.fmt){
ms_message("Configuring av recorder with video format %s",ms_fmt_descriptor_to_string(pinfmt.fmt));
}
pinfmt.pin=0;
ms_filter_call_method(stream->av_recorder.recorder,MS_FILTER_SET_INPUT_FMT,&pinfmt);
}
}
void audio_stream_link_video(AudioStream *stream, VideoStream *video){
if (stream->av_recorder.video_input && video->itcsink){
ms_filter_call_method(video->itcsink,MS_ITC_SINK_CONNECT,stream->av_recorder.video_input);
configure_av_recorder(stream);
}
}
void audio_stream_unlink_video(AudioStream *stream, VideoStream *video){
if (stream->av_recorder.video_input && video->itcsink){
ms_filter_call_method(video->itcsink,MS_ITC_SINK_CONNECT,NULL);
}
}
......
......@@ -91,7 +91,7 @@ static void media_stream_change_decoder(MediaStream *stream, int payload) {
MSFilter *dec;
if (stream->type == MSVideo){
/* Q: why only video ? this optimization seems relevant for audio too.*/
/* Q: why only video ? A: because an audio format can be used at different rates: ex: speex/16000 speex/8000*/
if ((stream->decoder != NULL) && (stream->decoder->desc->enc_fmt != NULL)
&& (strcasecmp(pt->mime_type, stream->decoder->desc->enc_fmt) == 0)) {
/* Same formats behind different numbers, nothing to do. */
......
......@@ -28,6 +28,11 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include <ortp/zrtp.h>
static const MSFmtDescriptor *video_stream_get_recv_format(VideoStream *stream){
int i=rtp_session_get_recv_payload_type(stream->ms.sessions.rtp_session);
PayloadType *pt=rtp_profile_get_payload(rtp_session_get_profile(stream->ms.sessions.rtp_session),i);
return ms_factory_get_video_format(ms_factory_get_fallback(),pt->mime_type,NULL,pt->recv_fmtp);
}
void video_stream_free(VideoStream *stream) {
/* Prevent filters from being destroyed two times */
......@@ -56,10 +61,14 @@ void video_stream_free(VideoStream *stream) {
ms_filter_destroy(stream->jpegwriter);
if (stream->output2!=NULL)
ms_filter_destroy(stream->output2);
if (stream->tee3)
ms_filter_destroy(stream->tee3);
if (stream->itcsink)
ms_filter_destroy(stream->itcsink);
if (stream->display_name!=NULL)
ms_free(stream->display_name);
ms_free (stream);
ms_free(stream);
}
static void event_cb(void *ud, MSFilter* f, unsigned int event, void *eventdata){
......@@ -381,6 +390,24 @@ static void configure_video_source(VideoStream *stream){
}
}
static void configure_itc(VideoStream *stream){
if (stream->itcsink){
const MSFmtDescriptor *fmt=video_stream_get_recv_format(stream);
if (fmt){
MSPinFormat pinfmt={0};
pinfmt.pin=0;
pinfmt.fmt=fmt;
ms_filter_call_method(stream->itcsink,MS_FILTER_SET_OUTPUT_FMT,&pinfmt);
}
}
}
static void video_stream_payload_type_changed(RtpSession *session, unsigned long data){
VideoStream *stream = (VideoStream *)data;
mediastream_payload_type_changed(session,data);
configure_itc(stream);
}
int video_stream_start (VideoStream *stream, RtpProfile *profile, const char *rem_rtp_ip, int rem_rtp_port,
const char *rem_rtcp_ip, int rem_rtcp_port, int payload, int jitt_comp, MSWebCam *cam){
PayloadType *pt;
......@@ -419,7 +446,7 @@ int video_stream_start (VideoStream *stream, RtpProfile *profile, const char *re
rtp_session_set_jitter_compensation(rtps,jitt_comp);
rtp_session_signal_connect(stream->ms.sessions.rtp_session,"payload_type_changed",
(RtpCallback)mediastream_payload_type_changed,(unsigned long)&stream->ms);
(RtpCallback)video_stream_payload_type_changed,(unsigned long)&stream->ms);
rtp_session_get_jitter_buffer_params(stream->ms.sessions.rtp_session,&jbp);
jbp.max_packets=1000;//needed for high resolution video
......@@ -603,6 +630,7 @@ int video_stream_start (VideoStream *stream, RtpProfile *profile, const char *re
if (stream->itcsink){
ms_connection_helper_link(&ch,stream->tee3,0,0);
ms_filter_link(stream->tee3,1,stream->itcsink,0);
configure_itc(stream);
}
ms_connection_helper_link(&ch,stream->ms.decoder,0,0);
}
......@@ -806,7 +834,8 @@ video_stream_stop (VideoStream * stream)
}
}
}
video_stream_free (stream);
rtp_session_signal_disconnect_by_callback(stream->ms.sessions.rtp_session,"payload_type_changed",(RtpCallback)video_stream_payload_type_changed);
video_stream_free(stream);
}
......@@ -988,9 +1017,4 @@ void video_stream_decoding_error_reported(VideoStream *stream) {
stream->last_reported_decoding_error_time = stream->ms.sessions.ticker->time;
}
const MSFmtDescriptor *video_stream_get_recv_format(VideoStream *stream){
int i=rtp_session_get_recv_payload_type(stream->ms.sessions.rtp_session);
PayloadType *pt=rtp_profile_get_payload(rtp_session_get_profile(stream->ms.sessions.rtp_session),i);
return ms_factory_get_video_format(ms_factory_get_fallback(),pt->mime_type,NULL,NULL);
}
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