Skip to content

Commit

Permalink
Fixes #11358. Use dimension and cropping information from the video.
Browse files Browse the repository at this point in the history
This helps avoid hard-coding of 1088->1080 truncation and manual
rounding up to a multiple of 16.  There are still many instances in
the code base, but this is progress.

Cropping in the horizontal dimension is not yet implemented.

There is still some funny business with slightly changing aspect
ratios that needs further investigation.
  • Loading branch information
stichnot committed Mar 5, 2013
1 parent 7e7e51c commit 0a4e3e4
Show file tree
Hide file tree
Showing 24 changed files with 257 additions and 159 deletions.
38 changes: 0 additions & 38 deletions mythtv/libs/libmythtv/filtermanager.cpp
Expand Up @@ -53,49 +53,11 @@ FilterChain::~FilterChain()
filters.clear();
}

// Applies a crop filter, modifed from filter_crop.c, to crop the
// bottom 8 lines of a 1088-line frame, which often contains garbage.
static void crop1088(VideoFrame *frame)
{
if (frame->height != 1088)
return;
if (frame->width != 1920 && frame->width != 1440)
return;
if (frame->pitches[1] != frame->pitches[2])
return;
// assume input and output formats are FMT_YV12
uint64_t *ybuf = (uint64_t*) (frame->buf + frame->offsets[0]);
uint64_t *ubuf = (uint64_t*) (frame->buf + frame->offsets[1]);
uint64_t *vbuf = (uint64_t*) (frame->buf + frame->offsets[2]);
const uint64_t Y_black = 0x0000000000000000LL; // 8 bytes
const uint64_t UV_black = 0x8080808080808080LL; // 8 bytes
int y;
int sz = (frame->pitches[0] * frame->height) >> 3; // div 8 bytes
// Luma bottom
y = ((frame->height >> 4) - 1) * frame->pitches[0] << 1;
y = (y + sz) / 2;
for (; y < sz; y++)
{
ybuf[y] = Y_black;
}
// Chroma bottom
sz = (frame->pitches[1] * (frame->height >> 1)) >> 3; // div 8 bytes
y = ((frame->height >> 4) - 1) * frame->pitches[1];
y = (y + sz) / 2;
for (; y < sz; y++)
{
ubuf[y] = UV_black;
vbuf[y] = UV_black;
}
}

void FilterChain::ProcessFrame(VideoFrame *frame, FrameScanType scan)
{
if (!frame)
return;

crop1088(frame);

vector<VideoFilter*>::iterator it = filters.begin();
for (; it != filters.end(); ++it)
(*it)->filter(*it, frame, kScan_Intr2ndField == scan);
Expand Down
4 changes: 2 additions & 2 deletions mythtv/libs/libmythtv/mythplayer.cpp
Expand Up @@ -484,7 +484,7 @@ bool MythPlayer::InitVideo(void)
decoder->GetCodecDecoderName(),
decoder->GetVideoCodecID(),
decoder->GetVideoCodecPrivate(),
pipState, video_disp_dim, video_aspect,
pipState, video_dim, video_disp_dim, video_aspect,
parentWidget, embedRect,
video_frame_rate, (uint)playerFlags);

Expand Down Expand Up @@ -588,7 +588,7 @@ void MythPlayer::ReinitVideo(void)
videoOutput->SetVideoFrameRate(video_frame_rate);
float aspect = (forced_video_aspect > 0) ? forced_video_aspect :
video_aspect;
if (!videoOutput->InputChanged(video_disp_dim, aspect,
if (!videoOutput->InputChanged(video_dim, video_disp_dim, aspect,
decoder->GetVideoCodecID(),
decoder->GetVideoCodecPrivate(),
aspect_only))
Expand Down
23 changes: 15 additions & 8 deletions mythtv/libs/libmythtv/videoout_d3d.cpp
Expand Up @@ -131,7 +131,8 @@ void VideoOutputD3D::WindowResized(const QSize &new_size)
*/
}

bool VideoOutputD3D::InputChanged(const QSize &input_size,
bool VideoOutputD3D::InputChanged(const QSize &video_dim_buf,
const QSize &video_dim_disp,
float aspect,
MythCodecID av_codec_id,
void *codec_private,
Expand All @@ -145,12 +146,12 @@ bool VideoOutputD3D::InputChanged(const QSize &input_size,
QString("InputChanged from %1: %2x%3 aspect %4 to %5: %6x%7 aspect %9")
.arg(toString(video_codec_id)).arg(cursize.width())
.arg(cursize.height()).arg(window.GetVideoAspect())
.arg(toString(av_codec_id)).arg(input_size.width())
.arg(input_size.height()).arg(aspect));
.arg(toString(av_codec_id)).arg(video_dim_disp.width())
.arg(video_dim_disp.height()).arg(aspect));


bool cid_changed = (video_codec_id != av_codec_id);
bool res_changed = input_size != cursize;
bool res_changed = video_dim_disp != cursize;
bool asp_changed = aspect != window.GetVideoAspect();

if (!res_changed && !cid_changed)
Expand All @@ -166,7 +167,7 @@ bool VideoOutputD3D::InputChanged(const QSize &input_size,

TearDown();
QRect disp = window.GetDisplayVisibleRect();
if (Init(input_size.width(), input_size.height(),
if (Init(video_dim_buf, video_dim_disp,
aspect, m_hWnd, disp, av_codec_id))
{
BestDeint();
Expand Down Expand Up @@ -199,7 +200,9 @@ bool VideoOutputD3D::SetupContext()
return true;
}

bool VideoOutputD3D::Init(int width, int height, float aspect, WId winid,
bool VideoOutputD3D::Init(const QSize &video_dim_buf,
const QSize &video_dim_disp,
float aspect, WId winid,
const QRect &win_rect,MythCodecID codec_id)
{
MythPainter *painter = GetMythPainter();
Expand All @@ -210,15 +213,17 @@ bool VideoOutputD3D::Init(int width, int height, float aspect, WId winid,
m_hWnd = winid;
window.SetAllowPreviewEPG(true);

VideoOutput::Init(width, height, aspect, winid, win_rect, codec_id);
VideoOutput::Init(video_dim_buf, video_dim_disp,
aspect, winid, win_rect, codec_id);

LOG(VB_PLAYBACK, LOG_INFO, LOC + QString("Init with codec: %1")
.arg(toString(codec_id)));
SetProfile();

bool success = true;
success &= SetupContext();
InitDisplayMeasurements(width, height, false);
InitDisplayMeasurements(video_dim_disp.width(), video_dim_disp.height(),
false);

if (codec_is_dxva2(video_codec_id))
{
Expand Down Expand Up @@ -540,6 +545,8 @@ void VideoOutputD3D::ProcessFrame(VideoFrame *frame, OSD *osd,
pauseframe = true;
}

CropToDisplay(frame);

if (frame)
dummy = frame->dummy;
bool deint_proc = m_deinterlacing && (m_deintFilter != NULL) &&
Expand Down
7 changes: 5 additions & 2 deletions mythtv/libs/libmythtv/videoout_d3d.h
Expand Up @@ -19,7 +19,9 @@ class VideoOutputD3D : public VideoOutput
VideoOutputD3D();
~VideoOutputD3D();

bool Init(int width, int height, float aspect,
bool Init(const QSize &video_dim_buf,
const QSize &video_dim_disp,
float aspect,
WId winid, const QRect &win_rect, MythCodecID codec_id);
void PrepareFrame(VideoFrame *buffer, FrameScanType, OSD *osd);
void ProcessFrame(VideoFrame *frame, OSD *osd,
Expand All @@ -28,7 +30,8 @@ class VideoOutputD3D : public VideoOutput
FrameScanType scan);
void Show(FrameScanType );
void WindowResized(const QSize &new_size);
bool InputChanged(const QSize &input_size,
bool InputChanged(const QSize &video_dim_buf,
const QSize &video_dim_disp,
float aspect,
MythCodecID av_codec_id,
void *codec_private,
Expand Down
22 changes: 14 additions & 8 deletions mythtv/libs/libmythtv/videoout_null.cpp
Expand Up @@ -76,16 +76,17 @@ void VideoOutputNull::CreatePauseFrame(void)
clear(&av_pause_frame);
}

bool VideoOutputNull::InputChanged(const QSize &input_size,
bool VideoOutputNull::InputChanged(const QSize &video_dim_buf,
const QSize &video_dim_disp,
float aspect,
MythCodecID av_codec_id,
void *codec_private,
bool &aspect_only)
{
LOG(VB_PLAYBACK, LOG_INFO,
QString("InputChanged(WxH = %1x%2, aspect = %3)")
.arg(input_size.width())
.arg(input_size.height()).arg(aspect));
.arg(video_dim_disp.width())
.arg(video_dim_disp.height()).arg(aspect));

if (!codec_is_std(av_codec_id))
{
Expand All @@ -97,14 +98,15 @@ bool VideoOutputNull::InputChanged(const QSize &input_size,

QMutexLocker locker(&global_lock);

if (input_size == window.GetActualVideoDim())
if (video_dim_disp == window.GetActualVideoDim())
{
vbuffers.Clear();
MoveResize();
return true;
}

VideoOutput::InputChanged(input_size, aspect, av_codec_id, codec_private,
VideoOutput::InputChanged(video_dim_buf, video_dim_disp,
aspect, av_codec_id, codec_private,
aspect_only);
vbuffers.DeleteBuffers();

Expand All @@ -131,10 +133,12 @@ bool VideoOutputNull::InputChanged(const QSize &input_size,
return ok;
}

bool VideoOutputNull::Init(int width, int height, float aspect, WId winid,
bool VideoOutputNull::Init(const QSize &video_dim_buf,
const QSize &video_dim_disp,
float aspect, WId winid,
const QRect &win_rect, MythCodecID codec_id)
{
if ((width <= 0) || (height <= 0))
if ((video_dim_disp.width() <= 0) || (video_dim_disp.height() <= 0))
return false;

if (!codec_is_std(codec_id))
Expand All @@ -147,12 +151,14 @@ bool VideoOutputNull::Init(int width, int height, float aspect, WId winid,

QMutexLocker locker(&global_lock);

VideoOutput::Init(width, height, aspect, winid, win_rect, codec_id);
VideoOutput::Init(video_dim_buf, video_dim_disp,
aspect, winid, win_rect, codec_id);

vbuffers.Init(kNumBuffers, true, kNeedFreeFrames,
kPrebufferFramesNormal, kPrebufferFramesSmall,
kKeepPrebuffer);

// XXX should this be GetActualVideoDim() ?
const QSize video_dim = window.GetVideoDim();

if (!vbuffers.CreateBuffers(FMT_YV12, video_dim.width(), video_dim.height()))
Expand Down
7 changes: 5 additions & 2 deletions mythtv/libs/libmythtv/videoout_null.h
Expand Up @@ -12,14 +12,17 @@ class VideoOutputNull : public VideoOutput
VideoOutputNull();
~VideoOutputNull();

bool Init(int width, int height, float aspect,
bool Init(const QSize &video_dim_buf,
const QSize &video_dim_disp,
float aspect,
WId winid, const QRect &win_rect, MythCodecID codec_id);
bool SetupDeinterlace(bool, const QString &ovrf = "")
{ (void)ovrf; return false; } // we don't deinterlace in null output..
void PrepareFrame(VideoFrame *buffer, FrameScanType, OSD *osd);
void Show(FrameScanType );
void CreatePauseFrame(void);
bool InputChanged(const QSize &input_size,
bool InputChanged(const QSize &video_dim_buf,
const QSize &video_dim_disp,
float aspect,
MythCodecID av_codec_id,
void *codec_private,
Expand Down
17 changes: 11 additions & 6 deletions mythtv/libs/libmythtv/videoout_nullvaapi.cpp
Expand Up @@ -117,12 +117,15 @@ QStringList VideoOutputNullVAAPI::GetAllowedRenderers(MythCodecID myth_codec_id)
return list;
}

bool VideoOutputNullVAAPI::Init(int width, int height, float aspect,
bool VideoOutputNullVAAPI::Init(const QSize &video_dim_buf,
const QSize &video_dim_disp,
float aspect,
WId winid, const QRect &win_rect,
MythCodecID codec_id)
{
QMutexLocker locker(&m_lock);
bool ok = VideoOutput::Init(width, height, aspect, winid, win_rect, codec_id);
bool ok = VideoOutput::Init(video_dim_buf, video_dim_disp,
aspect, winid, win_rect, codec_id);
if (!codec_is_vaapi_hw(video_codec_id))
return false;

Expand All @@ -138,21 +141,23 @@ bool VideoOutputNullVAAPI::Init(int width, int height, float aspect,
return ok;
}

bool VideoOutputNullVAAPI::InputChanged(const QSize &input_size,
bool VideoOutputNullVAAPI::InputChanged(const QSize &video_dim_buf,
const QSize &video_dim_disp,
float aspect,
MythCodecID av_codec_id,
void *codec_private,
bool &aspect_only)
{
LOG(VB_PLAYBACK, LOG_INFO, LOC +
QString("InputChanged(%1,%2,%3) '%4'->'%5'")
.arg(input_size.width()).arg(input_size.height()).arg(aspect)
.arg(video_dim_disp.width()).arg(video_dim_disp.height())
.arg(aspect)
.arg(toString(video_codec_id)).arg(toString(av_codec_id)));

QMutexLocker locker(&m_lock);

bool cid_changed = (video_codec_id != av_codec_id);
bool res_changed = input_size != window.GetActualVideoDim();
bool res_changed = video_dim_disp != window.GetActualVideoDim();
if (!res_changed && !cid_changed)
{
aspect_only = true;
Expand All @@ -161,7 +166,7 @@ bool VideoOutputNullVAAPI::InputChanged(const QSize &input_size,

TearDown();
QRect disp = window.GetDisplayVisibleRect();
if (Init(input_size.width(), input_size.height(),
if (Init(video_dim_buf, video_dim_disp,
aspect, 0, disp, av_codec_id))
{
return true;
Expand Down
7 changes: 5 additions & 2 deletions mythtv/libs/libmythtv/videoout_nullvaapi.h
Expand Up @@ -14,9 +14,12 @@ class VideoOutputNullVAAPI : public VideoOutput
~VideoOutputNullVAAPI();

virtual void* GetDecoderContext(unsigned char* buf, uint8_t*& id);
virtual bool Init(int width, int height, float aspect, WId winid,
virtual bool Init(const QSize &video_dim_buf,
const QSize &video_dim_disp,
float aspect, WId winid,
const QRect &win_rect, MythCodecID codec_id);
virtual bool InputChanged(const QSize &input_size,
virtual bool InputChanged(const QSize &video_dim_buf,
const QSize &video_dim_disp,
float aspect,
MythCodecID av_codec_id,
void *codec_private,
Expand Down
17 changes: 11 additions & 6 deletions mythtv/libs/libmythtv/videoout_nullvdpau.cpp
Expand Up @@ -44,12 +44,15 @@ void VideoOutputNullVDPAU::TearDown(void)
DeleteRender();
}

bool VideoOutputNullVDPAU::Init(int width, int height, float aspect,
bool VideoOutputNullVDPAU::Init(const QSize &video_dim_buf,
const QSize &video_dim_disp,
float aspect,
WId winid, const QRect &win_rect,
MythCodecID codec_id)
{
QMutexLocker locker(&m_lock);
bool ok = VideoOutput::Init(width, height, aspect, winid, win_rect, codec_id);
bool ok = VideoOutput::Init(video_dim_buf, video_dim_disp,
aspect, winid, win_rect, codec_id);
if (!codec_is_vdpau_hw(video_codec_id))
return false;

Expand Down Expand Up @@ -516,21 +519,23 @@ void VideoOutputNullVDPAU::ReleaseFrame(VideoFrame *frame)
VideoOutput::ReleaseFrame(frame);
}

bool VideoOutputNullVDPAU::InputChanged(const QSize &input_size,
bool VideoOutputNullVDPAU::InputChanged(const QSize &video_dim_buf,
const QSize &video_dim_disp,
float aspect,
MythCodecID av_codec_id,
void *codec_private,
bool &aspect_only)
{
LOG(VB_PLAYBACK, LOG_INFO, LOC +
QString("InputChanged(%1,%2,%3) '%4'->'%5'")
.arg(input_size.width()).arg(input_size.height()).arg(aspect)
.arg(video_dim_disp.width()).arg(video_dim_disp.height())
.arg(aspect)
.arg(toString(video_codec_id)).arg(toString(av_codec_id)));

QMutexLocker locker(&m_lock);

bool cid_changed = (video_codec_id != av_codec_id);
bool res_changed = input_size != window.GetActualVideoDim();
bool res_changed = video_dim_disp != window.GetActualVideoDim();

if (!res_changed && !cid_changed)
{
Expand All @@ -540,7 +545,7 @@ bool VideoOutputNullVDPAU::InputChanged(const QSize &input_size,

TearDown();
QRect disp = window.GetDisplayVisibleRect();
if (Init(input_size.width(), input_size.height(),
if (Init(video_dim_buf, video_dim_disp,
aspect, 0, disp, av_codec_id))
{
return true;
Expand Down
7 changes: 5 additions & 2 deletions mythtv/libs/libmythtv/videoout_nullvdpau.h
Expand Up @@ -35,9 +35,12 @@ class VideoOutputNullVDPAU : public VideoOutput
VideoOutputNullVDPAU();
~VideoOutputNullVDPAU();

virtual bool Init(int width, int height, float aspect, WId winid,
virtual bool Init(const QSize &video_dim_buf,
const QSize &video_dim_disp,
float aspect, WId winid,
const QRect &win_rect, MythCodecID codec_id);
virtual bool InputChanged(const QSize &input_size,
virtual bool InputChanged(const QSize &video_dim_buf,
const QSize &video_dim_disp,
float aspect,
MythCodecID av_codec_id,
void *codec_private,
Expand Down

0 comments on commit 0a4e3e4

Please sign in to comment.