├── .gitignore ├── README.md ├── bld └── android │ └── jni │ ├── Android.mk │ └── Application.mk └── src ├── TestCodec.cpp ├── ffcodec.cpp ├── ffcodec.h ├── ffdecoder.cpp ├── ffdecoder.h ├── ffencoder.cpp ├── ffencoder.h ├── ffheader.h ├── fflog.h └── ffparam.h /.gitignore: -------------------------------------------------------------------------------- 1 | obj 2 | *.o 3 | *.obj 4 | *.a 5 | *.so 6 | *.lib 7 | *.dll 8 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | FFCodec 2 | ======= 3 | 4 | One audio/video decoder/encoder package for ffmpeg 5 | -------------------------------------------------------------------------------- /bld/android/jni/Android.mk: -------------------------------------------------------------------------------- 1 | ROOT_PATH := $(call my-dir)/../../.. 2 | EXT_PATH := $(ROOT_PATH)/ffmpeg 3 | LOCAL_PATH := $(ROOT_PATH)/src 4 | include $(CLEAR_VARS) 5 | 6 | LOCAL_ARM_MODE := arm 7 | 8 | LOCAL_SRC_FILES:= \ 9 | ffdecoder.cpp \ 10 | ffencoder.cpp \ 11 | ffcodec.cpp 12 | 13 | LOCAL_SHARED_LIBRARIES := 14 | LOCAL_STATIC_LIBRARIES := 15 | 16 | LOCAL_LDLIBS := -llog -L../../libs/armeabi-v7a -lavutil -lavcodec -lavformat -lswscale 17 | 18 | LOCAL_MODULE := ffcodec 19 | 20 | LOCAL_C_INCLUDES := \ 21 | $(LOCAL_PATH) \ 22 | $(EXT_PATH) 23 | 24 | LOCAL_CFLAGS := -DANDROID -Wdeprecated-declarations 25 | 26 | include $(BUILD_SHARED_LIBRARY) 27 | -------------------------------------------------------------------------------- /bld/android/jni/Application.mk: -------------------------------------------------------------------------------- 1 | APP_MODULES := ffcodec 2 | APP_OPTIM := release 3 | APP_ABI := armeabi-v7a 4 | APP_STL := stlport_static 5 | -------------------------------------------------------------------------------- /src/TestCodec.cpp: -------------------------------------------------------------------------------- 1 | int main(int argc, char **argv) 2 | { 3 | return 0; 4 | } 5 | -------------------------------------------------------------------------------- /src/ffcodec.cpp: -------------------------------------------------------------------------------- 1 | #include "ffcodec.h" 2 | 3 | // for video pixel format 4 | typedef struct pix_fmt_entry_t { 5 | enum FFPixelFormat pix_fmt; 6 | enum AVPixelFormat av_pix_fmt; 7 | int bpp; 8 | const char *name; 9 | }pix_fmt_entry_t; 10 | const pix_fmt_entry_t k_pix_fmt_entries[] = { 11 | { FF_PIX_FMT_NONE, AV_PIX_FMT_NONE, 0, "" }, 12 | 13 | { FF_PIX_FMT_I420, AV_PIX_FMT_YUV420P, 12, "I420" }, 14 | { FF_PIX_FMT_RGB24, AV_PIX_FMT_RGB24, 24, "RGB24" }, 15 | { FF_PIX_FMT_BGR24, AV_PIX_FMT_BGR24, 24, "BGR24" }, 16 | { FF_PIX_FMT_NV21, AV_PIX_FMT_NV21, 12, "NV21" }, 17 | }; 18 | 19 | // for video codec id 20 | typedef struct codec_id_entry_t { 21 | enum FFCodecID codec_id; 22 | enum AVCodecID av_codec_id; 23 | const char *fourcc; 24 | }codec_id_entry_t; 25 | const codec_id_entry_t k_codec_id_entries[] = { 26 | { FF_CODEC_ID_MP2, AV_CODEC_ID_MP2, "mp2 " }, 27 | { FF_CODEC_ID_OPUS, AV_CODEC_ID_OPUS, "opus" }, 28 | { FF_CODEC_ID_H264, AV_CODEC_ID_H264, "h264" }, 29 | { FF_CODEC_ID_VP8, AV_CODEC_ID_VP8, "vp8" }, 30 | }; 31 | 32 | // for audio sample format 33 | typedef struct sample_fmt_entry_t { 34 | enum FFSampleFormat sample_fmt; 35 | enum AVSampleFormat av_sample_fmt; 36 | const char *fmt_be, *fmt_le; 37 | } sample_fmt_entry_t; 38 | const sample_fmt_entry_t k_sample_fmt_entries[] = { 39 | { FF_SAMPLE_FMT_NONE, AV_SAMPLE_FMT_NONE, "", ""}, 40 | 41 | { FF_SAMPLE_FMT_U8, AV_SAMPLE_FMT_U8, "u8", "u8" }, 42 | { FF_SAMPLE_FMT_S16, AV_SAMPLE_FMT_S16, "s16be", "s16le" }, 43 | { FF_SAMPLE_FMT_S32, AV_SAMPLE_FMT_S32, "s32be", "s32le" }, 44 | { FF_SAMPLE_FMT_FLT, AV_SAMPLE_FMT_FLT, "f32be", "f32le" }, 45 | { FF_SAMPLE_FMT_DBL, AV_SAMPLE_FMT_DBL, "f64be", "f64le" }, 46 | 47 | { FF_SAMPLE_FMT_U8P, AV_SAMPLE_FMT_U8P, "u8p", "u8p" }, 48 | { FF_SAMPLE_FMT_S16P, AV_SAMPLE_FMT_S16P, "s16pbe", "s16ple" }, 49 | { FF_SAMPLE_FMT_S32P, AV_SAMPLE_FMT_S32P, "s32pbe", "s32ple" }, 50 | { FF_SAMPLE_FMT_FLTP, AV_SAMPLE_FMT_FLTP, "f32pbe", "f32ple" }, 51 | { FF_SAMPLE_FMT_DBLP, AV_SAMPLE_FMT_DBLP, "f64pbe", "f64ple" }, 52 | }; 53 | 54 | 55 | AVPixelFormat GetAVPixelFormat(FFPixelFormat pix_fmt) { 56 | for (int i = 0; i < FF_ARRAY_ELEMS(k_pix_fmt_entries); i++) { 57 | const struct pix_fmt_entry_t *entry = &k_pix_fmt_entries[i]; 58 | if (pix_fmt == entry->pix_fmt) 59 | return entry->av_pix_fmt; 60 | } 61 | return AV_PIX_FMT_NONE; 62 | } 63 | 64 | FFPixelFormat GetFFPixelFormat(AVPixelFormat pix_fmt) { 65 | for (int i = 0; i < FF_ARRAY_ELEMS(k_pix_fmt_entries); i++) { 66 | const struct pix_fmt_entry_t *entry = &k_pix_fmt_entries[i]; 67 | if (pix_fmt == entry->av_pix_fmt) 68 | return entry->pix_fmt; 69 | } 70 | return FF_PIX_FMT_NONE; 71 | } 72 | 73 | AVCodecID GetAVCodecID(FFCodecID codec_id) { 74 | for (int i = 0; i < FF_ARRAY_ELEMS(k_codec_id_entries); i++) { 75 | const struct codec_id_entry_t *entry = &k_codec_id_entries[i]; 76 | if (codec_id == entry->codec_id) 77 | return entry->av_codec_id; 78 | } 79 | return AV_CODEC_ID_NONE; 80 | } 81 | 82 | FFCodecID GetFFCodecID(AVCodecID codec_id) { 83 | for (int i = 0; i < FF_ARRAY_ELEMS(k_codec_id_entries); i++) { 84 | const struct codec_id_entry_t *entry = &k_codec_id_entries[i]; 85 | if (codec_id == entry->av_codec_id) 86 | return entry->codec_id; 87 | } 88 | return FF_CODEC_ID_NONE; 89 | } 90 | 91 | AVSampleFormat GetAVSampleFormat(FFSampleFormat sample_fmt) { 92 | for (int i = 0; i < FF_ARRAY_ELEMS(k_sample_fmt_entries); i++) { 93 | const struct sample_fmt_entry_t *entry = &k_sample_fmt_entries[i]; 94 | if (sample_fmt == entry->sample_fmt) 95 | return entry->av_sample_fmt; 96 | } 97 | return AV_SAMPLE_FMT_NONE; 98 | } 99 | 100 | FFSampleFormat GetFFSampleFormat(AVSampleFormat sample_fmt) { 101 | for (int i = 0; i < FF_ARRAY_ELEMS(k_sample_fmt_entries); i++) { 102 | const struct sample_fmt_entry_t *entry = &k_sample_fmt_entries[i]; 103 | if (sample_fmt == entry->av_sample_fmt) 104 | return entry->sample_fmt; 105 | } 106 | return FF_SAMPLE_FMT_NONE; 107 | } 108 | 109 | 110 | 111 | /* check that a given sample format is supported by the encoder */ 112 | int check_sample_fmt(AVCodec *codec, enum AVSampleFormat sample_fmt) 113 | { 114 | const enum AVSampleFormat *p = codec->sample_fmts; 115 | while (*p != AV_SAMPLE_FMT_NONE) { 116 | if (*p == sample_fmt) 117 | return 1; 118 | p++; 119 | } 120 | return 0; 121 | } 122 | 123 | /* just pick the first supported sample_fmt */ 124 | AVSampleFormat select_sample_fmt(AVCodec *codec) 125 | { 126 | const enum AVSampleFormat *p = codec->sample_fmts; 127 | return *p; 128 | } 129 | 130 | /* check that a given sample rate is supported by the encoder */ 131 | int check_sample_rate(AVCodec *codec, int sample_rate) 132 | { 133 | const int *p; 134 | int best_samplerate = 0; 135 | if (!codec->supported_samplerates){ 136 | if (sample_rate == 44100) 137 | return 1; 138 | return 0; 139 | } 140 | 141 | p = codec->supported_samplerates; 142 | while (*p) { 143 | if (*p == sample_rate) 144 | return 1; 145 | p++; 146 | } 147 | return 0; 148 | } 149 | 150 | /* just pick the highest supported samplerate */ 151 | int select_sample_rate(AVCodec *codec) 152 | { 153 | const int *p; 154 | int best_samplerate = 0; 155 | if (!codec->supported_samplerates) 156 | return 44100; 157 | 158 | p = codec->supported_samplerates; 159 | while (*p) { 160 | best_samplerate = FFMAX(*p, best_samplerate); 161 | p++; 162 | } 163 | return best_samplerate; 164 | } 165 | 166 | /* select layout with the highest channel count */ 167 | int select_channel_layout(AVCodec *codec) 168 | { 169 | const uint64_t *p; 170 | uint64_t best_ch_layout = 0; 171 | int best_nb_channels = 0; 172 | if (!codec->channel_layouts) 173 | return AV_CH_LAYOUT_STEREO; 174 | 175 | p = codec->channel_layouts; 176 | while (*p) { 177 | int nb_channels = av_get_channel_layout_nb_channels(*p); 178 | if (nb_channels > best_nb_channels) { 179 | best_ch_layout = *p; 180 | best_nb_channels = nb_channels; 181 | } 182 | p++; 183 | } 184 | return best_ch_layout; 185 | } 186 | 187 | 188 | 189 | /* check that a given pixel format is supported by the encoder */ 190 | int check_pix_fmt(AVCodec *codec, enum AVPixelFormat pix_fmt) 191 | { 192 | const enum AVPixelFormat *p = codec->pix_fmts; 193 | while (*p != AV_PIX_FMT_NONE) { 194 | if (*p == pix_fmt) 195 | return 1; 196 | p++; 197 | } 198 | return 0; 199 | } 200 | 201 | /* just pick the first supported pix_fmt */ 202 | AVPixelFormat select_pix_fmt(AVCodec *codec) 203 | { 204 | const enum AVPixelFormat *p = codec->pix_fmts; 205 | return *p; 206 | } 207 | 208 | -------------------------------------------------------------------------------- /src/ffcodec.h: -------------------------------------------------------------------------------- 1 | #ifndef __FFCODEC_H_ 2 | #define __FFCODEC_H_ 3 | 4 | #include "ffparam.h" 5 | 6 | class FFCodec { 7 | public: 8 | explicit FFCodec(FFMediaType type) { 9 | mtype = type; 10 | codec = NULL; 11 | avctx = NULL; 12 | frame = NULL; 13 | frame2 = NULL; 14 | swsctx = NULL; 15 | } 16 | 17 | virtual ~FFCodec() { 18 | codec = NULL; 19 | if (avctx) { 20 | avcodec_close(avctx); 21 | av_free(avctx); 22 | avctx = NULL; 23 | } 24 | if (frame) { 25 | av_frame_free(&frame); 26 | frame = NULL; 27 | } 28 | if (frame2) { 29 | av_frame_free(&frame2); 30 | frame2 = NULL; 31 | } 32 | if (swsctx) { 33 | sws_freeContext(swsctx); 34 | swsctx = NULL; 35 | } 36 | } 37 | 38 | public: 39 | FFMediaType mtype; 40 | 41 | AVCodec *codec; 42 | AVCodecContext *avctx; 43 | AVFrame *frame; // for pre-allocated buffer 44 | AVFrame *frame2; // for self-allocated buffer 45 | AVPacket avpkt; 46 | SwsContext *swsctx; 47 | }; 48 | 49 | 50 | #define safe_delete_codec(p) do {if(p) delete (FFCodec *)p; p = NULL;}while(0) 51 | 52 | // for const variables 53 | AVPixelFormat GetAVPixelFormat(FFPixelFormat pix_fmt); 54 | FFPixelFormat GetFFPixelFormat(AVPixelFormat pix_fmt); 55 | 56 | AVCodecID GetAVCodecID(FFCodecID codec_id); 57 | FFCodecID GetFFCodecID(AVCodecID codec_id); 58 | 59 | AVSampleFormat GetAVSampleFormat(FFSampleFormat fmt); 60 | FFSampleFormat GetFFSampleFormat(AVSampleFormat fmt); 61 | 62 | // for audio codec 63 | int check_sample_fmt(AVCodec *codec, enum AVSampleFormat sample_fmt); 64 | AVSampleFormat select_sample_fmt(AVCodec *codec); 65 | int select_channel_layout(AVCodec *codec); 66 | int check_sample_rate(AVCodec *codec, int sample_rate); 67 | int select_sample_rate(AVCodec *codec); 68 | 69 | // for video codec 70 | int check_pix_fmt(AVCodec *codec, enum AVPixelFormat pix_fmt); 71 | AVPixelFormat select_pix_fmt(AVCodec *codec); 72 | 73 | 74 | #endif // __FFCODEC_H_ 75 | 76 | -------------------------------------------------------------------------------- /src/ffdecoder.cpp: -------------------------------------------------------------------------------- 1 | #include "ffdecoder.h" 2 | #include "fflog.h" 3 | #include "ffcodec.h" 4 | 5 | FFDecoder::FFDecoder() { 6 | m_video = NULL; 7 | m_audio = NULL; 8 | m_vfmt.reset(); 9 | } 10 | 11 | FFDecoder::~FFDecoder() { 12 | closeVideo(); 13 | closeAudio(); 14 | } 15 | 16 | long FFDecoder::openCodec(ff_codec_t codec, FFCodecID codec_id) { 17 | FFCodec *pCodec = (FFCodec *)codec; 18 | returnv_if_fail(pCodec, -1); 19 | 20 | AVCodecID av_codec_id = GetAVCodecID(codec_id); 21 | returnv_if_fail(av_codec_id != AV_CODEC_ID_NONE, -1); 22 | 23 | pCodec->codec = avcodec_find_decoder(av_codec_id); 24 | returnv_if_fail(pCodec->codec, -1); 25 | 26 | pCodec->avctx = avcodec_alloc_context3(pCodec->codec); 27 | returnv_if_fail(pCodec->avctx, -1); 28 | 29 | int iret = avcodec_open2(pCodec->avctx, pCodec->codec, NULL); 30 | returnv_if_fail(iret == 0, -1); 31 | 32 | pCodec->frame = av_frame_alloc(); 33 | av_init_packet(&pCodec->avpkt); 34 | return 0; 35 | } 36 | 37 | long FFDecoder::openVideo(FFCodecID codec_id) { 38 | returnv_if_fail(!m_video, 1); // has been opened 39 | m_video = (ff_codec_t)new FFCodec(FF_MEDIA_VIDEO); 40 | returnv_if_fail(m_video, -1); 41 | m_vfmt.reset(); 42 | 43 | long lret = openCodec(m_video, codec_id); 44 | if (lret != 0) { 45 | safe_delete_codec(m_video); 46 | LOGE("fail to open ff_codec_id="<codec = avcodec_find_encoder(av_codec_id); 24 | returnv_if_fail(pCodec->codec, -1); 25 | 26 | pCodec->avctx = avcodec_alloc_context3(pCodec->codec); 27 | returnv_if_fail(pCodec->avctx, -1); 28 | 29 | return 0; 30 | } 31 | long FFEncoder::openCodec(ff_codec_t codec, const FFVideoFormat &fmt) { 32 | FFCodec *pCodec = (FFCodec *)codec; 33 | returnv_if_fail(pCodec, -1); 34 | returnv_if_fail(pCodec->avctx, -1); 35 | 36 | pCodec->avctx->bit_rate = fmt.bitrate; 37 | pCodec->avctx->width = fmt.width; 38 | pCodec->avctx->height = fmt.height; 39 | pCodec->avctx->time_base = (AVRational){1,fmt.fps}; 40 | pCodec->avctx->gop_size = fmt.data.gop_size; 41 | pCodec->avctx->max_b_frames = fmt.data.max_b_frames; 42 | 43 | AVPixelFormat pix_fmt = GetAVPixelFormat(fmt.pix_fmt); 44 | if (!check_pix_fmt(pCodec->codec, pix_fmt)) { 45 | pCodec->avctx->pix_fmt = select_pix_fmt(pCodec->codec); 46 | LOGW("unsupported (ff_pix_fmt="<avctx, pCodec->codec, NULL); 58 | returnv_if_fail(iret == 0, -1); 59 | 60 | av_init_packet(&pCodec->avpkt); 61 | pCodec->avpkt.data = NULL; 62 | pCodec->avpkt.size = 0; 63 | return 0; 64 | } 65 | long FFEncoder::openCodec(ff_codec_t codec, const FFAudioFormat &fmt) { 66 | FFCodec *pCodec = (FFCodec *)codec; 67 | returnv_if_fail(pCodec, -1); 68 | returnv_if_fail(pCodec->avctx, -1); 69 | 70 | pCodec->avctx->bit_rate = fmt.bitrate; 71 | 72 | AVSampleFormat sample_fmt = GetAVSampleFormat(fmt.sample_fmt); 73 | if (!check_sample_fmt(pCodec->codec, pCodec->avctx->sample_fmt)) { 74 | pCodec->avctx->sample_fmt = select_sample_fmt(pCodec->codec); 75 | LOGW("unsupported (ff_sample_fmt="< 54 | 55 | 56 | #endif // __FFHEADER_H_ 57 | 58 | -------------------------------------------------------------------------------- /src/fflog.h: -------------------------------------------------------------------------------- 1 | #ifndef __FFLOG_H_ 2 | #define __FFLOG_H_ 3 | 4 | #include 5 | 6 | #ifdef ANDROID 7 | #include 8 | #endif 9 | 10 | 11 | // enable/disable log 12 | #define FF_ENABLE_LOG 0 13 | 14 | #ifndef return_if_fail 15 | #define return_if_fail(p) do{if(!(p)) return;}while(0) 16 | #endif 17 | 18 | #ifndef returnv_if_fail 19 | #define returnv_if_fail(p, v) do{if(!(p)) return(v);}while(0) 20 | #endif 21 | 22 | #ifndef safe_delete 23 | #define safe_delete(p) do{if(p) {delete (p); (p) = NULL;}}while(0) 24 | #endif 25 | 26 | 27 | enum { 28 | FF_LOG_DEBUG = 0x01, 29 | FF_LOG_INFO = 0x02, 30 | FF_LOG_WARN = 0x04, 31 | FF_LOG_ERROR = 0x08, 32 | }; 33 | 34 | #ifndef __FUNC__ 35 | #if defined (__GNUC__) 36 | # define __FUNC__ ((const char*) (__PRETTY_FUNCTION__)) 37 | #elif defined (__STDC_VERSION__) && __STDC_VERSION__ >= 19901L 38 | # define __FUNC__ ((const char*) (__func__)) 39 | #else 40 | # define __FUNC__ ((const char*) (__FUNCTION__)) 41 | #endif 42 | #endif 43 | 44 | #if FF_ENABLE_LOG 45 | # define __FF_TAG "FFCODEC" 46 | # define LOGD(str) __LOG_PRINT(FF_LOG_DEBUG, __FF_TAG, str) 47 | # define LOGI(str) __LOG_PRINT(FF_LOG_INFO, __FF_TAG, str) 48 | # define LOGW(str) __LOG_PRINT(FF_LOG_WARN, __FF_TAG, str) 49 | # define LOGE(str) __LOG_PRINT(FF_LOG_ERROR, __FF_TAG, str) 50 | # define __LOG_PRINT(level, tag, str) \ 51 | do { \ 52 | std::stringstream ssteam; \ 53 | sstream << __FUNC__ << "[#" << __LINE__ << "]: "; \ 54 | sstream << str; \ 55 | __ff_log_print(level, tag, ssteam.str()); \ 56 | }while(0) 57 | #else 58 | # define LOGD(str) 59 | # define LOGI(str) 60 | # define LOGW(str) 61 | # define LOGE(str) 62 | #endif 63 | 64 | void __ff_log_print(int level, const char *tag, const std::string &str) { 65 | #ifdef ANDROID 66 | int androidLevel = ANDROID_LOG_DEBUG; 67 | switch(level) { 68 | case FF_LOG_DEBUG: 69 | androidLevel = ANDROID_LOG_DEBUG; 70 | break; 71 | case FF_LOG_INFO: 72 | androidLevel = ANDROID_LOG_INFO; 73 | break; 74 | case FF_LOG_WARN: 75 | androidLevel = ANDROID_LOG_WARN; 76 | break; 77 | case FF_LOG_ERROR: 78 | androidLevel = ANDROID_LOG_ERROR; 79 | break; 80 | default: 81 | return; 82 | } 83 | __android_log_write(androidLevel, tag, str.c_str()); 84 | #else 85 | std::string szHead = ""; 86 | switch(level) { 87 | case FF_LOG_DEBUG: 88 | szHead = "DEBUG"; 89 | break; 90 | case FF_LOG_INFO: 91 | szHead = "INFO"; 92 | break; 93 | case FF_LOG_WARN: 94 | szHead = "WARN"; 95 | break; 96 | case FF_LOG_ERROR: 97 | szHead = "ERROR"; 98 | break; 99 | default: 100 | return; 101 | } 102 | fprintf(stdout, "[%s][%s] %s\n", tag, szHead.c_str(), str.c_str()); 103 | #endif 104 | } 105 | 106 | 107 | #endif // __FFLOG_H_ 108 | 109 | -------------------------------------------------------------------------------- /src/ffparam.h: -------------------------------------------------------------------------------- 1 | #ifndef __FFPARAM_H_ 2 | #define __FFPARAM_H_ 3 | 4 | #include "ffheader.h" 5 | 6 | typedef void * ff_codec_t; 7 | 8 | enum FFMediaType { 9 | FF_MEDIA_VIDEO, 10 | FF_MEDIA_AUDIO, 11 | }; 12 | 13 | enum FFPixelFormat { 14 | FF_PIX_FMT_NONE = -1, 15 | FF_PIX_FMT_I420, 16 | FF_PIX_FMT_RGB24, 17 | FF_PIX_FMT_BGR24, 18 | FF_PIX_FMT_NV21, 19 | 20 | FF_PIX_FMT_NB 21 | }; 22 | 23 | enum FFSampleFormat { 24 | FF_SAMPLE_FMT_NONE = -1, 25 | FF_SAMPLE_FMT_U8, // pcm u8 26 | FF_SAMPLE_FMT_S16, // pcm s16 27 | FF_SAMPLE_FMT_S32, // pcm s32 28 | FF_SAMPLE_FMT_FLT, // pcm float 29 | FF_SAMPLE_FMT_DBL, // pcm double 30 | 31 | // planar 32 | FF_SAMPLE_FMT_U8P, 33 | FF_SAMPLE_FMT_S16P, 34 | FF_SAMPLE_FMT_S32P, 35 | FF_SAMPLE_FMT_FLTP, 36 | FF_SAMPLE_FMT_DBLP, 37 | 38 | FF_SAMPLE_FMT_NB // Number of sample formats 39 | }; 40 | 41 | enum FFCodecID { 42 | FF_CODEC_ID_NONE, 43 | 44 | FF_CODEC_ID_OPUS, 45 | FF_CODEC_ID_MP2, 46 | 47 | FF_CODEC_ID_MJPG, 48 | FF_CODEC_ID_VP8, 49 | FF_CODEC_ID_H264, 50 | 51 | FF_CODEC_ID_NB 52 | }; 53 | 54 | 55 | class FFAudioFormat { 56 | public: 57 | FFAudioFormat() { 58 | reset(); 59 | } 60 | FFAudioFormat(int sample_rate, FFSampleFormat sample_fmt, int channels, int bitrate) { 61 | set(sample_rate, sample_fmt, channels, bitrate); 62 | } 63 | void reset() { 64 | set(0, FF_SAMPLE_FMT_NONE, 0, 0); 65 | } 66 | void set(int sample_rate, FFSampleFormat sample_fmt, int channels, int bitrate) { 67 | this->sample_rate = sample_rate; 68 | this->sample_fmt = sample_fmt; 69 | this->channels = channels; 70 | this->bitrate = bitrate; 71 | } 72 | 73 | public: 74 | int sample_rate; 75 | int channels; 76 | int bitrate; 77 | FFSampleFormat sample_fmt; 78 | }; 79 | 80 | class FFVideoFormat { 81 | public: 82 | FFVideoFormat() { 83 | reset(); 84 | } 85 | FFVideoFormat(int width, int height, FFPixelFormat pix_fmt, int bitrate, int fps) { 86 | set(width, height, pix_fmt, bitrate, fps); 87 | } 88 | void reset() { 89 | set(0, 0, FF_PIX_FMT_NONE, 0, 0); 90 | } 91 | void set(int width, int height, FFPixelFormat pix_fmt, int bitrate, int fps) { 92 | this->width = width; 93 | this->height = height; 94 | this->pix_fmt = pix_fmt; 95 | this->bitrate = bitrate; 96 | this->fps = fps; 97 | } 98 | 99 | public: 100 | struct CodecData { 101 | CodecData() { 102 | gop_size = 0; 103 | max_b_frames = 0; 104 | } 105 | int gop_size; 106 | int max_b_frames; 107 | }; 108 | 109 | public: 110 | int width; 111 | int height; 112 | FFPixelFormat pix_fmt; 113 | int bitrate; 114 | int fps; 115 | CodecData data; 116 | }; 117 | 118 | #endif // __FFPARAM_H_ 119 | 120 | --------------------------------------------------------------------------------