Skip to content
Snippets Groups Projects
Select Git revision
  • master default protected
  • release/202005
  • release/202001
  • release/201912
  • release/201911
  • release/releaseWindowsTestOne
  • release/windowsReleaseTest
  • release/releaseTest
  • release/releaseWindowsTest
  • release/201910
  • release/qt/201910
  • release/windows-test/201910
  • release/201908
  • release/201906
  • release/201905
  • release/201904
  • release/201903
  • release/201902
  • release/201901
  • release/201812
  • 4.0.0
  • 2.2.0
  • 2.1.0
  • 2.0.1
  • 2.0.0
  • 1.4.1
  • 1.4.0
  • 1.3.0
  • 1.2.0
  • 1.1.0
30 results

media_buffer.cpp

Blame
    • Philippe Gorley's avatar
      c2bfe7cc
      video: replace yuv422_clear_to_black · c2bfe7cc
      Philippe Gorley authored
      FFmpeg's av_image_fill_black supports more pixel formats.
      
      Works around casting int* to ptrdiff_t* on platforms where ptrdiff_t
      is not the same size as int by recreating the linesize array.
      
      Change-Id: I2825b18c6acc921a3cd3bb1398565df0aa657153
      c2bfe7cc
      History
      video: replace yuv422_clear_to_black
      Philippe Gorley authored
      FFmpeg's av_image_fill_black supports more pixel formats.
      
      Works around casting int* to ptrdiff_t* on platforms where ptrdiff_t
      is not the same size as int by recreating the linesize array.
      
      Change-Id: I2825b18c6acc921a3cd3bb1398565df0aa657153
    Code owners
    Assign users and groups as approvers for specific file changes. Learn more.
    media_buffer.cpp 4.26 KiB
    /*
     *  Copyright (C) 2015-2018 Savoir-faire Linux Inc.
     *
     *  Author: Guillaume Roguez <Guillaume.Roguez@savoirfairelinux.com>
     *
     *  This program is free software; you can redistribute it and/or modify
     *  it under the terms of the GNU General Public License as published by
     *  the Free Software Foundation; either version 3 of the License, or
     *  (at your option) any later version.
     *
     *  This program is distributed in the hope that it will be useful,
     *  but WITHOUT ANY WARRANTY; without even the implied warranty of
     *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     *  GNU General Public License for more details.
     *
     *  You should have received a copy of the GNU General Public License
     *  along with this program; if not, write to the Free Software
     *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA.
     */
    
    #include "libav_deps.h" // MUST BE INCLUDED FIRST
    #include "libav_utils.h"
    #include "media_buffer.h"
    #include "dring/videomanager_interface.h"
    
    #include <new> // std::bad_alloc
    #include <cstdlib>
    #include <cstring> // std::memset
    #include <ciso646> // fix windows compiler bug
    
    namespace ring {
    
    MediaFrame::MediaFrame()
        : frame_ {av_frame_alloc(), [](AVFrame* frame){ av_frame_free(&frame); }}
    {
        if (not frame_)
            throw std::bad_alloc();
    }
    
    void
    MediaFrame::reset() noexcept
    {
        av_frame_unref(frame_.get());
    }
    
    #ifdef RING_VIDEO
    
    VideoFrame::~VideoFrame()
    {
        if (releaseBufferCb_)
            releaseBufferCb_(ptr_);
    }
    
    void
    VideoFrame::reset() noexcept
    {
        MediaFrame::reset();
    #if !USE_OLD_AVU
        allocated_ = false;
    #endif
        releaseBufferCb_ = {};
    }
    
    size_t
    VideoFrame::size() const noexcept
    {
        return videoFrameSize(format(), width(), height());
    }
    
    int
    VideoFrame::format() const noexcept
    {
        return libav_utils::ring_pixel_format(frame_->format);
    }
    
    int
    VideoFrame::width() const noexcept
    {
        return frame_->width;
    }
    
    int
    VideoFrame::height() const noexcept
    {
        return frame_->height;
    }
    
    void
    VideoFrame::setGeometry(int format, int width, int height) noexcept
    {
        frame_->format = libav_utils::libav_pixel_format(format);
        frame_->width = width;
        frame_->height = height;
    }
    
    void
    VideoFrame::reserve(int format, int width, int height)
    {
        auto libav_format = (AVPixelFormat)libav_utils::libav_pixel_format(format);
        auto libav_frame = frame_.get();
    
        if (allocated_) {
            // nothing to do if same properties
            if (width == libav_frame->width
                and height == libav_frame->height
                and libav_format == libav_frame->format)
    #if USE_OLD_AVU
            avpicture_free((AVPicture *) libav_frame);
    #else
            av_frame_unref(libav_frame);
    #endif
        }
    
        setGeometry(format, width, height);
        if (av_frame_get_buffer(libav_frame, 32))
            throw std::bad_alloc();
        allocated_ = true;
        releaseBufferCb_ = {};
    }
    
    void
    VideoFrame::setFromMemory(uint8_t* ptr, int format, int width, int height) noexcept
    {
        reset();
        setGeometry(format, width, height);
        if (not ptr)
            return;
        av_image_fill_arrays(frame_->data, frame_->linesize, (uint8_t*)ptr,
                             (AVPixelFormat)frame_->format, width, height, 1);
    }
    
    void
    VideoFrame::setFromMemory(uint8_t* ptr, int format, int width, int height,
                              std::function<void(uint8_t*)> cb) noexcept
    {
        setFromMemory(ptr, format, width, height);
        if (cb) {
            releaseBufferCb_ = cb;
            ptr_ = ptr;
        }
    }
    
    void
    VideoFrame::noise()
    {
        auto f = frame_.get();
        if (f->data[0] == nullptr)
            return;
        for (std::size_t i=0 ; i < size(); ++i) {
            f->data[0][i] = std::rand() & 255;
        }
    }
    
    VideoFrame&
    VideoFrame::operator =(const VideoFrame& src)
    {
        reserve(src.format(), src.width(), src.height());
        auto source = src.pointer();
        av_image_copy(frame_->data, frame_->linesize, (const uint8_t **)source->data,
                      source->linesize, (AVPixelFormat)frame_->format,
                      frame_->width, frame_->height);
        return *this;
    }
    
    //=== HELPERS ==================================================================
    
    std::size_t
    videoFrameSize(int format, int width, int height)
    {
        return av_image_get_buffer_size((AVPixelFormat)libav_utils::libav_pixel_format(format),
                                        width, height, 1);
    }
    
    #endif // RING_VIDEO
    
    } // namespace ring