C++可以通過調用FFmpeg的API來對H264文件進行編碼和解碼。下面是一個簡單的例子。
首先需要在代碼中包含FFmpeg的頭文件:
extern "C" {
#include <libavcodec/avcodec.h>
#include <libavformat/avformat.h>
#include <libswscale/swscale.h>
}
然后需要初始化FFmpeg庫:
av_register_all();
avformat_network_init();
對于編碼,需要創建一個AVCodecContext和AVCodec:
AVCodec *codec;
AVCodecContext *codecContext;codec = avcodec_find_encoder(AV_CODEC_ID_H264);
codecContext = avcodec_alloc_context3(codec);// 設置編碼參數
codecContext->codec_type = AVMEDIA_TYPE_VIDEO;
codecContext->bit_rate = 400000;
codecContext->width = 640;
codecContext->height = 480;
codecContext->time_base = (AVRational){1, 25};
codecContext->gop_size = 10;
codecContext->max_b_frames = 1;avcodec_open2(codecContext, codec, NULL);
接下來可以將圖片數據轉換為AVFrame,然后進行編碼:
AVFrame *frame;
AVPacket packet;// 分配AVFrame對象
frame = av_frame_alloc();
frame->format = AV_PIX_FMT_YUV420P;
frame->width = codecContext->width;
frame->height = codecContext->height;// 分配內存
av_image_alloc(frame->data, frame->linesize, codecContext->width, codecContext->height, AV_PIX_FMT_YUV420P, 1);// 將RGB數據轉換為YUV420P
struct SwsContext *swsContext;
swsContext = sws_getContext(codecContext->width, codecContext->height, AV_PIX_FMT_RGB24,codecContext->width, codecContext->height, AV_PIX_FMT_YUV420P,SWS_BILINEAR, NULL, NULL, NULL);uint8_t *inputData[1] = {rgbData}; // rgbData為輸入圖片數據
int inputLineSize[1] = {codecContext->width * 3}; // RGB數據每行字節數
sws_scale(swsContext, inputData, inputLineSize, 0, codecContext->height, frame->data, frame->linesize);// 編碼
int gotPacket = 0;
av_init_packet(&packet);
packet.data = NULL;
packet.size = 0;
avcodec_encode_video2(codecContext, &packet, frame, &gotPacket);
對于解碼,需要創建一個AVCodecContext和AVCodecParserContext:
AVCodec *codec;
AVCodecContext *codecContext;codec = avcodec_find_decoder(AV_CODEC_ID_H264);
codecContext = avcodec_alloc_context3(codec);// 設置解碼參數
avcodec_open2(codecContext, codec, NULL);AVCodecParserContext *parserContext;
parserContext = av_parser_init(AV_CODEC_ID_H264);
接下來將輸入數據(例如H264文件)分割成一幀一幀的數據,并解碼:
uint8_t *inputData = // 輸入數據
int inputSize = // 輸入數據大小while (inputSize > 0) {int parsedSize = av_parser_parse2(parserContext, codecContext, &packet.data, &packet.size,inputData, inputSize, AV_NOPTS_VALUE, AV_NOPTS_VALUE, 0);inputSize -= parsedSize;inputData += parsedSize;if (packet.size > 0) {int frameFinished = 0;avcodec_decode_video2(codecContext, frame, &frameFinished, &packet);if (frameFinished) {// 處理解碼后的數據}}
}
以上是一個簡單的例子,實際使用中還需要進行一些錯誤處理和內存管理等操作。因此建議參考FFmpeg的官方文檔和示例代碼進行開發。