Skip to content

Commit

Permalink
fixup: MMALFFmpeg: Add Sand/YUVUV128 support
Browse files Browse the repository at this point in the history
  • Loading branch information
popcornmix committed May 22, 2017
1 parent 7600a75 commit 7d2dc0a
Show file tree
Hide file tree
Showing 4 changed files with 54 additions and 38 deletions.
3 changes: 3 additions & 0 deletions xbmc/cores/VideoPlayer/DVDCodecs/Video/MMALCodec.h
Expand Up @@ -41,6 +41,7 @@
#include "rendering/RenderSystem.h"
#include "cores/VideoPlayer/VideoRenderers/BaseRenderer.h"
#include "cores/VideoPlayer/DVDResource.h"
#include "linux/RBP.h"


enum MMALState { MMALStateNone, MMALStateHWDec, MMALStateFFDec, MMALStateDeint, };
Expand All @@ -60,6 +61,8 @@ class CMMALBuffer : public IDVDResourceCounted<CMMALBuffer>
unsigned int m_height;
unsigned int m_aligned_width;
unsigned int m_aligned_height;
unsigned int m_size;
AVRpiZcFrameGeometry m_geo;
uint32_t m_encoding;
float m_aspect_ratio;
MMALState m_state;
Expand Down
39 changes: 19 additions & 20 deletions xbmc/cores/VideoPlayer/DVDCodecs/Video/MMALFFmpeg.cpp
Expand Up @@ -61,17 +61,17 @@ CMMALYUVBuffer::CMMALYUVBuffer(CDecoder *omv, std::shared_ptr<CMMALPool> pool, u
m_rendered = false;
m_stills = false;

const AVRpiZcFrameGeometry geo = g_RBP.GetFrameGeometry(m_encoding, width, height);
const unsigned int size_y = geo.stride_y * geo.height_y;
const unsigned int size_c = geo.stride_c * geo.height_c;
unsigned int size_pic = (size_y + size_c * geo.planes_c) * geo.stripes;
assert(size_pic > 0);
if (size)
if (size == 0)
{
assert(size_pic <= size);
size_pic = size;
m_geo = g_RBP.GetFrameGeometry(m_encoding, aligned_width, aligned_height);
const unsigned int size_y = m_geo.stride_y * m_geo.height_y;
const unsigned int size_c = m_geo.stride_c * m_geo.height_c;
m_size = (size_y + size_c * m_geo.planes_c) * m_geo.stripes;
}
gmem = m_pool->AllocateBuffer(size_pic);
else
m_size = size;
assert(m_size > 0);
gmem = m_pool->AllocateBuffer(m_size);
if (gmem)
gmem->m_opaque = (void *)this;
if (VERBOSE && g_advancedSettings.CanLogComponent(LOGVIDEO))
Expand Down Expand Up @@ -175,11 +175,7 @@ int CDecoder::FFGetBuffer(AVCodecContext *avctx, AVFrame *frame, int flags)

CSingleLock lock(dec->m_section);
CGPUMEM *gmem = YUVBuffer->gmem;
const AVRpiZcFrameGeometry geo = g_RBP.GetFrameGeometry(mmal_format, frame->width, frame->height);
const unsigned int size_y = geo.stride_y * geo.height_y;
const unsigned int size_c = geo.stride_c * geo.height_c;
const unsigned int size_pic = (size_y + size_c * geo.planes_c) * geo.stripes;
AVBufferRef *buf = av_buffer_create((uint8_t *)gmem->m_arm, size_pic, CDecoder::FFReleaseBuffer, gmem, AV_BUFFER_FLAG_READONLY);
AVBufferRef *buf = av_buffer_create((uint8_t *)gmem->m_arm, YUVBuffer->m_size, CDecoder::FFReleaseBuffer, gmem, AV_BUFFER_FLAG_READONLY);
if (!buf)
{
CLog::Log(LOGERROR, "%s::%s av_buffer_create() failed", CLASSNAME, __FUNCTION__);
Expand All @@ -206,17 +202,20 @@ int CDecoder::FFGetBuffer(AVCodecContext *avctx, AVFrame *frame, int flags)
}
else if (frame->format == AV_PIX_FMT_SAND128)
{
const unsigned int size_y = YUVBuffer->m_geo.stride_y * YUVBuffer->m_geo.height_y;
const unsigned int size_c = YUVBuffer->m_geo.stride_c * YUVBuffer->m_geo.height_c;

frame->buf[0] = buf;

frame->linesize[0] = geo.stride_y;
frame->linesize[1] = geo.stride_c;
frame->linesize[2] = geo.stride_c;
if (geo.stripes > 1)
frame->linesize[3] = geo.height_y + geo.height_c; // abuse: linesize[3] = stripe stride
frame->linesize[0] = YUVBuffer->m_geo.stride_y;
frame->linesize[1] = YUVBuffer->m_geo.stride_c;
frame->linesize[2] = YUVBuffer->m_geo.stride_c;
if (YUVBuffer->m_geo.stripes > 1)
frame->linesize[3] = YUVBuffer->m_geo.height_y + YUVBuffer->m_geo.height_c; // abuse: linesize[3] = stripe stride

frame->data[0] = (uint8_t *)gmem->m_arm;
frame->data[1] = frame->data[0] + size_y;
if (geo.planes_c > 1)
if (YUVBuffer->m_geo.planes_c > 1)
frame->data[2] = frame->data[1] + size_c;

frame->extended_data = frame->data;
Expand Down
38 changes: 26 additions & 12 deletions xbmc/linux/RBP.cpp
Expand Up @@ -456,18 +456,32 @@ AVRpiZcFrameGeometry CRBP::GetFrameGeometry(uint32_t encoding, unsigned short vi
{
AVRpiZcFrameGeometry geo = {};
struct VC_IMAGE_T img = {};
img.type = encoding == MMAL_ENCODING_YUVUV128 ? VC_IMAGE_YUV_UV : encoding == MMAL_ENCODING_I420 ? VC_IMAGE_YUV420 : 0;
img.width = video_width;
img.height = video_height;
int rc = get_image_params(GetMBox(), &img);
assert(rc == 0);
const unsigned int stripe_w = 128;
geo.stride_y = stripe_w;
geo.stride_c = stripe_w;
geo.height_y = ((intptr_t)img.extra.uv.u - (intptr_t)img.image_data) / stripe_w;
geo.height_c = img.pitch / stripe_w - geo.height_y;
geo.planes_c = 1;
geo.stripes = (video_width + stripe_w - 1) / stripe_w;

if (encoding == MMAL_ENCODING_YUVUV128)
{
img.type = VC_IMAGE_YUV_UV;
img.width = video_width;
img.height = video_height;
int rc = get_image_params(GetMBox(), &img);
assert(rc == 0);
const unsigned int stripe_w = 128;
geo.stride_y = stripe_w;
geo.stride_c = stripe_w;
geo.height_y = ((intptr_t)img.extra.uv.u - (intptr_t)img.image_data) / stripe_w;
geo.height_c = img.pitch / stripe_w - geo.height_y;
geo.planes_c = 1;
geo.stripes = (video_width + stripe_w - 1) / stripe_w;
}
else if (encoding == MMAL_ENCODING_I420)
{
geo.stride_y = (video_width + 31) & ~31;
geo.stride_c = geo.stride_y / 2;
geo.height_y = (video_height + 15) & ~15;
geo.height_c = geo.height_y / 2;
geo.planes_c = 2;
geo.stripes = 1;
}
else assert(0);
return geo;
}

Expand Down
12 changes: 6 additions & 6 deletions xbmc/linux/RBP.h
Expand Up @@ -43,12 +43,12 @@

typedef struct AVRpiZcFrameGeometry
{
unsigned int stride_y;
unsigned int height_y;
unsigned int stride_c;
unsigned int height_c;
unsigned int planes_c;
unsigned int stripes;
unsigned int stride_y;
unsigned int height_y;
unsigned int stride_c;
unsigned int height_c;
unsigned int planes_c;
unsigned int stripes;
} AVRpiZcFrameGeometry;

class CGPUMEM
Expand Down

0 comments on commit 7d2dc0a

Please sign in to comment.