为什么FFMPEG屏幕记录器输出只显示绿色屏幕?

Why FFMPEG screen recorder output shows green screen only?(为什么FFMPEG屏幕记录器输出只显示绿色屏幕?)
本文介绍了为什么FFMPEG屏幕记录器输出只显示绿色屏幕?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用FFMPEG库编写一个屏幕记录器,但在输出中它只显示一个绿屏视频。 我的代码如下

#define __STDC_CONSTANT_MACROS
#include<iostream>
extern "C"
{
#include <libavcodec/avcodec.h>
#include <libavformat/avformat.h>
#include <libavdevice/avdevice.h>
#include <libavutil/imgutils.h>
#include <libswscale/swscale.h>
//#include <libswscale/swscale.h>
}
using namespace std;
//const char* out_filename = "D:\my\folder\to\Frame.jpg";

AVCodecContext* GetCodecContextFromPar(AVCodecParameters * par)
{
    AVCodecContext* cntxt = NULL;
    cntxt = avcodec_alloc_context3(avcodec_find_decoder(par->codec_id));
    avcodec_parameters_to_context(cntxt,par);
    return cntxt;
}
int AvCodecDecodeVideo2(AVCodecContext* avctx, AVFrame* frame, int* got_picture_ptr, const AVPacket* avpkt)
{
    
    int ret = avcodec_send_packet(avctx, avpkt);
    if (ret < 0)
    {
        return -1;
        *got_picture_ptr = 0;
    }
        
    while (ret >= 0)
    {
        ret = avcodec_receive_frame(avctx, frame);

    }
    *got_picture_ptr = 1;
    return 0;
    

}

int AvCodecEncodeVideo2(AVCodecContext* avctx, AVPacket* avpkt, const AVFrame* frame, int* got_packet_ptr)
{
    char str2[] = "";
    
    int Res = avcodec_send_frame(avctx, frame);
    while (Res >= 0)
    {
        Res = avcodec_send_frame(avctx, frame);
    }
    //avcodec_encode_video2
    Res = avcodec_receive_packet(avctx, avpkt);
        
    if (Res == 0)
    {
        *got_packet_ptr = 1;
        return 0;
    }
    cout << "
Error :" << av_make_error_string(str2, sizeof(str2), Res);
    return -1;
}
int main(int argc, char** argv)
{
    const char* out_filename = "D:\myfolder\to\output\new_out.mp4";
    avdevice_register_all();
    AVOutputFormat* ofmt = NULL;
    AVInputFormat* ifmt = NULL;
    AVFormatContext* ifmt_ctx = avformat_alloc_context();
    AVFormatContext* ofmt_ctx = avformat_alloc_context();
    AVCodecParameters * av_codec_par_in = avcodec_parameters_alloc();
    AVCodecParameters* av_codec_par_out = avcodec_parameters_alloc();
    AVCodecContext* avcodec_contx = NULL;
    AVCodec* av_codec;

    AVStream* video_stream = NULL;
    av_codec_par_out->height = 480;
    av_codec_par_out->width = 640;
    av_codec_par_out->bit_rate = 40000;
    av_codec_par_out->codec_id = AV_CODEC_ID_MPEG4;
    av_codec_par_out->codec_type = AVMEDIA_TYPE_VIDEO;
    av_codec_par_out->format = 0;
    av_codec_par_out->sample_aspect_ratio.den = 3;
    av_codec_par_out->sample_aspect_ratio.num = 4;

    AVDictionary* options = NULL;

    av_dict_set(&options,"framerate","30",0);
    av_dict_set(&options,"offset_x","20",0);
    av_dict_set(&options,"offset_y","40",0);
    av_dict_set(&options,"video_size","640x480",0);
    int ret, i;
    ifmt = av_find_input_format("gdigrab");
    
    if (avformat_open_input(&ifmt_ctx, "desktop", ifmt, &options) <0)
    {
        cout << "Error in opening file";
        exit(1);
    }
    int VideoStreamIndx = -1;
    avformat_find_stream_info(ifmt_ctx, NULL);
    /* find the first video stream index . Also there is an API available to do the below operations */
    for (int i = 0; i < ifmt_ctx->nb_streams; i++) // find video stream posistion/index.
    {
        if (ifmt_ctx->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_VIDEO)
        {
            VideoStreamIndx = i;
            break;
        }

    }
    if (VideoStreamIndx == -1)
    {
        cout << "
unable to find the video stream index. (-1)";
        exit(1);
    }
    av_codec_par_in = ifmt_ctx->streams[VideoStreamIndx]->codecpar;
    av_codec = avcodec_find_decoder(av_codec_par_in->codec_id);
    if (av_codec == NULL)
    {
        cout << "
unable to find the decoder";
        exit(1);
    }
    avcodec_contx = avcodec_alloc_context3(av_codec);
    if (avcodec_parameters_to_context(avcodec_contx, av_codec_par_in) < 0)
    {
        cout << "
error in converting the codec contexts";
        exit(1);
    }

    //av_dict_set
    int value = avcodec_open2(avcodec_contx, av_codec, NULL);//Initialize the AVCodecContext to use the given AVCodec.
    if (value < 0)
    {
        cout << "
unable to open the av codec";
        exit(1);
    }
    value = 0;
    ofmt = av_guess_format(NULL, out_filename, NULL);
    if (!ofmt)
    {
        cout << "
error in guessing the video format. try with correct format";
        exit(1);
    }
    avformat_alloc_output_context2(&ofmt_ctx, ofmt, NULL, out_filename);
    if (!ofmt_ctx)
    {
        cout << "
error in allocating av format output context";
        exit(1);
    }
    AVCodec * av_codec_out = avcodec_find_encoder(av_codec_par_out->codec_id);
    if (av_codec_out == NULL)
    {
        cout << "
unable to find the encoder";
        exit(1);
    }
    video_stream = avformat_new_stream(ofmt_ctx, av_codec_out);
    if (!video_stream)
    {
        cout << "
error in creating a av format new stream";
        exit(1);
    }
    AVCodecContext* av_cntx_out;
    av_cntx_out = avcodec_alloc_context3(av_codec_out);
    if (!av_cntx_out)
    {
        cout << "
error in allocating the codec contexts";
        exit(1);
    }
    
    if (avcodec_parameters_copy(video_stream->codecpar, av_codec_par_out) < 0)
    {
        cout << "
Codec parameter canot copied";
        exit(1);
    }
    if (avcodec_parameters_to_context(av_cntx_out, av_codec_par_out) < 0)
    {
        cout << "
error in converting the codec contexts";
        exit(1);
    }
    
    //av_cntx_out->pix_fmt = AV_PIX_FMT_YUV420P;
    av_cntx_out->gop_size = 3;
    av_cntx_out->max_b_frames = 2;
    av_cntx_out->time_base.num = 1;
    av_cntx_out->time_base.den = 30; //
    value = avcodec_open2(av_cntx_out, av_codec_out, NULL);//Initialize the AVCodecContext to use the given AVCodec.
    if (value < 0)
    {
        cout << "
unable to open the av codec";
        exit(1);
    }
    if (avcodec_contx->codec_id == AV_CODEC_ID_H264)
    {
        av_opt_set(av_cntx_out->priv_data, "preset", "slow", 0);
    }
    avio_open(&ofmt_ctx->pb, out_filename, AVIO_FLAG_READ_WRITE);
    if (ofmt_ctx->oformat->flags & AVFMT_GLOBALHEADER)
    {
        av_cntx_out->flags |= AV_CODEC_FLAG_GLOBAL_HEADER;
    }
    if (avformat_write_header(ofmt_ctx, NULL) < 0)
    {
        cout << "
error in writing the header context";
        exit(1);
    }
    AVPacket * av_pkt = av_packet_alloc();
    av_init_packet(av_pkt);
    AVFrame * av_frame = av_frame_alloc();
    if (!av_frame)
    {
        cout << "
unable to release the avframe resources";
        exit(1);
    }
    AVFrame * outFrame = av_frame_alloc();//Allocate an AVFrame and set its fields to default values.
    if (!outFrame)
    {
        cout << "
unable to release the avframe resources for outframe";
        exit(1);
    }

    //int video_outbuf_size;
    //int nbytes = av_image_get_buffer_size(av_cntx_out->pix_fmt, av_cntx_out->width, av_cntx_out->height, 32);
    //uint8_t* video_outbuf = (uint8_t*)av_malloc(nbytes);
    //if (video_outbuf == NULL)
    //{
    //  cout << "
unable to allocate memory";
    //  exit(1);
    /
本站部分内容来源互联网,如果有图片或者内容侵犯您的权益请联系我们删除!

相关文档推荐

C++ find method not working(C++查找方法不起作用)
How to determine the offset of an element of a tuple at compile time?(如何在编译时确定元组元素的偏移量?)
Error: control Reaches end of non void function(错误:控件已到达非无效函数的末尾)
Error: Jump to case label in switch statement(错误:跳转到SWITCH语句中的CASE标签)
Order of elements in set of pointers(指针集中元素的顺序)
error while loading shared libraries: jvm.dll(加载共享库时出错:jvm.dll)