[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