Commit 9819c046 authored by François Grisez's avatar François Grisez

Creates MSIFrameReqestsLimitor class use it in VTH264Encoder

parent 7f3a3803
...@@ -46,6 +46,7 @@ set(HEADER_FILES ...@@ -46,6 +46,7 @@ set(HEADER_FILES
msfilerec.h msfilerec.h
msfilter.h msfilter.h
msgenericplc.h msgenericplc.h
msiframerequestslimiter.h
msinterfaces.h msinterfaces.h
msitc.h msitc.h
msjava.h msjava.h
......
...@@ -26,6 +26,7 @@ mediastreamer2_include_HEADERS=allfilters.h \ ...@@ -26,6 +26,7 @@ mediastreamer2_include_HEADERS=allfilters.h \
msfilerec.h \ msfilerec.h \
msfilter.h \ msfilter.h \
msgenericplc.h \ msgenericplc.h \
msiframerequestslimiter.h \
msinterfaces.h \ msinterfaces.h \
msitc.h \ msitc.h \
msjava.h \ msjava.h \
...@@ -33,6 +34,7 @@ mediastreamer2_include_HEADERS=allfilters.h \ ...@@ -33,6 +34,7 @@ mediastreamer2_include_HEADERS=allfilters.h \
msmediaplayer.h \ msmediaplayer.h \
msqueue.h \ msqueue.h \
msrtp.h \ msrtp.h \
msrtt4103.h \
mssndcard.h \ mssndcard.h \
mstee.h \ mstee.h \
msticker.h \ msticker.h \
...@@ -52,8 +54,7 @@ mediastreamer2_include_HEADERS=allfilters.h \ ...@@ -52,8 +54,7 @@ mediastreamer2_include_HEADERS=allfilters.h \
upnp_igd.h \ upnp_igd.h \
videostarter.h \ videostarter.h \
x11_helper.h \ x11_helper.h \
zrtp.h \ zrtp.h
msrtt4103.h
EXTRA_DIST=$(mediastreamer2_include_HEADERS) 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>
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);
#endif
...@@ -168,6 +168,7 @@ set(VOIP_SOURCE_FILES_C ...@@ -168,6 +168,7 @@ set(VOIP_SOURCE_FILES_C
voip/bitratedriver.c voip/bitratedriver.c
voip/ice.c voip/ice.c
voip/mediastream.c voip/mediastream.c
voip/msiframerequestslimiter.c
voip/msmediaplayer.c voip/msmediaplayer.c
voip/msvoip.c voip/msvoip.c
voip/private.h voip/private.h
......
...@@ -112,7 +112,8 @@ libmediastreamer_voip_la_SOURCES+= voip/private.h \ ...@@ -112,7 +112,8 @@ libmediastreamer_voip_la_SOURCES+= voip/private.h \
voip/stun.c \ voip/stun.c \
voip/stun_udp.c \ voip/stun_udp.c \
crypto/ms_srtp.c \ crypto/ms_srtp.c \
crypto/dtls_srtp.c crypto/dtls_srtp.c \
voip/msiframerequestslimiter.c
else else
libmediastreamer_base_la_SOURCES+= ortp-deps/logging.c \ libmediastreamer_base_la_SOURCES+= ortp-deps/logging.c \
ortp-deps/port.c \ ortp-deps/port.c \
......
...@@ -24,6 +24,7 @@ ...@@ -24,6 +24,7 @@
#include "mediastreamer2/rfc3984.h" #include "mediastreamer2/rfc3984.h"
#include "mediastreamer2/msticker.h" #include "mediastreamer2/msticker.h"
#include "mediastreamer2/videostarter.h" #include "mediastreamer2/videostarter.h"
#include "mediastreamer2/msiframerequestslimiter.h"
const MSVideoConfiguration h264_video_confs[] = { const MSVideoConfiguration h264_video_confs[] = {
MS_VIDEO_CONF(1536000, 2560000, SXGA_MINUS, 25, 2), MS_VIDEO_CONF(1536000, 2560000, SXGA_MINUS, 25, 2),
...@@ -48,13 +49,12 @@ typedef struct _VTH264EncCtx { ...@@ -48,13 +49,12 @@ typedef struct _VTH264EncCtx {
bool_t is_configured; bool_t is_configured;
bool_t bitrate_changed; bool_t bitrate_changed;
bool_t fps_changed; bool_t fps_changed;
bool_t iframe_requested;
uint64_t last_iframe_request_time;
const MSFilter *f; const MSFilter *f;
const MSVideoConfiguration *video_confs; const MSVideoConfiguration *video_confs;
MSVideoStarter starter; MSVideoStarter starter;
bool_t enable_avpf; bool_t enable_avpf;
bool_t first_frame; bool_t first_frame;
MSIFrameRequestsLimiterCtx iframe_limiter;
} VTH264EncCtx; } VTH264EncCtx;
static void h264_enc_output_cb(VTH264EncCtx *ctx, void *sourceFrameRefCon, OSStatus status, VTEncodeInfoFlags infoFlags, CMSampleBufferRef sampleBuffer) { static void h264_enc_output_cb(VTH264EncCtx *ctx, void *sourceFrameRefCon, OSStatus status, VTEncodeInfoFlags infoFlags, CMSampleBufferRef sampleBuffer) {
...@@ -100,6 +100,7 @@ static void h264_enc_output_cb(VTH264EncCtx *ctx, void *sourceFrameRefCon, OSSta ...@@ -100,6 +100,7 @@ static void h264_enc_output_cb(VTH264EncCtx *ctx, void *sourceFrameRefCon, OSSta
ms_queue_insert(&nalu_queue, insertion_point, nalu); ms_queue_insert(&nalu_queue, insertion_point, nalu);
i++; i++;
} while(i < parameter_set_count); } 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)); rfc3984_pack(&ctx->packer_ctx, &nalu_queue, &ctx->queue, (uint32_t)(ctx->f->ticker->time * 90));
...@@ -170,6 +171,7 @@ static void h264_enc_preprocess(MSFilter *f) { ...@@ -170,6 +171,7 @@ static void h264_enc_preprocess(MSFilter *f) {
VTH264EncCtx *ctx = (VTH264EncCtx *)f->data; VTH264EncCtx *ctx = (VTH264EncCtx *)f->data;
h264_enc_configure(ctx); h264_enc_configure(ctx);
ms_video_starter_init(&ctx->starter); ms_video_starter_init(&ctx->starter);
ms_iframe_requests_limiter_init(&ctx->iframe_limiter, f->ticker, 1000);
ctx->first_frame = TRUE; ctx->first_frame = TRUE;
} }
...@@ -224,7 +226,7 @@ static void h264_enc_process(MSFilter *f) { ...@@ -224,7 +226,7 @@ static void h264_enc_process(MSFilter *f) {
freemsg(frame); freemsg(frame);
ms_filter_lock(f); ms_filter_lock(f);
if(ctx->fps_changed || ctx->bitrate_changed || ctx->iframe_requested) { if(ctx->fps_changed || ctx->bitrate_changed || ms_iframe_requests_limiter_iframe_sending_authorized(&ctx->iframe_limiter)) {
CFNumberRef value; CFNumberRef value;
enc_param = CFDictionaryCreateMutable(NULL, 0, NULL, NULL); enc_param = CFDictionaryCreateMutable(NULL, 0, NULL, NULL);
if(ctx->fps_changed) { if(ctx->fps_changed) {
...@@ -237,12 +239,12 @@ static void h264_enc_process(MSFilter *f) { ...@@ -237,12 +239,12 @@ static void h264_enc_process(MSFilter *f) {
CFDictionaryAddValue(enc_param, kVTCompressionPropertyKey_AverageBitRate, value); CFDictionaryAddValue(enc_param, kVTCompressionPropertyKey_AverageBitRate, value);
ctx->bitrate_changed = FALSE; ctx->bitrate_changed = FALSE;
} }
if(ctx->iframe_requested && f->ticker->time - ctx->last_iframe_request_time > 1000) { if(ms_iframe_requests_limiter_iframe_sending_authorized(&ctx->iframe_limiter)) {
ms_message("MSVTH264Encoder: requesting encoder for I-frame");
int force_keyframe = 1; int force_keyframe = 1;
value = CFNumberCreate(NULL, kCFNumberIntType, &force_keyframe); value = CFNumberCreate(NULL, kCFNumberIntType, &force_keyframe);
CFDictionaryAddValue(enc_param, kVTEncodeFrameOptionKey_ForceKeyFrame, value); CFDictionaryAddValue(enc_param, kVTEncodeFrameOptionKey_ForceKeyFrame, value);
ctx->iframe_requested = FALSE; ms_iframe_requests_limiter_notify_iframe_sent(&ctx->iframe_limiter);
ctx->last_iframe_request_time = f->ticker->time;
} }
} }
ms_filter_unlock(f); ms_filter_unlock(f);
...@@ -350,7 +352,7 @@ static int h264_enc_set_fps(MSFilter *f, const float *fps) { ...@@ -350,7 +352,7 @@ static int h264_enc_set_fps(MSFilter *f, const float *fps) {
static int h264_enc_req_vfu(MSFilter *f, void *ptr) { static int h264_enc_req_vfu(MSFilter *f, void *ptr) {
VTH264EncCtx *ctx = (VTH264EncCtx *)f->data; VTH264EncCtx *ctx = (VTH264EncCtx *)f->data;
ms_filter_lock(f); ms_filter_lock(f);
ctx->iframe_requested = TRUE; ms_iframe_requests_limiter_require_iframe(&ctx->iframe_limiter);
ms_filter_unlock(f); ms_filter_unlock(f);
return 0; return 0;
} }
...@@ -635,6 +637,9 @@ static void h264_dec_process(MSFilter *f) { ...@@ -635,6 +637,9 @@ static void h264_dec_process(MSFilter *f) {
// Pull SPSs and PPSs out 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))) { while((nalu = ms_queue_get(&q_nalus))) {
MSH264NaluType nalu_type = ms_h264_nalu_get_type(nalu); MSH264NaluType nalu_type = ms_h264_nalu_get_type(nalu);
if(nalu_type == MSH264NaluTypeIDR) {
ms_message("VTH264Decoder: receiving IDR");
}
if(nalu_type == MSH264NaluTypeSPS || nalu_type == MSH264NaluTypePPS) { if(nalu_type == MSH264NaluTypeSPS || nalu_type == MSH264NaluTypePPS) {
parameter_sets = ms_list_append(parameter_sets, nalu); parameter_sets = ms_list_append(parameter_sets, nalu);
} else if(ctx->format_desc || parameter_sets) { } else if(ctx->format_desc || parameter_sets) {
......
#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->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