Skip to content

Commit

Permalink
Add option for native deinterlace
Browse files Browse the repository at this point in the history
This option will try to set monitor to matching interlaced hdmi mode and will try to output fields correctly so display can handle deinterlace.
It will only work in limited situations:
  The framerate must be supported by display
  The resolution must exactly match display
  All frames must have same interlace flags and be encoded as a pair of weaved fields

Requires updated firmware
  • Loading branch information
popcornmix committed Jun 26, 2014
1 parent af3d8be commit fe1ca6e
Show file tree
Hide file tree
Showing 2 changed files with 22 additions and 5 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ Using OMXPlayer
-p / --passthrough audio passthrough
-d / --deinterlace force deinterlacing
--nodeinterlace force no deinterlacing
--nativedeinterlace Let display handle interlace
--anaglyph type Convert 3d to anaglyph
-w / --hw hw audio decoding
-3 / --3d mode switch tv into 3d mode (e.g. SBS/TB)
Expand Down
26 changes: 21 additions & 5 deletions omxplayer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@ long m_Volume = 0;
long m_Amplification = 0;
bool m_Deinterlace = false;
bool m_NoDeinterlace = false;
bool m_NativeDeinterlace = false;
OMX_IMAGEFILTERANAGLYPHTYPE m_anaglyph = OMX_ImageFilterAnaglyphNone;
bool m_HWDecode = false;
std::string deviceString = "";
Expand Down Expand Up @@ -162,6 +163,7 @@ void print_usage()
printf(" -p / --passthrough audio passthrough\n");
printf(" -d / --deinterlace force deinterlacing\n");
printf(" --nodeinterlace force no deinterlacing\n");
printf(" --nativedeinterlace Let display handle interlace\n");
printf(" --anaglyph type Convert 3d to anaglyph\n");
printf(" -w / --hw hw audio decoding\n");
printf(" -3 / --3d mode switch tv into 3d mode (e.g. SBS/TB)\n");
Expand Down Expand Up @@ -388,7 +390,7 @@ void SetVideoMode(int width, int height, int fpsrate, int fpsscale, FORMAT_3D_T
if (num_modes > 0 && prefer_group != HDMI_RES_GROUP_INVALID)
{
uint32_t best_score = 1<<30;
uint32_t scan_mode = 0;
uint32_t scan_mode = m_NativeDeinterlace;

for (i=0; i<num_modes; i++)
{
Expand All @@ -404,7 +406,7 @@ void SetVideoMode(int width, int height, int fpsrate, int fpsscale, FORMAT_3D_T
else if(fabs(r - 2.0f*fps) / fps < 0.002f)
score += 1<<8;
else
score += (1<<28)/r; // bad - but prefer higher framerate
score += (1<<16) + (1<<20)/r; // bad - but prefer higher framerate

/* Check size too, only choose, bigger resolutions */
if(width && height)
Expand Down Expand Up @@ -448,12 +450,15 @@ void SetVideoMode(int width, int height, int fpsrate, int fpsscale, FORMAT_3D_T

if(tv_found)
{
char response[80];
printf("Output mode %d: %dx%d@%d %s%s:%x\n", tv_found->code, tv_found->width, tv_found->height,
tv_found->frame_rate, tv_found->native?"N":"", tv_found->scan_mode?"I":"", tv_found->code);
if (m_NativeDeinterlace && tv_found->scan_mode)
vc_gencmd(response, sizeof response, "hvs_update_fields %d", 1);

// if we are closer to ntsc version of framerate, let gpu know
int ifps = (int)(fps+0.5f);
bool ntsc_freq = fabs(fps*1001.0f/1000.0f - ifps) < fabs(fps-ifps);
char response[80];
vc_gencmd(response, sizeof response, "hdmi_ntsc_freqs %d", ntsc_freq);

/* inform TV of any 3D settings. Note this property just applies to next hdmi mode change, so no need to call for 2D modes */
Expand Down Expand Up @@ -631,6 +636,7 @@ int main(int argc, char *argv[])
const int layer_opt = 0x20b;
const int no_keys_opt = 0x20c;
const int anaglyph_opt = 0x20d;
const int native_deinterlace_opt = 0x20e;

struct option longopts[] = {
{ "info", no_argument, NULL, 'i' },
Expand All @@ -645,6 +651,7 @@ int main(int argc, char *argv[])
{ "amp", required_argument, NULL, amp_opt },
{ "deinterlace", no_argument, NULL, 'd' },
{ "nodeinterlace",no_argument, NULL, no_deinterlace_opt },
{ "nativedeinterlace",no_argument, NULL, native_deinterlace_opt },
{ "anaglyph", required_argument, NULL, anaglyph_opt },
{ "hw", no_argument, NULL, 'w' },
{ "3d", required_argument, NULL, '3' },
Expand Down Expand Up @@ -730,6 +737,10 @@ int main(int argc, char *argv[])
case no_deinterlace_opt:
m_NoDeinterlace = true;
break;
case native_deinterlace_opt:
m_NoDeinterlace = true;
m_NativeDeinterlace = true;
break;
case anaglyph_opt:
m_anaglyph = (OMX_IMAGEFILTERANAGLYPHTYPE)atoi(optarg);
break;
Expand Down Expand Up @@ -1029,11 +1040,11 @@ int main(int argc, char *argv[])
m_3d = CONF_FLAGS_FORMAT_TB;

// 3d modes don't work without switch hdmi mode
if (m_3d != CONF_FLAGS_FORMAT_NONE)
if (m_3d != CONF_FLAGS_FORMAT_NONE || m_NativeDeinterlace)
m_refresh = true;

// you really don't want want to match refresh rate without hdmi clock sync
if (m_refresh && !m_no_hdmi_clock_sync)
if ((m_refresh || m_NativeDeinterlace) && !m_no_hdmi_clock_sync)
m_hdmi_clock_sync = true;

if(!m_av_clock->OMXInitialize())
Expand Down Expand Up @@ -1772,6 +1783,11 @@ int main(int argc, char *argv[])
printf("Stopped at: %02d:%02d:%02d\n", (t/3600), (t/60)%60, t%60);
}

if (m_NativeDeinterlace)
{
char response[80];
vc_gencmd(response, sizeof response, "hvs_update_fields %d", 0);
}
if(m_has_video && m_refresh && tv_state.display.hdmi.group && tv_state.display.hdmi.mode)
{
m_BcmHost.vc_tv_hdmi_power_on_explicit_new(HDMI_MODE_HDMI, (HDMI_RES_GROUP_T)tv_state.display.hdmi.group, tv_state.display.hdmi.mode);
Expand Down

0 comments on commit fe1ca6e

Please sign in to comment.