Commit af36a13d authored by Ghislain MARY's avatar Ghislain MARY

Merge branch '2.12.x'

Conflicts:
	src/voip/private.h
parents e0d08401 372ec3ba
......@@ -26,7 +26,7 @@ project(MEDIASTREAMER2 C CXX)
set(MEDIASTREAMER_MAJOR_VERSION "2")
set(MEDIASTREAMER_MINOR_VERSION "12")
set(MEDIASTREAMER_MICRO_VERSION "0")
set(MEDIASTREAMER_MICRO_VERSION "1")
set(MEDIASTREAMER_VERSION "${MEDIASTREAMER_MAJOR_VERSION}.${MEDIASTREAMER_MINOR_VERSION}.${MEDIASTREAMER_MICRO_VERSION}")
set(MEDIASTREAMER_SO_VERSION "6")
......
mediastreamer2-2.12.1: November 16, 2015
* Fix crash in MKV recorder
* Fix I-frame request when starting MKV recording
mediastreamer2-2.12.0: November 2, 2015
* Allow video stream to keep its source (camera)
* Basic AVPF handling for H.264 codec
......
dnl Process this file with autoconf to produce a configure script.
AC_INIT([mediastreamer],[2.12.0])
AC_INIT([mediastreamer],[2.12.1])
AC_MSG_NOTICE([$PACKAGE_NAME-$PACKAGE_VERSION A mediastreaming library for telephony application.])
AC_MSG_NOTICE([licensed under the terms of the General Public License (GPL)])
......
mediastreamer2 (2.12.1) unstable; urgency=low
* Fix crash in MKV recorder
* Fix I-frame request when starting MKV recording
-- Belledonne Communications <info@belledonne-communications.com> Mon, 16 Nov 2015 10:42:00 +0200
mediastreamer2 (2.12.0) unstable; urgency=low
* Allow video stream to keep its source (camera)
......
......@@ -41,10 +41,10 @@ static int recorder_close(MSFilter *f, void *arg);
/*********************************************************************************************
* Module interface *
*********************************************************************************************/
typedef void *(*ModuleNewFunc)();
typedef void *(*ModuleNewFunc)(void);
typedef void (*ModuleFreeFunc)(void *obj);
typedef void (*ModuleSetFunc)(void *obj, const MSFmtDescriptor *fmt);
typedef void (*ModulePreProFunc)(void *obj, MSQueue *input, MSQueue *output);
typedef int (*ModulePreProFunc)(void *obj, MSQueue *input, MSQueue *output);
typedef mblk_t *(*ModuleProFunc)(void *obj, mblk_t *buffer, ms_bool_t *isKeyFrame, ms_bool_t *isVisible, uint8_t **codecPrivateData, size_t *codecPrivateSize);
typedef void (*ModuleReverseFunc)(void *obj, mblk_t *input, MSQueue *output, ms_bool_t isFirstFrame, const uint8_t *codecPrivateData, size_t codecPrivateSize);
typedef void (*ModulePrivateDataFunc)(const void *obj, uint8_t **data, size_t *data_size);
......@@ -212,7 +212,7 @@ typedef struct {
H264Private *codecPrivate;
} H264Module;
static void *h264_module_new() {
static void *h264_module_new(void) {
H264Module *mod = ms_new0(H264Module, 1);
rfc3984_init(&mod->rfc3984Context);
rfc3984_set_mode(&mod->rfc3984Context,1);
......@@ -228,7 +228,7 @@ static void h264_module_free(void *data) {
ms_free(obj);
}
static void h264_module_preprocessing(void *data, MSQueue *input, MSQueue *output) {
static int h264_module_preprocessing(void *data, MSQueue *input, MSQueue *output) {
H264Module *obj = (H264Module *)data;
MSQueue queue;
mblk_t *inputBuffer = NULL;
......@@ -245,6 +245,8 @@ static void h264_module_preprocessing(void *data, MSQueue *input, MSQueue *outpu
ms_queue_put(output, frame);
}
}
return 0;
}
static int h264_nalu_type(const mblk_t *nalu) {
......@@ -431,35 +433,35 @@ typedef struct _Vp8Module {
uint16_t cseq;
} Vp8Module;
void *vp8_module_new() {
static void *vp8_module_new(void) {
Vp8Module *obj = (Vp8Module *)ms_new0(Vp8Module, 1);
vp8rtpfmt_unpacker_init(&obj->unpacker, NULL, FALSE, TRUE, FALSE);
vp8rtpfmt_packer_init(&obj->packer);
return obj;
}
void vp8_module_free(void *obj) {
static void vp8_module_free(void *obj) {
Vp8Module *mod = (Vp8Module *)obj;
vp8rtpfmt_unpacker_uninit(&mod->unpacker);
vp8rtpfmt_packer_uninit(&mod->packer);
ms_free(mod);
}
void vp8_module_preprocess(void *obj, MSQueue *input, MSQueue *output) {
static int vp8_module_preprocess(void *obj, MSQueue *input, MSQueue *output) {
Vp8RtpFmtUnpackerCtx *unpacker = (Vp8RtpFmtUnpackerCtx *)obj;
Vp8RtpFmtFrameInfo infos;
vp8rtpfmt_unpacker_feed(unpacker, input);
vp8rtpfmt_unpacker_get_frame(unpacker, output, &infos);
return vp8rtpfmt_unpacker_get_frame(unpacker, output, &infos);
}
mblk_t *vp8_module_process(void *obj, mblk_t *buffer, ms_bool_t *isKeyFrame, ms_bool_t *isVisible, uint8_t **codecPrivateData, size_t *codecPrivateSize) {
static mblk_t *vp8_module_process(void *obj, mblk_t *buffer, ms_bool_t *isKeyFrame, ms_bool_t *isVisible, uint8_t **codecPrivateData, size_t *codecPrivateSize) {
uint8_t first_byte = *buffer->b_rptr;
*isKeyFrame = !(first_byte & 0x01);
*isVisible = first_byte & 0x10;
return buffer;
}
void vp8_module_reverse(void *obj, mblk_t *input, MSQueue *output, ms_bool_t isFirstFrame, const uint8_t *codecPrivateData, size_t codecPrivateSize) {
static void vp8_module_reverse(void *obj, mblk_t *input, MSQueue *output, ms_bool_t isFirstFrame, const uint8_t *codecPrivateData, size_t codecPrivateSize) {
Vp8Module *mod = (Vp8Module *)obj;
MSList *packer_input = NULL;
Vp8RtpFmtPacket *packet = ms_new0(Vp8RtpFmtPacket, 1);
......@@ -484,7 +486,7 @@ void vp8_module_reverse(void *obj, mblk_t *input, MSQueue *output, ms_bool_t isF
}
}
ms_bool_t vp8_module_is_keyframe(const mblk_t *frame) {
static ms_bool_t vp8_module_is_keyframe(const mblk_t *frame) {
uint8_t first_byte = *frame->b_rptr;
return !(first_byte & 0x01);
}
......@@ -559,7 +561,7 @@ static void wav_private_load(WavPrivate *obj, const uint8_t *data) {
}
/* µLaw module */
static void *mu_law_module_new() {
static void *mu_law_module_new(void) {
return ms_new0(WavPrivate, 1);
}
......@@ -651,7 +653,7 @@ static void opus_codec_private_load(OpusCodecPrivate *obj, const uint8_t *data,
}
// OpusModule
static void *opus_module_new() {
static void *opus_module_new(void) {
OpusCodecPrivate *obj = ms_new0(OpusCodecPrivate, 1);
opus_codec_private_init(obj);
return obj;
......@@ -778,14 +780,15 @@ static void module_set(Module *module, const MSFmtDescriptor *format) {
}
}
static void module_preprocess(Module *module, MSQueue *input, MSQueue *output) {
static int module_preprocess(Module *module, MSQueue *input, MSQueue *output) {
if(moduleDescs[module->id]->preprocess != NULL) {
moduleDescs[module->id]->preprocess(module->data, input, output);
return moduleDescs[module->id]->preprocess(module->data, input, output);
} else {
mblk_t *buffer;
while((buffer = ms_queue_get(input)) != NULL) {
ms_queue_put(output, buffer);
}
return 0;
}
}
......@@ -1306,7 +1309,7 @@ static int matroska_get_codec_private(const Matroska *obj, int trackNum, const u
ebml_binary *codecPrivate;
if(trackEntry == NULL)
return -1;
codecPrivate = (ebml_binary *)EBML_MasterGetChild(trackEntry, &MATROSKA_ContextCodecPrivate);
codecPrivate = (ebml_binary *)EBML_MasterFindChild(trackEntry, &MATROSKA_ContextCodecPrivate);
if(codecPrivate == NULL)
return -2;
......@@ -1840,6 +1843,13 @@ static int recorder_open_file(MSFilter *f, void *arg) {
return -1;
}
static void recorder_request_fir(MSFilter *f, MKVRecorder *obj){
if (obj->lastFirTime == -1 || obj->lastFirTime +2000 < f->ticker->time){
obj->lastFirTime = f->ticker->time;
ms_filter_notify_no_arg(f, MS_RECORDER_NEEDS_FIR);
}
}
static int recorder_start(MSFilter *f, void *arg) {
MKVRecorder *obj = (MKVRecorder *)f->data;
int i;
......@@ -1890,6 +1900,7 @@ static int recorder_start(MSFilter *f, void *arg) {
}
obj->state = MSRecorderRunning;
obj->needKeyFrame = TRUE;
recorder_request_fir(f, obj);
ms_message("MKVRecorder: recording successfully started");
ms_filter_unlock(f);
return 0;
......@@ -1929,13 +1940,6 @@ static int recorder_stop(MSFilter *f, void *arg) {
return -1;
}
static void recorder_request_fir(MSFilter *f, MKVRecorder *obj){
if (obj->lastFirTime == -1 || obj->lastFirTime +2000 < f->ticker->time){
obj->lastFirTime = f->ticker->time;
ms_filter_notify_no_arg(f, MS_RECORDER_NEEDS_FIR);
}
}
static void recorder_process(MSFilter *f) {
MKVRecorder *obj = f->data;
int i;
......@@ -1958,7 +1962,10 @@ static void recorder_process(MSFilter *f) {
ms_queue_init(&frames);
ms_queue_init(&frames_ms);
module_preprocess(obj->modulesList[i], f->inputs[i], &frames);
if ((module_preprocess(obj->modulesList[i], f->inputs[i], &frames) < 0) && obj->needKeyFrame) {
ms_warning("MKVRecorder: preprocess error, waiting for an I-frame");
recorder_request_fir(f, obj);
}
while((buffer = ms_queue_get(&frames)) != NULL) {
mblk_set_timestamp_info(buffer, time_loop_canceler_apply(obj->timeLoopCancelers[i], mblk_get_timestamp_info(buffer)));
changeClockRate(buffer, obj->inputDescsList[i]->rate, 1000);
......@@ -2031,7 +2038,7 @@ static int recorder_close(MSFilter *f, void *arg) {
if(codecPrivateDataSize > 0) {
matroska_track_set_codec_private(&obj->file, i + 1, codecPrivateData, codecPrivateDataSize);
}
ms_free(codecPrivateData);
if (codecPrivateData) ms_free(codecPrivateData);
} else {
matroska_del_track(&obj->file, i+1);
}
......
......@@ -583,6 +583,13 @@ static void video_input_updated(void *stream, MSFilter *f, unsigned int event_id
}
}
static void av_recorder_handle_event(void *userdata, MSFilter *recorder, unsigned int event, void *event_arg){
AudioStream *audiostream = (AudioStream *)userdata;
if (audiostream->videostream != NULL) {
video_recorder_handle_event(audiostream->videostream, recorder, event, event_arg);
}
}
static void setup_av_recorder(AudioStream *stream, int sample_rate, int nchannels){
stream->av_recorder.recorder=ms_filter_new(MS_MKV_RECORDER_ID);
if (stream->av_recorder.recorder){
......@@ -616,6 +623,7 @@ static void setup_av_recorder(AudioStream *stream, int sample_rate, int nchannel
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);
ms_filter_add_notify_callback(stream->av_recorder.video_input,video_input_updated,stream,TRUE);
ms_filter_add_notify_callback(stream->av_recorder.recorder, av_recorder_handle_event, stream, TRUE);
}
}
......
......@@ -116,6 +116,8 @@ void ms_srtp_context_delete(MSSrtpCtx *session);
void register_video_preset_high_fps(MSVideoPresetsManager *manager);
MSFilter *_ms_create_av_player(const char *filename);
void video_recorder_handle_event(void *userdata, MSFilter *recorder, unsigned int event, void *event_arg);
#ifdef __cplusplus
}
......
......@@ -135,7 +135,7 @@ static void video_stream_process_rtcp(MediaStream *media_stream, mblk_t *m){
for (i = 0; ; i++) {
rtcp_fb_fir_fci_t *fci = rtcp_PSFB_fir_get_fci(m, i);
if (fci == NULL) break;
if (rtcp_fb_fir_fci_get_ssrc(fci) == rtp_session_get_send_ssrc(stream->ms.sessions.rtp_session)) {
if (rtcp_fb_fir_fci_get_ssrc(fci) == rtp_session_get_recv_ssrc(stream->ms.sessions.rtp_session)) {
uint8_t seq_nr = rtcp_fb_fir_fci_get_seq_nr(fci);
ms_filter_call_method(stream->ms.encoder, MS_VIDEO_ENCODER_NOTIFY_FIR, &seq_nr);
break;
......@@ -666,13 +666,15 @@ int video_stream_start (VideoStream *stream, RtpProfile *profile, const char *re
return video_stream_start_from_io(stream, profile, rem_rtp_ip, rem_rtp_port, rem_rtcp_ip, rem_rtcp_port, payload, &io);
}
static void recorder_handle_event(void *userdata, MSFilter *recorder, unsigned int event, void *event_arg){
void video_recorder_handle_event(void *userdata, MSFilter *recorder, unsigned int event, void *event_arg){
VideoStream *stream = (VideoStream*) userdata;
switch (event){
case MS_RECORDER_NEEDS_FIR:
ms_message("Request sending of FIR on videostream [%p]", stream);
video_stream_send_fir(stream);
break;
break;
default:
break;
}
}
......@@ -735,7 +737,7 @@ int video_stream_start_from_io(VideoStream *stream, RtpProfile *profile, const c
ms_filter_destroy(stream->recorder_output);
}
stream->recorder_output = recorder;
ms_filter_add_notify_callback(recorder, recorder_handle_event, stream, TRUE);
ms_filter_add_notify_callback(recorder, video_recorder_handle_event, stream, TRUE);
if (io->output.file) video_stream_open_remote_record(stream, io->output.file);
break;
default:
......
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