[Libav-user] Difficulty decoding libvpx VP8 with Alpha as RGBA
Craig Turner
turner.craig at gmail.com
Sun Jan 31 23:42:59 EET 2021
Hi,
I'm trying to decode and convert a VP8 video with an alpha channel to a
32-bit RGBA for rendering in my application. The decoding with libvpx works
fine, but I can't get the alpha channel through into the RGBA. Am I
doing something wrong with libswscale?
Thanks in advance!
Craig
Here's the initialization code:
// Open video file
if(avformat_open_input(&_formatCtx, _videoFile.toUtf8().constData(),
nullptr, nullptr) != 0)
return false; // Couldn't open file
// Retrieve stream information
if(avformat_find_stream_info(_formatCtx, nullptr) < 0)
return false; // Couldn't find stream information
// Find the first video stream
for(int i = 0; i < _formatCtx->nb_streams; i++)
{
if(_formatCtx->streams[i]->codecpar->codec_type ==
AVMEDIA_TYPE_VIDEO)
{
_videoStream=i;
break;
}
}
if(_videoStream == -1)
return false; // Didn't find a video stream
// Find the decoder for the video stream
if(_formatCtx->streams[_videoStream]->codecpar->codec_id ==
AV_CODEC_ID_VP8)
_codec = avcodec_find_decoder_by_name("libvpx");
else if(_formatCtx->streams[_videoStream]->codecpar->codec_id ==
AV_CODEC_ID_VP9)
_codec = avcodec_find_decoder_by_name("libvpx-vp9");
else
_codec =
avcodec_find_decoder(_formatCtx->streams[_videoStream]->codecpar->codec_id);
if(_codec == NULL)
return false; // Codec not found
// Copy context
_codecCtx = avcodec_alloc_context3(_codec);
if(avcodec_parameters_to_context(_codecCtx,
_formatCtx->streams[_videoStream]->codecpar) < 0)
return false; // Couldn't convert codec parameters to context
// Open codec
if(avcodec_open2(_codecCtx, _codec, nullptr) < 0)
return false; // Could not open codec
// Allocate video frame
_frame = av_frame_alloc();
if(_frame == nullptr)
return false;
// Allocate an AVFrame structure
_frameBGRA = av_frame_alloc();
if(_frameBGRA == nullptr)
return false;
int numBytes;
// Determine required buffer size and allocate buffer
numBytes = avpicture_get_size(AV_PIX_FMT_BGRA, _targetSize.width(),
_targetSize.height());
_buffer=(uint8_t *)av_malloc(numBytes * sizeof(uint8_t));
// Assign appropriate parts of buffer to image planes in FrameBGRA
avpicture_fill((AVPicture *)_frameBGRA, _buffer, AV_PIX_FMT_BGRA,
_targetSize.width(), _targetSize.height());
// initialize SWS context for software scaling
_sws_ctx = sws_getContext(_codecCtx->width,
_codecCtx->height,
_codecCtx->pix_fmt,
_targetSize.width(),
_targetSize.height(),
AV_PIX_FMT_BGRA,
SWS_BILINEAR,
nullptr,
nullptr,
nullptr);
And here's the code in the worker thread handling the individual packets:
while(av_read_frame(_formatCtx, &packet) >= 0)
{
// Is this a packet from the video stream?
if(packet.stream_index == _videoStream)
{
// Decode video frame
avcodec_decode_video2(_codecCtx, _frame, &frameFinished,
&packet);
// Did we get a video frame?
if(frameFinished)
{
// Convert the image from its native format to ARGB
sws_scale(_sws_ctx,
(uint8_t const * const *)_frame->data,
_frame->linesize,
0,
_codecCtx->height,
_frameBGRA->data,
_frameBGRA->linesize);
// Inform the application the frame is complete
}
}
// Free the packet that was allocated by av_read_frame
av_packet_unref(&packet);
}
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://ffmpeg.org/pipermail/libav-user/attachments/20210131/05e9851b/attachment.html>
More information about the Libav-user
mailing list