Commit 3a480a10 authored by Sylvain Berfini's avatar Sylvain Berfini 🐮
Browse files

Merge branch 'master' into dev_audio_bypass

parents 75fe8bcf da046f0c
......@@ -46,6 +46,7 @@ set(HEADER_FILES
msfilerec.h
msfilter.h
msgenericplc.h
msiframerequestslimiter.h
msinterfaces.h
msitc.h
msjava.h
......
......@@ -26,6 +26,7 @@ mediastreamer2_include_HEADERS=allfilters.h \
msfilerec.h \
msfilter.h \
msgenericplc.h \
msiframerequestslimiter.h \
msinterfaces.h \
msitc.h \
msjava.h \
......@@ -33,6 +34,7 @@ mediastreamer2_include_HEADERS=allfilters.h \
msmediaplayer.h \
msqueue.h \
msrtp.h \
msrtt4103.h \
mssndcard.h \
mstee.h \
msticker.h \
......@@ -52,8 +54,7 @@ mediastreamer2_include_HEADERS=allfilters.h \
upnp_igd.h \
videostarter.h \
x11_helper.h \
zrtp.h \
msrtt4103.h
zrtp.h
EXTRA_DIST=$(mediastreamer2_include_HEADERS)
/*
mediastreamer2 library - modular sound and video processing and streaming
Copyright (C) 2006 Simon MORLAT (simon.morlat@linphone.org)
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#ifndef MS_IFRAME_REQUESTS_LIMITER_H
#define MS_IFRAME_REQUESTS_LIMITER_H
#include <mediastreamer2/msticker.h>
#ifdef __cplusplus
extern "C" {
#endif
typedef struct _MSIFrameRequestsLimiterCtx {
const MSTicker *ticker;
bool_t iframe_required;
uint64_t last_sent_iframe_time;
int min_iframe_interval;
} MSIFrameRequestsLimiterCtx;
MS2_PUBLIC void ms_iframe_requests_limiter_init(MSIFrameRequestsLimiterCtx *obj, const MSTicker *t, int min_iframe_interval);
MS2_PUBLIC void ms_iframe_requests_limiter_require_iframe(MSIFrameRequestsLimiterCtx *obj);
MS2_PUBLIC bool_t ms_iframe_requests_limiter_iframe_sending_authorized(const MSIFrameRequestsLimiterCtx *obj);
MS2_PUBLIC void ms_iframe_requests_limiter_notify_iframe_sent(MSIFrameRequestsLimiterCtx *obj);
#ifdef __cplusplus
}
#endif
#endif
......@@ -38,7 +38,11 @@ public final class Log {
TAG = tag;
isLogEnabled = enable;
}
public static void setEnableLog(boolean enable){
isLogEnabled = enable;
}
@SuppressWarnings(value="all")
private static boolean isLoggable(int level) {
return isLogEnabled && (!useIsLoggable || android.util.Log.isLoggable(TAG, level));
......
......@@ -168,6 +168,7 @@ set(VOIP_SOURCE_FILES_C
voip/bitratedriver.c
voip/ice.c
voip/mediastream.c
voip/msiframerequestslimiter.c
voip/msmediaplayer.c
voip/msvoip.c
voip/private.h
......@@ -377,12 +378,6 @@ if(ENABLE_VIDEO)
voip/vp8rtpfmt.h
)
endif()
if(MATROSKA2_FOUND)
list(APPEND VOIP_SOURCE_FILES_C
videofilters/mkv.c
utils/mkv_reader.c
)
endif()
if(X11_FOUND)
list(APPEND VOIP_SOURCE_FILES_C utils/x11_helper.c)
endif()
......@@ -390,6 +385,14 @@ if(ENABLE_VIDEO)
list(APPEND VOIP_SOURCE_FILES_C videofilters/x11video.c)
endif()
endif()
if(MATROSKA2_FOUND)
list(APPEND VOIP_SOURCE_FILES_C
videofilters/mkv.c
utils/mkv_reader.c
voip/rfc2429.h
voip/rfc3984.c
)
endif()
set(VOIP_SOURCE_FILES_ALL ${VOIP_SOURCE_FILES_C} ${VOIP_SOURCE_FILES_CXX} ${VOIP_SOURCE_FILES_OBJC})
......
......@@ -112,7 +112,8 @@ libmediastreamer_voip_la_SOURCES+= voip/private.h \
voip/stun.c \
voip/stun_udp.c \
crypto/ms_srtp.c \
crypto/dtls_srtp.c
crypto/dtls_srtp.c \
voip/msiframerequestslimiter.c
else
libmediastreamer_base_la_SOURCES+= ortp-deps/logging.c \
ortp-deps/port.c \
......
......@@ -57,6 +57,7 @@ static SoundDeviceDescription devices[]={
{ "HTC", "HTC One_M8", "msm8974", 0, 120 },
{ "LGE", "LS670", "", 0, 170 },
{ "LGE", "Nexus 5", "msm8974", 0, 0 , 16000 },
{ "LGE", "LG-H815", "msm8992", DEVICE_HAS_BUILTIN_AEC, 0 },
{ "motorola", "DROID RAZR", "", 0, 400 },
{ "motorola", "MB860", "", 0, 200 },
......
......@@ -378,22 +378,18 @@ static void player_process(MSFilter *f){
ms_queue_put(f->outputs[0],om);
}else freemsg(om);
if (err<bytes){
ms_filter_notify_no_arg(f,MS_PLAYER_EOF);
/*for compatibility:*/
ms_filter_notify_no_arg(f,MS_FILE_PLAYER_EOF);
lseek(d->fd,d->hsize,SEEK_SET);
/* special value for playing file only once */
if (d->loop_after<0)
{
if (d->loop_after<0){
d->state=MSPlayerPaused;
ms_filter_unlock(f);
return;
}
if (d->loop_after>=0){
}else if (d->loop_after>=0){
d->pause_time=d->loop_after;
}
ms_filter_notify_no_arg(f,MS_PLAYER_EOF);
/*for compatibility:*/
ms_filter_notify_no_arg(f,MS_FILE_PLAYER_EOF);
}
}else{
ms_warning("Fail to read %i bytes: %s",bytes,strerror(errno));
......
......@@ -24,6 +24,7 @@
#include "mediastreamer2/rfc3984.h"
#include "mediastreamer2/msticker.h"
#include "mediastreamer2/videostarter.h"
#include "mediastreamer2/msiframerequestslimiter.h"
const MSVideoConfiguration h264_video_confs[] = {
MS_VIDEO_CONF(1536000, 2560000, SXGA_MINUS, 25, 2),
......@@ -48,12 +49,12 @@ typedef struct _VTH264EncCtx {
bool_t is_configured;
bool_t bitrate_changed;
bool_t fps_changed;
bool_t vfu_requested;
const MSFilter *f;
const MSVideoConfiguration *video_confs;
MSVideoStarter starter;
bool_t enable_avpf;
bool_t first_frame;
MSIFrameRequestsLimiterCtx iframe_limiter;
} VTH264EncCtx;
static void h264_enc_output_cb(VTH264EncCtx *ctx, void *sourceFrameRefCon, OSStatus status, VTEncodeInfoFlags infoFlags, CMSampleBufferRef sampleBuffer) {
......@@ -99,6 +100,7 @@ static void h264_enc_output_cb(VTH264EncCtx *ctx, void *sourceFrameRefCon, OSSta
ms_queue_insert(&nalu_queue, insertion_point, nalu);
i++;
} while(i < parameter_set_count);
ms_message("VTH264Encoder: I-frame created");
}
rfc3984_pack(&ctx->packer_ctx, &nalu_queue, &ctx->queue, (uint32_t)(ctx->f->ticker->time * 90));
......@@ -169,6 +171,7 @@ static void h264_enc_preprocess(MSFilter *f) {
VTH264EncCtx *ctx = (VTH264EncCtx *)f->data;
h264_enc_configure(ctx);
ms_video_starter_init(&ctx->starter);
ms_iframe_requests_limiter_init(&ctx->iframe_limiter, f->ticker, 1000);
ctx->first_frame = TRUE;
}
......@@ -183,14 +186,6 @@ static void h264_enc_process(MSFilter *f) {
return;
}
#if 0 && TARGET_OS_IPHONE
CVPixelBufferPoolRef pixbuf_pool = VTCompressionSessionGetPixelBufferPool(ctx->session);
if(pixbuf_pool == NULL) {
ms_error("VideoToolbox: fails to get the pixel buffer pool");
return;
}
#endif
while((frame = ms_queue_get(f->inputs[0]))) {
YuvBuf src_yuv_frame, dst_yuv_frame = {0};
CVPixelBufferRef pixbuf;
......@@ -201,15 +196,11 @@ static void h264_enc_process(MSFilter *f) {
ms_yuv_buf_init_from_mblk(&src_yuv_frame, frame);
#if 0 && TARGET_OS_IPHONE
CVPixelBufferPoolCreatePixelBuffer(NULL, pixbuf_pool, &pixbuf);
#else
pixbuf_attr = CFDictionaryCreateMutable(NULL, 0, NULL, NULL);
value = CFNumberCreate(NULL, kCFNumberIntType, &pixbuf_fmt);
CFDictionarySetValue(pixbuf_attr, kCVPixelBufferPixelFormatTypeKey, value);
CVPixelBufferCreate(NULL, ctx->conf.vsize.width, ctx->conf.vsize.height, kCVPixelFormatType_420YpCbCr8Planar, pixbuf_attr, &pixbuf);
CFRelease(pixbuf_attr);
#endif
CVPixelBufferLockBaseAddress(pixbuf, 0);
dst_yuv_frame.w = (int)CVPixelBufferGetWidth(pixbuf);
......@@ -223,7 +214,7 @@ static void h264_enc_process(MSFilter *f) {
freemsg(frame);
ms_filter_lock(f);
if(ctx->fps_changed || ctx->bitrate_changed || ctx->vfu_requested) {
if(ctx->fps_changed || ctx->bitrate_changed || ms_iframe_requests_limiter_iframe_sending_authorized(&ctx->iframe_limiter)) {
CFNumberRef value;
enc_param = CFDictionaryCreateMutable(NULL, 0, NULL, NULL);
if(ctx->fps_changed) {
......@@ -236,11 +227,12 @@ static void h264_enc_process(MSFilter *f) {
CFDictionaryAddValue(enc_param, kVTCompressionPropertyKey_AverageBitRate, value);
ctx->bitrate_changed = FALSE;
}
if(ctx->vfu_requested) {
if(ms_iframe_requests_limiter_iframe_sending_authorized(&ctx->iframe_limiter)) {
ms_message("MSVTH264Encoder: requesting encoder for I-frame");
int force_keyframe = 1;
value = CFNumberCreate(NULL, kCFNumberIntType, &force_keyframe);
CFDictionaryAddValue(enc_param, kVTEncodeFrameOptionKey_ForceKeyFrame, value);
ctx->vfu_requested = FALSE;
ms_iframe_requests_limiter_notify_iframe_sent(&ctx->iframe_limiter);
}
}
ms_filter_unlock(f);
......@@ -296,13 +288,21 @@ static int h264_enc_get_video_size(MSFilter *f, MSVideoSize *vsize) {
static int h264_enc_set_video_size(MSFilter *f, const MSVideoSize *vsize) {
VTH264EncCtx *ctx = (VTH264EncCtx *)f->data;
MSVideoConfiguration conf;
ms_message("VideoToolboxEnc: requested video size: %dx%d", vsize->width, vsize->height);
if(ctx->is_configured) {
ms_error("VideoToolbox: could not set video size: encoder is running");
return -1;
}
ctx->conf = ms_video_find_best_configuration_for_size(ctx->video_confs, *vsize, f->factory->cpu_count);
ms_message("VideoToolboxEnc: selected video conf: size=%dx%d, framerate=%ffps", ctx->conf.vsize.width, ctx->conf.vsize.height, ctx->conf.fps);
conf = ms_video_find_best_configuration_for_size(ctx->video_confs, *vsize, f->factory->cpu_count);
ctx->conf.vsize = conf.vsize;
ctx->conf.fps = conf.fps;
ctx->conf.bitrate_limit = conf.bitrate_limit;
if(ctx->conf.required_bitrate > ctx->conf.bitrate_limit) {
ctx->conf.required_bitrate = ctx->conf.bitrate_limit;
}
ms_message("VideoToolboxEnc: selected video conf: size=%dx%d, framerate=%ffps, bitrate=%dbit/s",
ctx->conf.vsize.width, ctx->conf.vsize.height, ctx->conf.fps, ctx->conf.required_bitrate);
return 0;
}
......@@ -337,12 +337,15 @@ static int h264_enc_set_fps(MSFilter *f, const float *fps) {
ctx->conf.fps = *fps;
if(ctx->is_configured) ctx->fps_changed = TRUE;
ms_filter_unlock(f);
ms_message("VideoToolboxEnc: new frame rate target (%ffps)", ctx->conf.fps);
return 0;
}
static int h264_enc_req_vfu(MSFilter *f, void *ptr) {
VTH264EncCtx *ctx = (VTH264EncCtx *)f->data;
ms_filter_lock(f);
((VTH264EncCtx *)f->data)->vfu_requested = TRUE;
ms_video_starter_deactivate(&ctx->starter);
ms_iframe_requests_limiter_require_iframe(&ctx->iframe_limiter);
ms_filter_unlock(f);
return 0;
}
......@@ -350,9 +353,10 @@ static int h264_enc_req_vfu(MSFilter *f, void *ptr) {
static int h264_enc_enable_avpf(MSFilter *f, const bool_t *enable_avpf) {
VTH264EncCtx *ctx = (VTH264EncCtx *)f->data;
if(ctx->is_configured) {
ms_error("VideoToolbox: could not %s AVPF: encoder is running", *enable_avpf ? "enable" : "disable");
ms_error("VideoToolboxEnc: could not %s AVPF: encoder is running", *enable_avpf ? "enable" : "disable");
return -1;
}
ms_message("VideoToolboxEnc: %s AVPF", *enable_avpf ? "enabling" : "disabling");
ctx->enable_avpf = *enable_avpf;
return 0;
}
......@@ -363,14 +367,34 @@ static int h264_enc_get_config_list(MSFilter *f, const MSVideoConfiguration **co
}
static int h264_enc_set_config_list(MSFilter *f, const MSVideoConfiguration **conf_list) {
const MSVideoConfiguration *conf = *conf_list;
((VTH264EncCtx *)f->data)->video_confs = conf ? conf : h264_video_confs;
VTH264EncCtx *ctx = (VTH264EncCtx *)f->data;
ctx->video_confs = *conf_list ? *conf_list : h264_video_confs;
ctx->conf = ms_video_find_best_configuration_for_size(ctx->video_confs, ctx->conf.vsize, f->factory->cpu_count);
ms_message("VideoToolboxEnc: new video settings: %dx%d, %dbit/s, %ffps",
ctx->conf.vsize.width, ctx->conf.vsize.height,
ctx->conf.required_bitrate, ctx->conf.fps);
return 0;
}
static int h264_enc_set_config(MSFilter *f, const MSVideoConfiguration *conf) {
VTH264EncCtx *ctx = (VTH264EncCtx *)f->data;
ctx->conf = *conf;
ms_filter_lock(f);
if(ctx->is_configured) {
if(ctx->conf.fps != conf->fps) {
ctx->conf.fps = conf->fps;
ctx->fps_changed = TRUE;
}
if(ctx->conf.required_bitrate != conf->required_bitrate) {
ctx->conf.required_bitrate = conf->required_bitrate;
ctx->bitrate_changed = TRUE;
}
} else {
ctx->conf = *conf;
}
ms_filter_unlock(f);
ms_message("VideoToolboxEnc: new video settings: %dx%d, %dbit/s, %ffps",
ctx->conf.vsize.width, ctx->conf.vsize.height,
ctx->conf.required_bitrate, ctx->conf.fps);
return 0;
}
......@@ -383,6 +407,9 @@ static MSFilterMethod h264_enc_methods[] = {
{ MS_FILTER_SET_FPS , (MSFilterMethodFunc)h264_enc_set_fps },
{ MS_FILTER_REQ_VFU , (MSFilterMethodFunc)h264_enc_req_vfu },
{ MS_VIDEO_ENCODER_REQ_VFU , (MSFilterMethodFunc)h264_enc_req_vfu },
{ MS_VIDEO_ENCODER_NOTIFY_FIR , (MSFilterMethodFunc)h264_enc_req_vfu },
{ MS_VIDEO_ENCODER_NOTIFY_PLI , (MSFilterMethodFunc)h264_enc_req_vfu },
{ MS_VIDEO_ENCODER_NOTIFY_SLI , (MSFilterMethodFunc)h264_enc_req_vfu },
{ MS_VIDEO_ENCODER_ENABLE_AVPF , (MSFilterMethodFunc)h264_enc_enable_avpf },
{ MS_VIDEO_ENCODER_GET_CONFIGURATION_LIST , (MSFilterMethodFunc)h264_enc_get_config_list },
{ MS_VIDEO_ENCODER_SET_CONFIGURATION_LIST , (MSFilterMethodFunc)h264_enc_set_config_list },
......@@ -588,31 +615,35 @@ static void h264_dec_process(MSFilter *f) {
OSStatus status;
MSList *parameter_sets = NULL;
bool_t unpacking_failed;
bool_t iframe_received = FALSE;
ms_queue_init(&q_nalus);
ms_queue_init(&q_nalus2);
// unpack RTP packet
// unpack RTP packets
unpacking_failed = FALSE;
while((pkt = ms_queue_get(f->inputs[0]))) {
unpacking_failed |= (rfc3984_unpack(&ctx->unpacker, pkt, &q_nalus) != 0);
}
if (unpacking_failed) {
ms_error("VideoToolboxDecoder: error while unpacking RTP packets");
goto fail;
ms_warning("VideoToolboxDecoder: error while unpacking RTP packets");
}
// Pull out SPSs and PPSs and put them into the filter context if necessary
// Pull SPSs and PPSs out and put them into the filter context if necessary
while((nalu = ms_queue_get(&q_nalus))) {
MSH264NaluType nalu_type = ms_h264_nalu_get_type(nalu);
if(nalu_type == MSH264NaluTypeSPS || nalu_type == MSH264NaluTypePPS) {
parameter_sets = ms_list_append(parameter_sets, nalu);
iframe_received = TRUE;
} else if(ctx->format_desc || parameter_sets) {
ms_queue_put(&q_nalus2, nalu);
} else {
freemsg(nalu);
}
}
if(iframe_received) ms_message("VideoToolboxDecoder: I-frame received");
if(parameter_sets) {
CMFormatDescriptionRef last_format = ctx->format_desc ? CFRetain(ctx->format_desc) : NULL;
h264_dec_update_format_description(ctx, parameter_sets);
......@@ -801,15 +832,17 @@ MSFilterDesc ms_vt_h264_dec = {
};
void _register_videotoolbox_if_supported(MSFactory *factory) {
if (VTCompressionSessionCreate != NULL
&& VTDecompressionSessionCreate != NULL
&& CMVideoFormatDescriptionCreateFromH264ParameterSets != NULL) {
#ifdef __ios
if (kCFCoreFoundationVersionNumber >= kCFCoreFoundationVersionNumber_iOS_8_0) {
#else
if (kCFCoreFoundationVersionNumber >= kCFCoreFoundationVersionNumber10_8) {
#endif
ms_message("Registering VideoToobox H264 codec");
ms_factory_register_filter(factory, &ms_vt_h264_enc);
ms_factory_register_filter(factory, &ms_vt_h264_dec);
} else {
ms_warning("Cannot register VideoToolbox filters. Those filters"
" require iOS 8 or MacOSX 10.8");
ms_warning("Cannot register VideoToolbox H264 codec. That"
" requires iOS 8 or MacOSX 10.8");
}
}
......
#include "mediastreamer2/msiframerequestslimiter.h"
void ms_iframe_requests_limiter_init(MSIFrameRequestsLimiterCtx *obj, const MSTicker *t, int min_iframe_interval) {
memset(obj, 0, sizeof(MSIFrameRequestsLimiterCtx));
obj->ticker = t;
obj->last_sent_iframe_time = t->time;
obj->min_iframe_interval = min_iframe_interval;
}
void ms_iframe_requests_limiter_require_iframe(MSIFrameRequestsLimiterCtx *obj) {
obj->iframe_required = TRUE;
}
bool_t ms_iframe_requests_limiter_iframe_sending_authorized(const MSIFrameRequestsLimiterCtx *obj) {
return obj->iframe_required && (obj->ticker->time - obj->last_sent_iframe_time) > obj->min_iframe_interval;
}
void ms_iframe_requests_limiter_notify_iframe_sent(MSIFrameRequestsLimiterCtx *obj) {
obj->iframe_required = FALSE;
obj->last_sent_iframe_time = obj->ticker->time;
}
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