不仅avcodec_encode_video已过时,avcodec_encode_video2也被标记为弃用了一段时间.您现在应该使用新的avcodec_send_frame和avcodec_receive_packet进行编码.
“翻转”部分对编码没有任何好处,我强烈建议不要在代码中执行此操作.如果您发现输出大小不正确,只需将swscale插值算法标志切换到SWS_ACCURATE_RND.
除了旧的avcodec_encode_video API,还有几个潜在的风险:
>要使用H264编码器,请使用AV_CODEC_ID_H264而不是AV_CODEC_ID_MPEG1VIDEO找到它,还应使用libx264构建ffmpeg库.
>或者,如果你有一个支持nvenc的工作nvidia卡,avcodec_find_encoder_by_name(“h264_nvenc”)将会好得多.
>删除FileHandle执行两次.
> avpicture …函数已被弃用了很长时间.请改用其他功能.
如果性能至关重要,请将所有编码过程移动到独立的线程而不是游戏线程.
我有一些代码用于在我的自定义GameViewportClient类中编码UE4视口输出,这类似于ffmpeg官方多路复用和encode_video示例.
MyGameViewportClient.h:
UCLASS(Config=Game)
class FUSIONCUT_API UMyGameViewportClient : public UGameViewportClient
{
GENERATED_BODY()
public:
virtual void Draw(FViewport* Viewport, FCanvas* SceneCanvas) override;
void FirstTimeInit();
void InitCodec();
void TidyUp();
void SetAutoRecording(bool val);
void RecordNextFrame();
bool CanRecordNextFrame();
void SetRecording(bool val);
void SetLevelDelay(int32 delay);
void SetOver(bool val);
void SetAbandon(bool val);
void SetFilePath(FString out_file);
void SetThumbnail(FString thumbnail_file, int32 thumbnail_frame);
void SaveThumbnailImage();
private:
UPROPERTY(Config)
FString DeviceNum;
UPROPERTY(Config)
FString H264Crf;
UPROPERTY(Config)
int DeviceIndex;
UPROPERTY()
UFunction* ProgressFunc;
UPROPERTY()
UFunction* FinishFunc;
FIntPoint ViewportSize;
int count;
TArray ColorBuffer;
TArray IMG_Buffer;
struct OutputStream {
AVStream* Stream;
AVCodecContext* Ctx;
int64_t NextPts;
AVFrame* Frame;
struct SwsContext* SwsCtx;
};
OutputStream VideoSt = { 0 };
AVOutputFormat* Fmt;
AVFormatContext* FmtCtx;
AVCodec* VideoCodec;
AVDictionary* Opt = nullptr;
SwsContext* SwsCtx;
AVPacket Pkt;
int GotOutput;
int InLineSize[1];
bool Start;
bool Over;
bool FirstTime;
bool Abandon;
bool AutoRecording;
bool RecordingNextFrame;
double LastSendingTime;
std::string FilePath;
FString UEFilePath;