将alpha通道写入已解码的ffmpeg帧

我正在寻找一种快速的方法将我自己的alpha通道添加到解码的ffmpeg帧。

我有一个带有RGB信息的AVI文件,我有一个描述透明度alpha通道(灰度)的同步video流。 在使用ffmpeg解码AVI文件时,我想将输出帧转换为RGBA,同时添加我自己的alpha信息。 最后,我将获得一个半透明的video流。

是否有任何优化的函数,可能在libswscale或libswresample中,做这样的事情比迭代像素更好?

基本上我希望能够编写这样的函数,如果我只有sws_scale_and_add_alpha这样的函数:

void* FFmpegLib_nextFrame_withAlpha(void* _handle, uint8_t* my_alpha_channel) { FFmpegLibHandle* handle = (FFmpegLibHandle*)_handle; AVPacket packet; int frameFinished; while(av_read_frame(handle->pFormatCtx, &packet) >= 0) { // Is this a packet from the video stream? if(packet.stream_index==handle->videoStream) { // Decode video frame avcodec_decode_video2(handle->pCodecCtx, handle->pFrame, &frameFinished, &packet); // Did we get a video frame? if(frameFinished) { sws_scale_and_add_alpha ( handle->sws_ctx, (uint8_t const * const *)handle->pFrame->data, handle->pFrame->linesize, 0, handle->pCodecCtx->height, handle->pFrameARGB->data, handle->pFrameARGB->linesize, my_alpha_channel ); return handle->pFrameARGB->data; } } } return NULL; } 

我想过两种方法可以做到这一点。 通常,如果我想在命令行中合并alpha通道, ffmpeg为此提供alphamergefilter。 而且我很确定你可以在C中做同样的事情,虽然它可能很难编程,(甚至在ffmpeg源代码中也有一个videofilter示例。)。

第二个是自己编码,反对AVFrame结构。 AVFrame的data字段保存像素信息。 我们需要将alpha通道打包到其中。

首先将压缩图像帧转换为打包ARGB

 // pFrameARGB should have been allocated and of pix_fmt `AV_PIX_FMT_ARGB` sws_scale(sws_ctx, pFrame->data, pFrame->linesize, 0, height, pFrameARGB->data, pFrameARGB->linesize); 

AVFrame.data是一个包含不同平面的多维数组。 这里我们有一个打包的ARGB图像,而不是平面图像,因此data[0]包含我们需要的所有像素。

 // cpp example, easy to convert to pure C auto p = pFrameARGB->data[0]; for (auto i = 0; i < width * height; i++) { auto num = i * sizeof(uint8_t) * 4; auto div_result = std::div(num, width * sizeof(uint8_t) * 4); auto offset = pFrameARGB->linesize * div_result.quot + div_result.rem; p[offset] = my_alpha_channel[i]; }