FFMPEGæ¯ç®å被åºç¨æ广æ³çç¼è§£ç 软件åºï¼æ¯æå¤ç§æµè¡çç¼è§£ç å¨ï¼å®æ¯Cè¯è¨å®ç°çï¼ä¸ä»
被éæå°åç§PC软件ï¼ä¹ç»å¸¸è¢«ç§»æ¤å°å¤ç§åµå
¥å¼è®¾å¤ä¸ã使ç¨é¢å对象çåæ³æ¥è®¾æ³è¿æ ·ä¸ä¸ªç¼è§£ç åºï¼é¦å
让人æ³å°çæ¯æé åç§ç¼è§£ç å¨çç±»ï¼ç¶å对äºå®ä»¬çæ½è±¡åºç±»ç¡®å®è¿è¡æ°æ®æµçè§åï¼æ ¹æ®ç®æ³è½¬æ¢è¾å
¥è¾åºå¯¹è±¡ã
å¨å®é
ç代ç ï¼å°è¿äºç¼è§£ç å¨åæencoder/decoderï¼muxer/demuxerådeviceä¸ç§å¯¹è±¡ï¼åå«å¯¹åºäºç¼è§£ç ï¼è¾å
¥è¾åºæ ¼å¼å设å¤ãå¨mainå½æ°çå¼å§ï¼å°±æ¯åå§åè¿ä¸ç±»å¯¹è±¡ãå¨avcodec_register_allä¸ï¼å¾å¤ç¼è§£ç å¨è¢«æ³¨åï¼å
æ¬è§é¢çH.264解ç å¨åX264ç¼ç å¨çï¼
REGISTER_DECODER (H264, h264);
REGISTER_ENCODER (LIBX264, libx264);
æ¾å°ç¸å
³çå®ä»£ç å¦ä¸
#define REGISTER_ENCODER(X,x) { /
extern AVCodec x##_encoder; /
if(CONFIG_##X##_ENCODER) avcodec_register(&x##_encoder); }
#define REGISTER_DECODER(X,x) { /
extern AVCodec x##_decoder; /
if(CONFIG_##X##_DECODER) avcodec_register(&x##_decoder); }
è¿æ ·å°±å®é
å¨ä»£ç ä¸æ ¹æ®CONFIG_##X##_ENCODERè¿æ ·çç¼è¯é项æ¥æ³¨ålibx264_encoderåh264_decoderï¼æ³¨åçè¿ç¨åçå¨avcodec_register(AVCodec *codec)å½æ°ä¸ï¼å®é
ä¸å°±æ¯åå
¨å±é¾è¡¨first_avcodecä¸å å
¥libx264_encoderãh264_decoderç¹å®çç¼è§£ç å¨ï¼è¾å
¥åæ°AVCodecæ¯ä¸ä¸ªç»æä½ï¼å¯ä»¥ç解为ç¼è§£ç å¨çåºç±»ï¼å
¶ä¸ä¸ä»
å
å«äºå称ï¼idçå±æ§ï¼èä¸å
å«äºå¦ä¸å½æ°æéï¼è®©æ¯ä¸ªå
·ä½çç¼è§£ç å¨æ©å±ç±»å®ç°ã
int (*init)(AVCodecContext *);
int (*encode)(AVCodecContext *, uint8_t *buf, int buf_size, void *data);
int (*close)(AVCodecContext *);
int (*decode)(AVCodecContext *, void *outdata, int *outdata_size,
const uint8_t *buf, int buf_size);
void (*flush)(AVCodecContext *);
继ç»è¿½è¸ªlibx264ï¼ä¹å°±æ¯X264çéæç¼ç åºï¼å®å¨FFMPEGç¼è¯çæ¶å被å¼å
¥ä½ä¸ºH.264ç¼ç å¨ãå¨libx264.cä¸æå¦ä¸ä»£ç
AVCodec libx264_encoder = {
.name = "libx264",
.type = CODEC_TYPE_VIDEO,
.id = CODEC_ID_H264,
.priv_data_size = sizeof(X264Context),
.init = X264_init,
.encode = X264_frame,
.close = X264_close,
.capabilities = CODEC_CAP_DELAY,
.pix_fmts = (enum PixelFormat[]) { PIX_FMT_YUV420P, PIX_FMT_NONE },
.long_name = NULL_IF_CONFIG_SMALL("libx264 H.264 / AVC / MPEG-4 AVC / MPEG-4 part 10"),
};
è¿éå
·ä½å¯¹æ¥èªAVCodecå¾å±æ§åæ¹æ³èµå¼ãå
¶ä¸
.init = X264_init,
.encode = X264_frame,
.close = X264_close,
å°å½æ°æéæåäºå
·ä½å½æ°ï¼è¿ä¸ä¸ªå½æ°å°ä½¿ç¨libx264éæåºä¸æä¾çAPIï¼ä¹å°±æ¯X264ç主è¦æ¥å£å½æ°è¿è¡å
·ä½å®ç°ãpix_fmtså®ä¹äºææ¯æçè¾å
¥æ ¼å¼ï¼è¿é4ï¼2ï¼0
PIX_FMT_YUV420P, ///< planar YUV 4:2:0, 12bpp, (1 Cr & Cb sample per 2x2 Y samples)
ä¸é¢çå°çX264Contextå°è£
äºX264æéè¦çä¸ä¸æ管çæ°æ®ï¼
typedef struct X264Context {
x264_param_t params;
x264_t *enc;
x264_picture_t pic;
AVFrame out_pic;
} X264Context;
å®å±äºç»æä½AVCodecContextçvoid *priv_dataåéï¼å®ä¹äºæ¯ç§ç¼è§£ç å¨ç§æçä¸ä¸æå±æ§ï¼AVCodecContextä¹ç±»ä¼¼ä¸ä¸æåºç±»ä¸æ ·ï¼è¿æä¾å
¶ä»è¡¨ç¤ºå±å¹è§£æçãéåèå´ççä¸ä¸æå±æ§årtp_callbackçå½æ°æéä¾ç¼è§£ç 使ç¨ã
åå°mainå½æ°ï¼å¯ä»¥çå°å®æäºåç±»ç¼è§£ç å¨ï¼è¾å
¥è¾åºæ ¼å¼å设å¤æ³¨å以åï¼å°è¿è¡ä¸ä¸æåå§ååç¼è§£ç åæ°è¯»å
¥ï¼ç¶åè°ç¨av_encodeï¼ï¼å½æ°è¿è¡å
·ä½çç¼è§£ç å·¥ä½ãæ ¹æ®è¯¥å½æ°ç注éä¸è·¯æ¥çå
¶è¿ç¨ï¼
1. è¾å
¥è¾åºæµåå§åã
2. æ ¹æ®è¾å
¥è¾åºæµç¡®å®éè¦çç¼è§£ç å¨ï¼å¹¶åå§åã
3. åè¾åºæ件çåé¨å
éç¹å
³æ³¨ä¸ä¸step2å3ï¼ççæä¹å©ç¨åé¢åæçç¼è§£ç å¨åºç±»æ¥å®ç°å¤æã大æ¦æ¥çä¸ä¸è¿æ®µä»£ç çå
³ç³»ï¼åç°å¨FFMPEGéï¼å¯ä»¥ç¨ç±»å¾æ¥è¡¨ç¤ºå¤§æ¦çç¼è§£ç å¨ç»åã
å¯ä»¥åèã3ãæ¥äºè§£è¿äºç»æçå«ä¹ï¼è§éå½ï¼ãå¨è¿éä¼è°ç¨ä¸ç³»åæ¥èªutils.cçå½æ°ï¼è¿éçavcodec_openï¼ï¼å½æ°ï¼å¨æå¼ç¼è§£ç å¨é½ä¼è°ç¨å°ï¼å®å°è¿è¡å¦ä¸ä»£ç ï¼
avctx->codec = codec;
avctx->codec_id = codec->id;
avctx->frame_number = 0;
if(avctx->codec->init){
ret = avctx->codec->init(avctx);
è¿è¡å
·ä½éé
çç¼è§£ç å¨åå§åï¼èè¿éçavctx->codec->init(avctx)å°±æ¯è°ç¨AVCodecä¸å½æ°æéå®ä¹çå
·ä½åå§åå½æ°ï¼ä¾å¦X264_initã
å¨avcodec_encode_videoï¼ï¼åavcodec_encode_audioï¼ï¼è¢«output_packetï¼ï¼è°ç¨è¿è¡é³è§é¢ç¼ç ï¼å°åæ ·å©ç¨å½æ°æéavctx->codec->encodeï¼ï¼è°ç¨éé
ç¼ç å¨çç¼ç å½æ°ï¼å¦X264_frameè¿è¡å
·ä½å·¥ä½ã
ä»ä¸é¢çåæï¼æ们å¯ä»¥çå°FFMPEGæä¹å©ç¨é¢å对象æ¥æ½è±¡ç¼è§£ç å¨è¡ä¸ºï¼éè¿ç»åå继æ¿å
³ç³»å
·ä½åæ¯ä¸ªç¼è§£ç å¨å®ä½ã设æ³è¦å¨FFMPEGä¸å å
¥æ°ç解ç å¨H265ï¼è¦åçäºæ
å¦ä¸ï¼
1. å¨configç¼è¯é
ç½®ä¸å å
¥CONFIG_H265_DECODER
2. å©ç¨å®æ³¨åH265解ç å¨
3. å®ä¹AVCodec 265_decoderåéï¼åå§åå±æ§åå½æ°æé
4. å©ç¨è§£ç å¨APIå
·ä½å265_decoderçinitçå½æ°æé
å®æ以ä¸æ¥éª¤ï¼å°±å¯ä»¥ææ°ç解ç å¨æ¾å
¥FFMPEGï¼å¤é¨çå¹é
åè¿è¡è§åç±åºç±»çå¤æå®ç°äºã
4. X264æ¶æåæ
X264æ¯ä¸æ¬¾ä»2004å¹´ææ³å½å¤§å¦çåèµ·çå¼æºH.264ç¼ç å¨ï¼å¯¹PCè¿è¡æ±ç¼çº§ä»£ç ä¼åï¼èå¼äºçç»åå¤åè帧çæ§è½æçæ¯ä¸é«çåè½æ¥æé«ç¼ç æçï¼å®è¢«FFMPEGä½ä¸ºå¼å
¥ç.264ç¼ç åºï¼ä¹è¢«ç§»æ¤å°å¾å¤DSPåµå
¥å¹³å°ãåé¢ç¬¬ä¸èå·²ç»å¯¹FFMPEGä¸çX264è¿è¡ä¸¾ä¾åæï¼è¿éå°ç»§ç»ç»åX264æ¡æ¶å æ·±ç¸å
³å
容çäºè§£ã
æ¥ç代ç åï¼è¿æ¯æèä¸ä¸å¯¹äºä¸æ¬¾å
·ä½çç¼ç å¨ï¼æä¹é¢å对象åæå¢ï¼å¯¹çµç¼ç é¨å对ä¸åç®æ³çæ½è±¡ï¼è¿æ帧å
æ帧é´ç¼ç åç§ä¼°è®¡ç®æ³çæ½è±¡ï¼é½å¯ä»¥ä½ä¸ºç±»æ¥æ建ã
å¨X264ä¸ï¼æ们çå°ç对å¤APIåä¸ä¸æåéé½å£°æå¨X264.hä¸ï¼APIå½æ°ä¸ï¼å
³äºè¾
å©åè½çå½æ°å¨common.cä¸å®ä¹
void x264_picture_alloc( x264_picture_t *pic, int i_csp, int i_width, int i_height );
void x264_picture_clean( x264_picture_t *pic );
int x264_nal_encode( void *, int *, int b_annexeb, x264_nal_t *nal );
èç¼ç åè½å½æ°å®ä¹å¨encoder.c
x264_t *x264_encoder_open ( x264_param_t * );
int x264_encoder_reconfig( x264_t *, x264_param_t * );
int x264_encoder_headers( x264_t *, x264_nal_t **, int * );
int x264_encoder_encode ( x264_t *, x264_nal_t **, int *, x264_picture_t *, x264_picture_t * );
void x264_encoder_close ( x264_t * );
å¨x264.cæ件ä¸ï¼æç¨åºçmainå½æ°ï¼å¯ä»¥çä½åAPI使ç¨çä¾åï¼å®ä¹æ¯éè¿è°ç¨X264.hä¸çAPIåä¸ä¸æåéæ¥å®ç°å®é
åè½ã
X264æéè¦çè®°å½ä¸ä¸ææ°æ®çç»æä½x264_tå®ä¹å¨common.hä¸ï¼å®å
å«äºä»çº¿ç¨æ§å¶åéå°å
·ä½çSPSãPPSãéåç©éµãcabacä¸ä¸æçææçH.264ç¼ç ç¸å
³åéãå
¶ä¸å
å«å¦ä¸çç»æä½
x264_predict_t predict_16x16[4+3];
x264_predict_t predict_8x8c[4+3];
x264_predict8x8_t predict_8x8[9+3];
x264_predict_t predict_4x4[9+3];
x264_predict_8x8_filter_t predict_8x8_filter;
x264_pixel_function_t pixf;
x264_mc_functions_t mc;
x264_dct_function_t dctf;
x264_zigzag_function_t zigzagf;
x264_quant_function_t quantf;
x264_deblock_function_t loopf;
è·è¸ªæ¥çå¯ä»¥çå°å®ä»¬ææ¯ä¸ä¸ªå½æ°æéï¼ææ¯ç±å½æ°æéç»æçç»æï¼è¿æ ·çç¨æ³å¾æ³é¢å对象ä¸çinterfaceæ¥å£å£°æãè¿äºå½æ°æéå°å¨x264_encoder_openï¼ï¼å½æ°ä¸è¢«åå§åï¼è¿éçåå§åé¦å
æ ¹æ®CPUçä¸åæä¾ä¸åçå½æ°å®ç°ä»£ç 段ï¼å¾å¤ä¸å¯è½æ¯æ±ç¼å®ç°ï¼ä»¥æé«ä»£ç è¿è¡æçãå
¶æ¬¡æåè½ç¸ä¼¼çå½æ°éä¸ç®¡çï¼ä¾å¦ç±»ä¼¼intra16ç4ç§åintra4çä¹ç§é¢æµå½æ°é½è¢«ç¨å½æ°æéæ°ç»ç®¡çèµ·æ¥ã
x264_encoder_encodeï¼ï¼æ¯è´è´£ç¼ç ç主è¦å½æ°ï¼èå
¶å
å
å«çx264_slice_writeï¼ï¼è´è´£çå±ä¸ä¸çå
·ä½ç¼ç ï¼å
æ¬äºå¸§å
å帧é´å®åç¼ç ãå¨è¿éï¼cabacåcavlcçè¡ä¸ºæ¯æ ¹æ®h->param.b_cabacæ¥åºå«çï¼åå«è¿è¡x264_macroblock_write_cabacï¼ï¼åx264_macroblock_write_cavlcï¼ï¼æ¥åç æµï¼å¨è¿ä¸é¨åï¼åè½å½æ°ææ件å®ä¹å½ç±»ï¼åºæ¬æç
§ç¼ç æµç¨å¾è¿è¡ï¼çèµ·æ¥æ´åé¢åè¿ç¨çåæ³ï¼å¨å·²ç»åå§åäºå
·ä½çå½æ°æéï¼ç¨åºå°±ä¸ç´æç¼ç è¿ç¨çé»è¾å®ç°ãå¦æä»æ´ä½æ¶ææ¥çï¼x264å©ç¨è¿ç§ç±»ä¼¼æ¥å£çå½¢å¼å®ç°äºå¼±è¦ååå¯éç¨ï¼å©ç¨x264_tè¿ä¸ªè´¯ç©¿å§ç»çä¸ä¸æï¼å®ç°ä¿¡æ¯å°è£
åå¤æã
æ¬æ大æ¦åæäºFFMPEG/X264ç代ç æ¶æï¼éç¹æ¢è®¨ç¨Cè¯è¨æ¥å®ç°é¢å对象ç¼ç ï¼è½ä¸è³äºå¼ºè¡åC++é æ¢ï¼ä½æ¯ä¹åæå®ç°ç¹è²ï¼ä¿è¯å®ç¨æ§ãå¼å¾è§åCè¯è¨è½¯ä»¶é¡¹ç®æåé´ã
温馨提示:答案为网友推荐,仅供参考