From 675a831a20fad3912f4341b29fc25a94dfd268b2 Mon Sep 17 00:00:00 2001
From: Steven Liu <lingjiujianke@gmail.com>
Date: Thu, 14 Jul 2016 17:35:11 +0800
Subject: [PATCH] Add bitrate and framerate option for openH264

Signed-off-by: ErLiu <88486969@qq.com>
---
 libavcodec/libopenh264enc.c | 38 ++++++++++++++++++++++++++++++++++++++
 1 file changed, 38 insertions(+)

diff --git a/libavcodec/libopenh264enc.c b/libavcodec/libopenh264enc.c
index 24bc228..f7f11f9 100644
--- a/libavcodec/libopenh264enc.c
+++ b/libavcodec/libopenh264enc.c
@@ -42,6 +42,8 @@ typedef struct SVCContext {
     int skip_frames;
     int skipped;
     int cabac;
+    int bitrate;
+    int framerate;
 } SVCContext;
 
 #define OPENH264_VER_AT_LEAST(maj, min) \
@@ -61,6 +63,8 @@ static const AVOption options[] = {
     { "max_nal_size", "set maximum NAL size in bytes", OFFSET(max_nal_size), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, INT_MAX, VE },
     { "allow_skip_frames", "allow skipping frames to hit the target bitrate", OFFSET(skip_frames), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, VE },
     { "cabac", "Enable cabac", OFFSET(cabac), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 1, VE },
+    { "bitrate", "Set bitrate", OFFSET(bitrate), AV_OPT_TYPE_INT, { 0 }, 0, 700000, VE },
+    { "framerate", "Set framerate", OFFSET(framerate), AV_OPT_TYPE_INT, { 0 }, 0, 30, VE },
     { NULL }
 };
 
@@ -244,6 +248,37 @@ fail:
     return err;
 }
 
+static void check_is_reconfig_framerate(AVCodecContext *avctx)
+{
+    SVCContext *s = avctx->priv_data;
+
+    float m_framerate = 0.0;
+    float n_framerate = (float)s->framerate;
+
+    (*s->encoder)->GetOption(s->encoder, ENCODER_OPTION_FRAME_RATE, &m_framerate);
+
+    if (n_framerate > 0.0 && m_framerate != n_framerate ) {
+        (*s->encoder)->SetOption(s->encoder, ENCODER_OPTION_FRAME_RATE, &n_framerate);
+        av_log(avctx, AV_LOG_ERROR, "framerate:%f---->%f\n", m_framerate, n_framerate);
+    }
+
+}
+static void check_is_reconfig_bitrate(AVCodecContext *avctx)
+{
+    SVCContext *s = avctx->priv_data;
+
+    SBitrateInfo SB;
+
+    SB.iLayer = 0;
+    (*s->encoder)->GetOption(s->encoder, ENCODER_OPTION_BITRATE, &SB);
+
+    if (s->bitrate > 0 && SB.iBitrate != s->bitrate ) {
+        av_log(avctx, AV_LOG_ERROR, "bitrate:%d---->%d\n", SB.iBitrate, s->bitrate);
+        SB.iBitrate = s->bitrate;
+       (*s->encoder)->SetOption(s->encoder, ENCODER_OPTION_BITRATE, &SB);
+       (*s->encoder)->SetOption(s->encoder, ENCODER_OPTION_MAX_BITRATE, &SB);
+    }
+}
 static int svc_encode_frame(AVCodecContext *avctx, AVPacket *avpkt,
                             const AVFrame *frame, int *got_packet)
 {
@@ -263,6 +298,9 @@ static int svc_encode_frame(AVCodecContext *avctx, AVPacket *avpkt,
     sp.iPicWidth  = avctx->width;
     sp.iPicHeight = avctx->height;
 
+    check_is_reconfig_framerate( avctx );
+    check_is_reconfig_bitrate( avctx );
+
     encoded = (*s->encoder)->EncodeFrame(s->encoder, &sp, &fbi);
     if (encoded != cmResultSuccess) {
         av_log(avctx, AV_LOG_ERROR, "EncodeFrame failed\n");
-- 
2.7.4 (Apple Git-66)

