Commit 5d245fe6 authored by Simon Morlat's avatar Simon Morlat

mkv video-only player in progress

parent ece33d87
......@@ -765,7 +765,7 @@ struct _VideoStream
MSFilter *jpegwriter;
MSFilter *output2;
MSFilter *tee3;
MSFilter *itcsink;
MSFilter *recorder_output; /*can be an ItcSink to send video to the audiostream's multimedia recorder, or directly a MkvRecorder */
MSFilter *local_jpegwriter;
MSVideoSize sent_vsize;
MSVideoSize preview_vsize;
......
......@@ -527,6 +527,7 @@ static void _parse_audio_track_info(MKVAudioTrack *audio_info_out, ebml_element
}
static void _mkv_track_free(MKVTrack *obj) {
if (!obj) return;
if(obj->codec_private) ms_free(obj->codec_private);
ms_free(obj);
}
......
......@@ -1801,7 +1801,7 @@ static void recorder_process(MSFilter *f) {
module_preprocess(obj->modulesList[i], f->inputs[i], &frames);
while((buffer = ms_queue_get(&frames)) != NULL) {
mblk_set_timestamp_info(buffer, time_loop_canceler_apply(obj->timeLoopCancelers[i], mblk_get_timestamp_info(buffer)));
mblk_set_timestamp_info(buffer, time_loop_canceler_apply(obj->timeLoopCancelers[i], mblk_get_timestamp_info(buffer)));
changeClockRate(buffer, obj->inputDescsList[i]->rate, 1000);
ms_queue_put(&frames_ms, buffer);
}
......@@ -2238,6 +2238,7 @@ static int player_open_file(MSFilter *f, void *arg) {
ms_error("MKVPlayer: fail to open %s. A file is already opened", filename);
goto fail;
}
ms_message("MKVPlayer: opening %s", filename);
obj->reader = mkv_reader_open(filename);
if(obj->reader == NULL) {
ms_error("MKVPlayer: %s could not be opened in read-only mode", filename);
......
......@@ -1687,17 +1687,17 @@ static void configure_av_recorder(AudioStream *stream){
void audio_stream_link_video(AudioStream *stream, VideoStream *video){
stream->videostream=video;
if (stream->av_recorder.video_input && video->itcsink){
if (stream->av_recorder.video_input && video->recorder_output){
ms_message("audio_stream_link_video() connecting itc filters");
ms_filter_call_method(video->itcsink,MS_ITC_SINK_CONNECT,stream->av_recorder.video_input);
ms_filter_call_method(video->recorder_output,MS_ITC_SINK_CONNECT,stream->av_recorder.video_input);
configure_av_recorder(stream);
}
}
void audio_stream_unlink_video(AudioStream *stream, VideoStream *video){
stream->videostream=NULL;
if (stream->av_recorder.video_input && video->itcsink){
ms_filter_call_method(video->itcsink,MS_ITC_SINK_CONNECT,NULL);
if (stream->av_recorder.video_input && video->recorder_output){
ms_filter_call_method(video->recorder_output,MS_ITC_SINK_CONNECT,NULL);
}
}
......
......@@ -61,9 +61,10 @@ void rfc3984_set_max_payload_size(Rfc3984Context *ctx, int size){
ctx->maxsz=size;
}
static void send_packet(MSQueue *rtpq, uint32_t ts, mblk_t *m, bool_t marker){
static void send_packet(Rfc3984Context *ctx, MSQueue *rtpq, uint32_t ts, mblk_t *m, bool_t marker){
mblk_set_timestamp_info(m,ts);
mblk_set_marker_info(m,marker);
mblk_set_cseq(m, ctx->ref_cseq++);
ms_queue_put(rtpq,m);
}
......@@ -105,7 +106,7 @@ static mblk_t *prepend_fu_indicator_and_header(mblk_t *m, uint8_t indicator,
return h;
}
static void frag_nalu_and_send(MSQueue *rtpq, uint32_t ts, mblk_t *nalu, bool_t marker, int maxsize){
static void frag_nalu_and_send(Rfc3984Context *ctx, MSQueue *rtpq, uint32_t ts, mblk_t *nalu, bool_t marker, int maxsize){
mblk_t *m;
int payload_max_size=maxsize-2;/*minus FUA header*/
uint8_t fu_indicator;
......@@ -119,12 +120,12 @@ static void frag_nalu_and_send(MSQueue *rtpq, uint32_t ts, mblk_t *nalu, bool_t
nalu->b_rptr+=payload_max_size;
m->b_wptr=nalu->b_rptr;
m=prepend_fu_indicator_and_header(m,fu_indicator,start,FALSE,type);
send_packet(rtpq,ts,m,FALSE);
send_packet(ctx, rtpq,ts,m,FALSE);
start=FALSE;
}
/*send last packet */
m=prepend_fu_indicator_and_header(nalu,fu_indicator,FALSE,TRUE,type);
send_packet(rtpq,ts,m,marker);
send_packet(ctx, rtpq,ts,m,marker);
}
static void rfc3984_pack_mode_0(Rfc3984Context *ctx, MSQueue *naluq, MSQueue *rtpq, uint32_t ts){
......@@ -137,7 +138,7 @@ static void rfc3984_pack_mode_0(Rfc3984Context *ctx, MSQueue *naluq, MSQueue *rt
if (size>ctx->maxsz){
ms_warning("This H264 packet does not fit into mtu: size=%i",size);
}
send_packet(rtpq,ts,m,end);
send_packet(ctx, rtpq,ts,m,end);
}
}
......@@ -162,7 +163,7 @@ static void rfc3984_pack_mode_1(Rfc3984Context *ctx, MSQueue *naluq, MSQueue *rt
ms_debug("Sending STAP-A");
}else
ms_debug("Sending previous msg as single NAL");
send_packet(rtpq,ts,prevm,FALSE);
send_packet(ctx, rtpq,ts,prevm,FALSE);
prevm=NULL;
prevsz=0;
}
......@@ -177,25 +178,25 @@ static void rfc3984_pack_mode_1(Rfc3984Context *ctx, MSQueue *naluq, MSQueue *rt
/*send as single nal or FU-A*/
if (sz>ctx->maxsz){
ms_debug("Sending FU-A packets");
frag_nalu_and_send(rtpq,ts,m,end, ctx->maxsz);
frag_nalu_and_send(ctx, rtpq,ts,m,end, ctx->maxsz);
}else{
ms_debug("Sending Single NAL");
send_packet(rtpq,ts,m,end);
send_packet(ctx, rtpq,ts,m,end);
}
}
}else{
if (sz>ctx->maxsz){
ms_debug("Sending FU-A packets");
frag_nalu_and_send(rtpq,ts,m,end, ctx->maxsz);
frag_nalu_and_send(ctx, rtpq,ts,m,end, ctx->maxsz);
}else{
ms_debug("Sending Single NAL");
send_packet(rtpq,ts,m,end);
send_packet(ctx, rtpq,ts,m,end);
}
}
}
if (prevm){
ms_debug("Sending Single NAL (2)");
send_packet(rtpq,ts,prevm,TRUE);
send_packet(ctx, rtpq,ts,prevm,TRUE);
}
}
......
......@@ -32,7 +32,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include "private.h"
static void configure_itc(VideoStream *stream);
static void configure_recorder_output(VideoStream *stream);
static int video_stream_start_with_source_and_output(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, MSFilter *source, MSFilter *output);
......@@ -75,8 +75,8 @@ void video_stream_free(VideoStream *stream) {
ms_filter_destroy(stream->output2);
if (stream->tee3)
ms_filter_destroy(stream->tee3);
if (stream->itcsink)
ms_filter_destroy(stream->itcsink);
if (stream->recorder_output)
ms_filter_destroy(stream->recorder_output);
if (stream->local_jpegwriter)
ms_filter_destroy(stream->local_jpegwriter);
if (stream->rtp_io_session)
......@@ -117,7 +117,7 @@ static void internal_event_cb(void *ud, MSFilter *f, unsigned int event, void *e
video_stream_send_rpsi(stream, rpsi->bit_string, rpsi->bit_string_len);
break;
case MS_FILTER_OUTPUT_FMT_CHANGED:
if (stream->itcsink) configure_itc(stream);
if (stream->recorder_output) configure_recorder_output(stream);
break;
}
}
......@@ -300,8 +300,8 @@ VideoStream *video_stream_new_with_sessions(const MSMediaStreamSessions *session
* In practice, these filters are needed only for audio+video recording.
*/
if (ms_factory_lookup_filter_by_id(ms_factory_get_fallback(), MS_MKV_RECORDER_ID)){
stream->itcsink=ms_filter_new(MS_ITC_SINK_ID);
stream->tee3=ms_filter_new(MS_TEE_ID);
stream->recorder_output=ms_filter_new(MS_ITC_SINK_ID);
}
rtp_session_set_rtcp_xr_media_callbacks(stream->ms.sessions.rtp_session, &rtcp_xr_media_cbs);
......@@ -439,7 +439,7 @@ static void configure_video_source(VideoStream *stream){
int ret;
MSVideoSize preview_vsize;
MSPinFormat pf={0};
bool_t is_player=ms_filter_get_id(stream->source)==MS_ITC_SOURCE_ID;
bool_t is_player=ms_filter_get_id(stream->source)==MS_ITC_SOURCE_ID || ms_filter_get_id(stream->source)==MS_MKV_PLAYER_ID;
/* transmit orientation to source filter */
......@@ -566,8 +566,8 @@ static void configure_video_source(VideoStream *stream){
static void configure_itc(VideoStream *stream){
if (stream->itcsink){
static void configure_recorder_output(VideoStream *stream){
if (stream->recorder_output){
MSPinFormat pf={0};
ms_filter_call_method(stream->ms.decoder,MS_FILTER_GET_OUTPUT_FMT,&pf);
if (pf.fmt){
......@@ -581,7 +581,7 @@ static void configure_itc(VideoStream *stream){
tmp.rate=pt->clock_rate;
pinfmt.pin=0;
pinfmt.fmt=ms_factory_get_format(ms_factory_get_fallback(),&tmp);
ms_filter_call_method(stream->itcsink,MS_FILTER_SET_INPUT_FMT,&pinfmt);
ms_filter_call_method(stream->recorder_output,MS_FILTER_SET_INPUT_FMT,&pinfmt);
ms_message("configure_itc(): format set to %s",ms_fmt_descriptor_to_string(pinfmt.fmt));
}
}else ms_warning("configure_itc(): video decoder doesn't give output format.");
......@@ -642,15 +642,21 @@ static void video_stream_payload_type_changed(RtpSession *session, void *data){
ms_warning("No payload defined with number %i", payload);
}
configure_itc(stream);
configure_recorder_output(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){
MSMediaStreamIO io = MS_MEDIA_STREAM_IO_INITIALIZER;
if (cam==NULL){
cam = ms_web_cam_manager_get_default_cam( ms_web_cam_manager_get() );
}
return video_stream_start_with_source(stream, profile, rem_rtp_ip, rem_rtp_port, rem_rtcp_ip, rem_rtcp_port, payload, jitt_comp, cam, ms_web_cam_create_reader(cam));
io.input.type = MSResourceCamera;
io.input.camera = cam;
io.output.type = MSResourceDefault;
io.output.resource_arg = NULL;
rtp_session_set_jitter_compensation(stream->ms.sessions.rtp_session, jitt_comp);
return video_stream_start_from_io(stream, profile, rem_rtp_ip, rem_rtp_port, rem_rtcp_ip, rem_rtcp_port, payload, &io);
}
int video_stream_start_from_io(VideoStream *stream, RtpProfile *profile, const char *rem_rtp_ip, int rem_rtp_port,
......@@ -658,6 +664,12 @@ int video_stream_start_from_io(VideoStream *stream, RtpProfile *profile, const c
MSWebCam *cam = NULL;
MSFilter *source = NULL;
MSFilter *output = NULL;
MSFilter *recorder = NULL;
if (stream->ms.state != MSStreamInitialized){
ms_error("VideoStream in bad state");
return -1;
}
if (!ms_media_stream_io_is_consistent(io)) return -1;
......@@ -677,6 +689,11 @@ int video_stream_start_from_io(VideoStream *stream, RtpProfile *profile, const c
ms_error("Mediastreamer2 library compiled without libmastroska2");
return -1;
}
stream->source = source;
if (io->input.file) {
if (video_stream_open_remote_play(stream, io->input.file)!=NULL)
ms_filter_call_method_noarg(source, MS_PLAYER_START);
}
break;
default:
ms_error("Unhandled input resource type %s", ms_resource_type_to_string(io->input.type));
......@@ -689,6 +706,15 @@ int video_stream_start_from_io(VideoStream *stream, RtpProfile *profile, const c
ms_filter_call_method(output, MS_RTP_SEND_SET_SESSION, stream->rtp_io_session);
break;
case MSResourceFile:
recorder = ms_filter_new(MS_MKV_RECORDER_ID);
if (!recorder){
ms_error("Mediastreamer2 library compiled without libmastroska2");
return -1;
}
if (stream->recorder_output){
ms_filter_destroy(stream->recorder_output);
}
stream->recorder_output = recorder;
break;
default:
/*will just display in all other cases*/
......@@ -777,8 +803,10 @@ static int video_stream_start_with_source_and_output(VideoStream *stream, RtpPro
bool_t rtp_output = FALSE;
if (source == NULL) {
ms_error("videostream.c: no defined source");
return -1;
if (stream->source == NULL){
ms_error("videostream.c: no defined source");
return -1;
}else source = stream->source;
}
rtp_source = (ms_filter_get_id(source) == MS_RTP_RECV_ID) ? TRUE : FALSE;
......@@ -865,7 +893,6 @@ static int video_stream_start_with_source_and_output(VideoStream *stream, RtpPro
stream->output2=ms_filter_new_from_name (stream->display_name);
}
}
configure_video_source(stream);
}
......@@ -1013,10 +1040,10 @@ static int video_stream_start_with_source_and_output(VideoStream *stream, RtpPro
ms_connection_helper_start (&ch);
ms_connection_helper_link (&ch,stream->ms.rtprecv,-1,0);
if ((stream->output_performs_decoding == FALSE) && !rtp_output) {
if (stream->itcsink){
if (stream->recorder_output){
ms_connection_helper_link(&ch,stream->tee3,0,0);
ms_filter_link(stream->tee3,1,stream->itcsink,0);
configure_itc(stream);
ms_filter_link(stream->tee3,1,stream->recorder_output,0);
configure_recorder_output(stream);
}
ms_connection_helper_link(&ch,stream->ms.decoder,0,0);
}
......@@ -1310,9 +1337,9 @@ static MSFilter* _video_stream_stop(VideoStream * stream, bool_t keep_source)
ms_connection_helper_start (&h);
ms_connection_helper_unlink (&h,stream->ms.rtprecv,-1,0);
if ((stream->output_performs_decoding == FALSE) && !rtp_output) {
if (stream->itcsink){
if (stream->recorder_output){
ms_connection_helper_unlink(&h,stream->tee3,0,0);
ms_filter_unlink(stream->tee3,1,stream->itcsink,0);
ms_filter_unlink(stream->tee3,1,stream->recorder_output,0);
}
ms_connection_helper_unlink (&h,stream->ms.decoder,0,0);
}
......@@ -1576,12 +1603,29 @@ void video_stream_use_video_preset(VideoStream *stream, const char *preset) {
}
MSFilter * video_stream_open_remote_play(VideoStream *stream, const char *filename){
/*stub, to be implemented.*/
return NULL;
MSFilter *source = stream->source;
if (!source || !ms_filter_implements_interface(source, MSFilterPlayerInterface)){
ms_error("video_stream_open_remote_play(): the stream is not using a player.");
return NULL;
}
video_stream_close_remote_play(stream);
if (ms_filter_call_method(source, MS_PLAYER_OPEN, (void*)filename)!=0){
return NULL;
}
return source;
}
void video_stream_close_remote_play(VideoStream *stream){
/*stub, to be implemented.*/
MSPlayerState state = MSPlayerClosed;
MSFilter *source = stream->source;
if (!source) return;
ms_filter_call_method(source, MS_PLAYER_GET_STATE, &state);
if (state != MSPlayerClosed){
ms_filter_call_method_noarg(source, MS_PLAYER_CLOSE);
}
}
int video_stream_remote_record_open(VideoStream *stream, const char *filename){
......
......@@ -870,6 +870,7 @@ void setup_media_streams(MediastreamDatas* args) {
float zoom[] = {
args->zoom,
args->zoom_cx, args->zoom_cy };
MSMediaStreamIO iodef = MS_MEDIA_STREAM_IO_INITIALIZER;
if (args->eq){
ms_fatal("Cannot put an audio equalizer in a video stream !");
......@@ -900,11 +901,27 @@ void setup_media_streams(MediastreamDatas* args) {
cam=ms_web_cam_manager_get_cam(ms_web_cam_manager_get(),args->camera);
if (cam==NULL)
cam=ms_web_cam_manager_get_default_cam(ms_web_cam_manager_get());
video_stream_start(args->video,args->profile,
if (args->infile){
iodef.input.type = MSResourceFile;
iodef.input.file = args->infile;
}else{
iodef.input.type = MSResourceCamera;
iodef.input.camera = cam;
}
if (args->outfile){
iodef.output.type = MSResourceFile;
iodef.output.file = args->outfile;
}else{
iodef.output.type = MSResourceDefault;
iodef.output.resource_arg = NULL;
}
rtp_session_set_jitter_compensation(args->video->ms.sessions.rtp_session, args->jitter);
video_stream_start_from_io(args->video, args->profile,
args->ip,args->remoteport,
args->ip,args->enable_rtcp?args->remoteport+1:-1,
args->payload,
args->jitter,cam
&iodef
);
args->session=args->video->ms.sessions.rtp_session;
......
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