我想使用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_fmt
到AV_PIX_FMT_BGR8
.顺便说一下,我仍然面临着生成的GIF的一些问题.它没有播放,编码似乎失败了.
使用ffmpeg(左)在命令行中生成GIF...GIF以编程方式生成(右)
看起来有些选项没有定义......也可能是QImage和AVFrame之间的错误转换?我更新了上面的代码.它代表了很多代码,所以我试图保持简短.不要犹豫,询问更多细节.
编辑结束
我对ffmpeg并不熟悉,任何形式的帮助都会受到高度赞赏.谢谢.
GIF 只能支持 256 色位图(每像素 8 位)。这可能是您出现错误的原因Specified pixel format rgb24 is invalid or not supported
。
您需要使用的像素格式是AV_PIX_FMT_PAL8
(8 位,RGB32 调色板)。
归档时间: |
|
查看次数: |
1503 次 |
最近记录: |