使用ffmpeg从QImages创建GIF

Sie*_*rra 9 c++ qt ffmpeg gif



我想使用ffmpeg从QImage生成GIF - 所有这些都是以编程方式(C++)生成的.我正在使用Qt 5.6和ffmpeg的最后一个版本(构建git-0a9e781(2016-06-10).

我已经能够在.mp4中转换这些QImage并且它有效.我试图使用相同的原理GIF,改变格式像素和编解码器.GIF生成两张图片(每张1秒),15 FPS.

## INITIALIZATION
#####################################################################

// Filepath : "C:/Users/.../qt_temp.Jv7868.gif"  
// Allocating an AVFormatContext for an output format...
avformat_alloc_output_context2(formatContext, NULL, NULL, filepath);

...

// Adding the video streams using the default format codecs and initializing the codecs.
stream = avformat_new_stream(formatContext, *codec);

AVCodecContext * codecContext = avcodec_alloc_context3(*codec);

context->codec_id       = codecId;
context->bit_rate       = 400000;
...
context->pix_fmt        = AV_PIX_FMT_BGR8;

...

// Opening the codec...
avcodec_open2(codecContext, codec, NULL);

...

frame = allocPicture(codecContext->width, codecContext->height, codecContext->pix_fmt);
tmpFrame = allocPicture(codecContext->width, codecContext->height, AV_PIX_FMT_RGBA);

...

avformat_write_header(formatContext, NULL);

## ADDING A NEW FRAME
#####################################################################

// Getting in parameter the QImage: newFrame(const QImage & image)
const qint32 width  = image.width();
const qint32 height = image.height();

// Converting QImage into AVFrame
for (qint32 y = 0; y < height; y++) {
    const uint8_t * scanline = image.scanLine(y);

    for (qint32 x = 0; x < width * 4; x++) {
        tmpFrame->data[0][y * tmpFrame->linesize[0] + x] = scanline[x];
    }
}

...

// Scaling...
if (codec->pix_fmt != AV_PIX_FMT_BGRA) {
    if (!swsCtx) {
        swsCtx = sws_getContext(codec->width, codec->height,
                                AV_PIX_FMT_BGRA,
                                codec->width, codec->height,
                                codec->pix_fmt,
                                SWS_BICUBIC, NULL, NULL, NULL);
    }

    sws_scale(swsCtx,
              (const uint8_t * const *)tmpFrame->data,
              tmpFrame->linesize,
              0,
              codec->height,
              frame->data,
              frame->linesize);
}
frame->pts = nextPts++;

...

int gotPacket = 0;
AVPacket packet = {0};

av_init_packet(&packet);
avcodec_encode_video2(codec, &packet, frame, &gotPacket);

if (gotPacket) {
    av_packet_rescale_ts(paket, *codec->time_base, stream->time_base);
    paket->stream_index = stream->index;

    av_interleaved_write_frame(formatContext, paket);
}
Run Code Online (Sandbox Code Playgroud)

但是当我试图修改视频编解码器和像素格式以符合GIF规范时,我遇到了一些问题.我尝试了几种编解码器AV_CODEC_ID_GIF,AV_CODEC_ID_RAWVIDEO但是它们似乎都没有用.在初始化阶段,avcodec_open2()始终返回此类错误:

Specified pixel format rgb24 is invalid or not supported
Could not open video codec:  gif
Run Code Online (Sandbox Code Playgroud)

编辑17/06/2016

多挖一点,avcodec_open2()返回-22:

#define EINVAL          22      /* Invalid argument */
Run Code Online (Sandbox Code Playgroud)

编辑22/06/2016

以下是用于编译ffmpeg的标志:

"FFmpeg/Libav configuration: --disable-static --enable-shared --enable-gpl --enable-version3 --disable-w32threads --enable-nvenc --enable-avisynth --enable-bzlib --enable-fontconfig --enable-frei0r --enable-gnutls --enable-iconv --enable-libass --enable-libbluray --enable-libbs2b --enable-libcaca --enable-libfreetype --enable-libgme --enable-libgsm --enable-libilbc --enable-libmodplug --enable-libmfx --enable-libmp3lame --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-libopenjpeg --enable-libopus --enable-librtmp --enable-libschroedinger --enable-libsnappy --enable-libsoxr --enable-libspeex --enable-libtheora --enable-libtwolame --enable-libvidstab --enable-libvo-amrwbenc --enable-libvorbis --enable-libvpx --enable-libwavpack --enable-libwebp --enable-libx264 --enable-libx265 --enable-libxavs --enable-libxvid --enable-libzimg --enable-lzma --enable-decklink --enable-zlib"
Run Code Online (Sandbox Code Playgroud)

我错过了GIF的关键一个吗?

编辑27/06/2016

由于格温,我有一个第一输出:我设置好的了context->pix_fmtAV_PIX_FMT_BGR8.顺便说一下,我仍然面临着生成的GIF的一些问题.它没有播放,编码似乎失败了.

使用ffmpeg(左)在命令行中生成GIF...GIF以编程方式生成(右)
使用ffmpeg在命令行中生成 在此输入图像描述

看起来有些选项没有定义......也可能是QImage和AVFrame之间的错误转换?我更新了上面的代码.它代表了很多代码,所以我试图保持简短.不要犹豫,询问更多细节.

编辑结束

我对ffmpeg并不熟悉,任何形式的帮助都会受到高度赞赏.谢谢.

Gwe*_*wen 5

GIF 只能支持 256 色位图(每像素 8 位)。这可能是您出现错误的原因Specified pixel format rgb24 is invalid or not supported

您需要使用的像素格式是AV_PIX_FMT_PAL88 位,RGB32 调色板)。