From 30e62bbdfb63692350f3ec664b61885a1e09b2c9 Mon Sep 17 00:00:00 2001 From: nareix Date: Sat, 16 Jul 2016 12:36:21 +0800 Subject: [PATCH] ffmpeg: add Bitrate and profile --- cgo/ffmpeg/audio.go | 28 ++++++++++++++++++++++------ cgo/ffmpeg/ffmpeg.go | 1 + cgo/ffmpeg/ffmpeg.h | 9 +++++++++ 3 files changed, 32 insertions(+), 6 deletions(-) diff --git a/cgo/ffmpeg/audio.go b/cgo/ffmpeg/audio.go index 0d2a6d8..ee05a56 100644 --- a/cgo/ffmpeg/audio.go +++ b/cgo/ffmpeg/audio.go @@ -157,7 +157,7 @@ func (self *Resampler) Close() { type AudioEncoder struct { ff *ffctx SampleRate int - BitRate int + Bitrate int ChannelLayout av.ChannelLayout SampleFormat av.SampleFormat FrameSampleCount int @@ -233,10 +233,25 @@ func (self *AudioEncoder) SetChannelLayout(ch av.ChannelLayout) (err error) { return } +func (self *AudioEncoder) SetBitrate(bitrate int) (err error) { + self.Bitrate = bitrate + return +} + func (self *AudioEncoder) SetOption(key string, val interface{}) (err error) { ff := &self.ff.ff - s := fmt.Sprint(val) - C.av_dict_set(&ff.options, C.CString(key), C.CString(s), 0) + + sval := fmt.Sprint(val) + if key == "profile" { + ff.profile = C.avcodec_profile_name_to_int(ff.codec, C.CString(sval)) + if ff.profile == C.FF_PROFILE_UNKNOWN { + err = fmt.Errorf("ffmpeg: profile `%s` invalid", sval) + return + } + return + } + + C.av_dict_set(&ff.options, C.CString(key), C.CString(sval), 0) return } @@ -268,8 +283,8 @@ func (self *AudioEncoder) Setup() (err error) { self.SampleFormat = sampleFormatFF2AV(*ff.codec.sample_fmts) } - if self.BitRate == 0 { - self.BitRate = 80000 + if self.Bitrate == 0 { + self.Bitrate = 80000 } if self.SampleRate == 0 { self.SampleRate = 44100 @@ -280,10 +295,11 @@ func (self *AudioEncoder) Setup() (err error) { ff.codecCtx.sample_fmt = sampleFormatAV2FF(self.SampleFormat) ff.codecCtx.sample_rate = C.int(self.SampleRate) - ff.codecCtx.bit_rate = C.int64_t(self.BitRate) + ff.codecCtx.bit_rate = C.int64_t(self.Bitrate) ff.codecCtx.channel_layout = channelLayoutAV2FF(self.ChannelLayout) ff.codecCtx.strict_std_compliance = C.FF_COMPLIANCE_EXPERIMENTAL ff.codecCtx.flags = C.AV_CODEC_FLAG_GLOBAL_HEADER + ff.codecCtx.profile = ff.profile if C.avcodec_open2(ff.codecCtx, ff.codec, nil) != 0 { err = fmt.Errorf("ffmpeg: encoder: avcodec_open2 failed") diff --git a/cgo/ffmpeg/ffmpeg.go b/cgo/ffmpeg/ffmpeg.go index 42de7d1..e8836ca 100644 --- a/cgo/ffmpeg/ffmpeg.go +++ b/cgo/ffmpeg/ffmpeg.go @@ -52,6 +52,7 @@ func newFFCtxByCodec(codec *C.AVCodec) (ff *ffctx, err error) { ff = &ffctx{} ff.ff.codec = codec ff.ff.codecCtx = C.avcodec_alloc_context3(codec) + ff.ff.profile = C.FF_PROFILE_UNKNOWN runtime.SetFinalizer(ff, freeFFCtx) return } diff --git a/cgo/ffmpeg/ffmpeg.h b/cgo/ffmpeg/ffmpeg.h index 46c874a..e5f2a10 100644 --- a/cgo/ffmpeg/ffmpeg.h +++ b/cgo/ffmpeg/ffmpeg.h @@ -11,5 +11,14 @@ typedef struct { AVCodecContext *codecCtx; AVFrame *frame; AVDictionary *options; + int profile; } FFCtx; +static inline int avcodec_profile_name_to_int(AVCodec *codec, const char *name) { + const AVProfile *p; + for (p = codec->profiles; p != NULL && p->profile != FF_PROFILE_UNKNOWN; p++) + if (!strcmp(p->name, name)) + return p->profile; + return FF_PROFILE_UNKNOWN; +} +