我已经调试程序两周了,输出视频仅显示空白屏幕(正在使用VLC,WMP和WMPClassic进行测试)。 我碰巧尝试使用FFPlay和lo并发现视频效果完美。 我已经读到这通常是由不正确的像素格式引起的,切换到PIX_FMT_YUV420P可以使其通用工作……但是我已经在编码过程中使用了该像素格式。 还有其他原因吗?

AVCodec* codec;
AVCodecContext* c = NULL;
uint8_t* outbuf;
int i, out_size, outbuf_size;

avcodec_register_all();

printf("Video encoding\n");

// Find the mpeg1 video encoder
codec = avcodec_find_encoder(CODEC_ID_H264);
if (!codec) {
    fprintf(stderr, "Codec not found\n");
    exit(1);
}
else printf("H264 codec found\n");

c = avcodec_alloc_context3(codec);

c->bit_rate = 400000;
c->width = 1920;                                        // resolution must be a multiple of two (1280x720),(1900x1080),(720x480)
c->height = 1200;
c->time_base.num = 1;                                   // framerate numerator
c->time_base.den = 25;                                  // framerate denominator
c->gop_size = 10;                                       // emit one intra frame every ten frames
c->max_b_frames = 1;                                    // maximum number of b-frames between non b-frames
//c->keyint_min = 1;                                        // minimum GOP size
//c->i_quant_factor = (float)0.71;                      // qscale factor between P and I frames
//c->b_frame_strategy = 20;
//c->qcompress = (float)0.6;
//c->qmin = 20;                                         // minimum quantizer
//c->qmax = 51;                                         // maximum quantizer
//c->max_qdiff = 4;                                     // maximum quantizer difference between frames
//c->refs = 4;                                          // number of reference frames
//c->trellis = 1;                                           // trellis RD Quantization
c->pix_fmt = PIX_FMT_YUV420P;
c->codec_id = CODEC_ID_H264;
//c->codec_type = AVMEDIA_TYPE_VIDEO;

// Open the encoder
if (avcodec_open2(c, codec,NULL) < 0) {
    fprintf(stderr, "Could not open codec\n");
    exit(1);
}
else printf("H264 codec opened\n");

outbuf_size = 100000 + c->width*c->height*(32>>3);//*(32>>3);           // alloc image and output buffer
outbuf = static_cast<uint8_t *>(malloc(outbuf_size));
printf("Setting buffer size to: %d\n",outbuf_size);

FILE* f = fopen("example.mpg","wb");
if(!f) printf("x  -  Cannot open video file for writing\n");
else printf("Opened video file for writing\n");

// encode 5 seconds of video
for(i=0;i<STREAM_FRAME_RATE*STREAM_DURATION;i++) {
    fflush(stdout);

    screenCap();

    int nbytes = avpicture_get_size(PIX_FMT_YUV420P, c->width, c->height);
    uint8_t* outbuffer = (uint8_t*)av_malloc(nbytes*sizeof(uint8_t));

    AVFrame* inpic = avcodec_alloc_frame();
    AVFrame* outpic = avcodec_alloc_frame();

    outpic->pts = (int64_t)((float)i * (1000.0/((float)(c->time_base.den))) * 90);
    avpicture_fill((AVPicture*)inpic, (uint8_t*)pPixels, PIX_FMT_RGB32, c->width, c->height);                   // Fill picture with image
    avpicture_fill((AVPicture*)outpic, outbuffer, PIX_FMT_YUV420P, c->width, c->height);
    av_image_alloc(outpic->data, outpic->linesize, c->width, c->height, c->pix_fmt, 1); 

    inpic->data[0] += inpic->linesize[0]*(screenHeight-1);                                                      // Flipping frame
    inpic->linesize[0] = -inpic->linesize[0];                                                                   // Flipping frame

    struct SwsContext* fooContext = sws_getContext(screenWidth, screenHeight, PIX_FMT_RGB32, c->width, c->height, PIX_FMT_YUV420P, SWS_FAST_BILINEAR, NULL, NULL, NULL);
    sws_scale(fooContext, inpic->data, inpic->linesize, 0, c->height, outpic->data, outpic->linesize);

    // encode the image
    out_size = avcodec_encode_video(c, outbuf, outbuf_size, outpic);
    printf("Encoding frame %3d (size=%5d)\n", i, out_size);
    fwrite(outbuf, 1, out_size, f);
    delete [] pPixels;
    av_free(outbuffer);     
    av_free(inpic);
    av_free(outpic);
}

// get the delayed frames
for(; out_size; i++) {
    fflush(stdout);

    out_size = avcodec_encode_video(c, outbuf, outbuf_size, NULL);
    printf("Writing frame %3d (size=%5d)\n", i, out_size);
    fwrite(outbuf, 1, out_size, f);
}

// add sequence end code to have a real mpeg file
outbuf[0] = 0x00;
outbuf[1] = 0x00;
outbuf[2] = 0x01;
outbuf[3] = 0xb7;
fwrite(outbuf, 1, 4, f);
fclose(f);

avcodec_close(c);
free(outbuf);
av_free(c);
printf("Closed codec and Freed\n");

===============>>#1 票数:1

尝试将文件另存为example.h264 ,而不是example.mpg

  ask by mohM translate from so

未解决问题?本站智能推荐:

1回复

使用ffmpeg将帧编码为视频

我正在尝试使用C ++在Unreal Engine 4中对视频进行编码。 我可以访问单独的框架。 以下是读取viewport's显示的像素并将其存储在缓冲区中的代码。 虚幻引擎具有IImageWrapperModule ,您可以使用它从帧中获取图像,但要注意视频编码。 我想要的是对
1回复

使用ffmpeg进行编码:视频质量下降

我正在尝试使用ffmpeg将一组图片编码为视频。 我是新手,但我设法让它发挥作用。 我只有一个问题:第一或第二视频看起来不错,但随着时间的推移,视频质量不断下降。 最后(这是一段约16秒的视频),质量非常差,我无法理解为什么。 我正在使用AV_CODEC_ID_MPEG1VIDEO作
2回复

Libav(ffmpeg)将解码的视频时间戳复制到编码器

我正在编写一个应用程序,它从输入文件(任何编解码器,任何容器)解码单个视频流,进行一堆图像处理,并将结果编码为输出文件(单个视频流,Quicktime RLE,MOV)。 我正在使用ffmpeg的libav 3.1.5(目前是Windows版本,但应用程序将是跨平台的)。 输入帧和输出帧
1回复

ffmpeg编码过程中的更新参数正在运行

我想更新之前已经传递给AVCodecContext结构的视频编码器的fps,比特率,gop等参数。我想在每次更新任何参数时同时得到它的反射。 有一件事可以做,就是需要使用av编解码器关闭并再次打开它来关闭编解码器。 但我认为这不是好方法。 这是我的ffmpeg的视频编码源代码:
1回复

使用ffmpeg编码AAC(c ++)

我正在研究将在Unity插件中使用的视频编码。 我已经使图像编码工作,但现在我在音频。 所以只尝试将音频输入到具有AAC编码的mp4文件中。 而且我被困住了。 生成的文件不包含任何内容。 另外,根据我的理解,ffmpeg中的AAC仅支持AV_SAMPLE_FMT_FLTP,这就是我使用
2回复

在ffmpeg中读取JPEG

我正在尝试使ffmpeg将几个单独的JPEG图像编码为Android上的视频。 我已经为Android成功构建了它(请参阅本文末尾的配置字符串)。 我可以使用随机生成的帧内容编码h.263 +视频,否则ffmpeg看起来效果很好。 一个类似的问题表明以下代码足以将图像加载到AvFr
2回复

ffmpeg hevc(x265)编码

我正在尝试在ffmpeg库中使用h265编码器但是给我这个错误: 这是我的代码: 此代码适用于h264编码器,任何人都知道为什么不能与hevc一起使用?
1回复

使用ffmpeg将平面RGB图像组合成无损视频

我的内存中已经有一系列图像。 图像是RGB,但是是平面的,即非交错的。 我希望使用ffmpeg将其无损压缩为视频。 目前我有这个(注意:我已经排除了错误检查和清除): 目前在avformat_write_header失败,给我一个错误代码-22,我认为这意味着某种无效参数?
2回复

使用FFmpeg从音频和视频文件复用

我正在学习如何从这个例子中创建MP4视频。问题是该示例演示了动态生成的一些虚拟源数据的音频编码。我需要对文件中的音频进行编码。我检查了很多例子,其中大部分显示相同或只是一个单独的音频编码。 在我的试验和错误过程中,我对音频和视频帧使用相同的AVFormatContext。我不确定这是否正确,或
1回复

使用ffmpeg分割/保存h264 rtsp流和取消有效载荷标头,而无需在C ++中进行解码/编码

我想通过rtsp接收h264编码的流,从数据包头读取元数据(以保存到数据库中),拆分视频并将其保存到磁盘,而无需对流进行解码/编码。 分割的视频片段的长度可以固定为5-10分钟。 我想使用C ++中的FFMpeg API(不要使用命令行!)来做到这一点,并尽可能减少CPU开销,因为我需要标头