Commit b96e8f74 authored by Simon Morlat's avatar Simon Morlat

i frame limiter rework

parent 5ee74b0a
...@@ -31,8 +31,6 @@ static int debugLevel = 1; ...@@ -31,8 +31,6 @@ static int debugLevel = 1;
#endif #endif
static const int MIN_KEY_FRAME_DIST = 4;
#if defined(ANDROID) || (TARGET_OS_IPHONE == 1) || defined(__arm__) #if defined(ANDROID) || (TARGET_OS_IPHONE == 1) || defined(__arm__)
#define MS_OPENH264_CONF(required_bitrate, bitrate_limit, resolution, fps_pc, cpus_pc, fps_mobile, cpus_mobile) \ #define MS_OPENH264_CONF(required_bitrate, bitrate_limit, resolution, fps_pc, cpus_pc, fps_mobile, cpus_mobile) \
...@@ -146,7 +144,7 @@ void MSOpenH264Encoder::initialize() ...@@ -146,7 +144,7 @@ void MSOpenH264Encoder::initialize()
if (!mAVPFEnabled && (mFrameCount == 0)) { if (!mAVPFEnabled && (mFrameCount == 0)) {
ms_video_starter_init(&mVideoStarter); ms_video_starter_init(&mVideoStarter);
} }
ms_iframe_requests_limiter_init(&mIFrameLimiter, mFilter->ticker, 1000); ms_iframe_requests_limiter_init(&mIFrameLimiter, 1000);
} }
void MSOpenH264Encoder::feed() void MSOpenH264Encoder::feed()
...@@ -165,6 +163,8 @@ void MSOpenH264Encoder::feed() ...@@ -165,6 +163,8 @@ void MSOpenH264Encoder::feed()
while ((im = ms_queue_get(mFilter->inputs[0])) != NULL) { while ((im = ms_queue_get(mFilter->inputs[0])) != NULL) {
MSPicture pic; MSPicture pic;
if (ms_yuv_buf_init_from_mblk(&pic, im) == 0) { if (ms_yuv_buf_init_from_mblk(&pic, im) == 0) {
bool generateKeyFrame = false;
SFrameBSInfo sFbi = { 0 }; SFrameBSInfo sFbi = { 0 };
SSourcePicture srcPic = { 0 }; SSourcePicture srcPic = { 0 };
srcPic.iColorFormat = videoFormatI420; srcPic.iColorFormat = videoFormatI420;
...@@ -176,14 +176,20 @@ void MSOpenH264Encoder::feed() ...@@ -176,14 +176,20 @@ void MSOpenH264Encoder::feed()
} }
srcPic.uiTimeStamp = ts; srcPic.uiTimeStamp = ts;
if (!mAVPFEnabled && ms_video_starter_need_i_frame(&mVideoStarter, mFilter->ticker->time)) { if (!mAVPFEnabled && ms_video_starter_need_i_frame(&mVideoStarter, mFilter->ticker->time)) {
generateKeyframe(); generateKeyFrame = true;
} }
if (ms_iframe_requests_limiter_iframe_requested(&mIFrameLimiter, mFilter->ticker->time)){
generateKeyFrame = true;
}
if (generateKeyFrame){
generateKeyframe();
}
int ret = mEncoder->EncodeFrame(&srcPic, &sFbi); int ret = mEncoder->EncodeFrame(&srcPic, &sFbi);
if (ret == cmResultSuccess) { if (ret == cmResultSuccess) {
if ((sFbi.eFrameType != videoFrameTypeSkip) && (sFbi.eFrameType != videoFrameTypeInvalid)) { if ((sFbi.eFrameType != videoFrameTypeSkip) && (sFbi.eFrameType != videoFrameTypeInvalid)) {
if (sFbi.eFrameType == videoFrameTypeIDR) { if (sFbi.eFrameType == videoFrameTypeIDR) {
mLastIDRFrameCount = mFrameCount;
ms_iframe_requests_limiter_notify_iframe_sent(&mIFrameLimiter); ms_iframe_requests_limiter_notify_iframe_sent(&mIFrameLimiter);
ms_message("MSOpenH264Encoder: sending IDR"); ms_message("MSOpenH264Encoder: sending IDR");
} }
...@@ -283,55 +289,31 @@ void MSOpenH264Encoder::requestVFU() ...@@ -283,55 +289,31 @@ void MSOpenH264Encoder::requestVFU()
// If we receive a VFU request, stop the video starter // If we receive a VFU request, stop the video starter
ms_video_starter_deactivate(&mVideoStarter); ms_video_starter_deactivate(&mVideoStarter);
ms_filter_lock(mFilter); ms_filter_lock(mFilter);
ms_iframe_requests_limiter_require_iframe(&mIFrameLimiter); ms_iframe_requests_limiter_request_iframe(&mIFrameLimiter);
ms_filter_unlock(mFilter); ms_filter_unlock(mFilter);
generateKeyframe();
} }
void MSOpenH264Encoder::notifyPLI() void MSOpenH264Encoder::notifyPLI()
{ {
ms_message("OpenH264: PLI requested"); ms_message("OpenH264: PLI requested");
if (shouldGenerateKeyframe(MIN_KEY_FRAME_DIST)) { requestVFU();
ms_message("OpenH264: PLI accepted");
ms_filter_lock(mFilter);
ms_iframe_requests_limiter_require_iframe(&mIFrameLimiter);
ms_filter_unlock(mFilter);
generateKeyframe();
}
} }
void MSOpenH264Encoder::notifyFIR(uint8_t seqnr) void MSOpenH264Encoder::notifyFIR(uint8_t seqnr)
{ {
if (seqnr != mLastFIRSeqNr) { requestVFU();
ms_filter_lock(mFilter);
ms_iframe_requests_limiter_require_iframe(&mIFrameLimiter);
ms_filter_unlock(mFilter);
mLastFIRSeqNr = seqnr;
generateKeyframe();
}
} }
void MSOpenH264Encoder::generateKeyframe() void MSOpenH264Encoder::generateKeyframe()
{ {
if (isInitialized()) { int ret=0;
ms_filter_lock(mFilter); if (mFrameCount>0){
int ret=0; ret = mEncoder->ForceIntraFrame(true);
if (mFrameCount>0){ }else ms_message("ForceIntraFrame() ignored since no frame has been generated yet.");
if(ms_iframe_requests_limiter_iframe_sending_authorized(&mIFrameLimiter)) {
ret = mEncoder->ForceIntraFrame(true);
}
}else ms_message("ForceIntraFrame() ignored since no frame has been generated yet.");
ms_filter_unlock(mFilter);
if (ret != 0) {
ms_error("OpenH264 encoder: Failed forcing intra-frame: %d", ret);
}
}
}
bool MSOpenH264Encoder::shouldGenerateKeyframe(int frameDist) if (ret != 0) {
{ ms_error("OpenH264 encoder: Failed forcing intra-frame: %d", ret);
if (mFrameCount > mLastIDRFrameCount + frameDist) return true; }
return false;
} }
void MSOpenH264Encoder::fillNalusQueue(SFrameBSInfo &sFbi, MSQueue *nalus) void MSOpenH264Encoder::fillNalusQueue(SFrameBSInfo &sFbi, MSQueue *nalus)
......
...@@ -52,7 +52,6 @@ public: ...@@ -52,7 +52,6 @@ public:
private: private:
void generateKeyframe(); void generateKeyframe();
bool shouldGenerateKeyframe(int frameDist);
void fillNalusQueue(SFrameBSInfo& sFbi, MSQueue* nalus); void fillNalusQueue(SFrameBSInfo& sFbi, MSQueue* nalus);
void calcBitrates(int &targetBitrate, int &maxBitrate) const; void calcBitrates(int &targetBitrate, int &maxBitrate) const;
void applyBitrate(); void applyBitrate();
...@@ -66,9 +65,7 @@ private: ...@@ -66,9 +65,7 @@ private:
MSVideoStarter mVideoStarter; MSVideoStarter mVideoStarter;
MSIFrameRequestsLimiterCtx mIFrameLimiter; MSIFrameRequestsLimiterCtx mIFrameLimiter;
uint64_t mFrameCount; uint64_t mFrameCount;
uint64_t mLastIDRFrameCount;
bool mInitialized; bool mInitialized;
bool mPacketisationModeSet; bool mPacketisationModeSet;
bool mAVPFEnabled; bool mAVPFEnabled;
int mLastFIRSeqNr;
}; };
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