Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[GUI] search scene change + shortcuts for black frame search #372

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions avidemux/common/ADM_commonUI/myOwnMenu.h
Original file line number Diff line number Diff line change
Expand Up @@ -137,8 +137,10 @@ static const MenuEntry _myMenuGo[] = {
{MENU_ACTION,QT_TRANSLATE_NOOP("adm","Next Intra Frame"), NULL,ACT_NextKFrame, MKICON(player_fwd), "Up",0},
{MENU_ACTION,QT_TRANSLATE_NOOP("adm","Previous Cut Point"), NULL,ACT_PrevCutPoint, MKICON(prev_cut), NULL,0},
{MENU_ACTION,QT_TRANSLATE_NOOP("adm","Next Cut Point"), NULL,ACT_NextCutPoint, MKICON(next_cut), NULL,0},
{MENU_ACTION,QT_TRANSLATE_NOOP("adm","Previous Black Frame"),NULL,ACT_PrevBlackFrame, MKICON(prev_black), NULL,0},
{MENU_ACTION,QT_TRANSLATE_NOOP("adm","Next Black Frame"), NULL,ACT_NextBlackFrame, MKICON(next_black), NULL,0},
{MENU_ACTION,QT_TRANSLATE_NOOP("adm","Previous Scene Change"),NULL,ACT_PrevSceneChange, MKICON(prev_scd), "Alt+Left",0},
{MENU_ACTION,QT_TRANSLATE_NOOP("adm","Next Scene Change"), NULL,ACT_NextSceneChange, MKICON(next_scd), "Alt+Right",0},
{MENU_ACTION,QT_TRANSLATE_NOOP("adm","Previous Black Frame"),NULL,ACT_PrevBlackFrame, MKICON(prev_black), "Alt+Shift+Left",0},
{MENU_ACTION,QT_TRANSLATE_NOOP("adm","Next Black Frame"), NULL,ACT_NextBlackFrame, MKICON(next_black), "Alt+Shift+Right",0},
{MENU_ACTION,QT_TRANSLATE_NOOP("adm","First Frame"), NULL,ACT_Begin, MKICON(player_start), "Home",0},
{MENU_ACTION,QT_TRANSLATE_NOOP("adm","Last Frame"), NULL,ACT_End, MKICON(player_end), "End",0},
{MENU_SEPARATOR,"-",NULL,ACT_DUMMY,NULL,NULL,1},
Expand Down
2 changes: 2 additions & 0 deletions avidemux/common/gtkgui.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ bool GUI_PreviousKeyFrame(void);
bool GUI_GoToTime(uint64_t time);
uint8_t GUI_close(void);

void GUI_PrevSceneChange();
void GUI_NextSceneChange();
void GUI_PrevBlackFrame(void);
void GUI_NextBlackFrame( ) ;
void GUI_NextPrevBlackFrame( int ) ;
Expand Down
2 changes: 2 additions & 0 deletions avidemux/common/gui_action.names
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,8 @@ ACT(PreviousKFrame)
ACT(PreviousFrame)
ACT(PrevCutPoint)
ACT(NextCutPoint)
ACT(PrevSceneChange)
ACT(NextSceneChange)
ACT(PrevBlackFrame)
ACT(NextBlackFrame)
ACT(Goto)
Expand Down
6 changes: 6 additions & 0 deletions avidemux/common/gui_navigate.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -267,6 +267,12 @@ static int ignore_change=0;
case ACT_NextCutPoint:
GUI_NextCutPoint();
break;
case ACT_PrevSceneChange:
GUI_PrevSceneChange();
break;
case ACT_NextSceneChange:
GUI_NextSceneChange();
break;
case ACT_NextBlackFrame:
GUI_NextBlackFrame();
break;
Expand Down
251 changes: 251 additions & 0 deletions avidemux/common/gui_scenechange.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,251 @@
/***************************************************************************
gui_scenechange.cpp - description
-------------------

Detect scene change


copyright : (C) 2002/2008 by mean
2021 szlldm
email : [email protected]
***************************************************************************/

/***************************************************************************
* *
* 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 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/

#include "ADM_cpp.h"
#include "avi_vars.h"

#include <math.h>

#include "DIA_fileSel.h"
#include "ADM_assert.h"
#include "prototype.h"
#include "audio_out.h"
#include "ADM_coreAudio.h"
#include "gui_action.hxx"
#include "gtkgui.h"
#include "DIA_coreToolkit.h"
#include "ADM_render/GUI_render.h"
#include "DIA_working.h"
#include "DIA_processing.h"
#include "ADM_commonUI/DIA_busy.h"
#include "ADM_commonUI/GUI_ui.h"

#include "ADM_vidMisc.h"
#include "ADM_preview.h"

static float histogramGUISceneChange[64];

/**
\fn scChUtilCalcHisto
\brief Calculate histogram
*/
void scChUtilCalcHisto(ADMImage *img, float * hist)
{
uint32_t w,h;
int strides[3];
uint8_t * planes[3], *ptr1, *ptr2;
img->getWidthHeight(&w,&h);
img->GetPitches(strides);
img->GetReadPlanes(planes);

uint32_t tmpHist[64];
for (int i=0;i<64;i++)
tmpHist[i] = 0;

w /= 2;
h /= 2;
int u,v;
for (int y=0; y<h; y++)
{
ptr1 = planes[1] + y*strides[1];
ptr2 = planes[2] + y*strides[2];
for (int x=0; x<w; x++)
{
u = *ptr1++;
v = *ptr2++;
u /= 8;
v /= 8;
tmpHist[u]++;
tmpHist[v+32]++;
}
}

for (int i=0;i<64;i++)
{
hist[i] = tmpHist[i];
hist[i] /= w;
hist[i] /= h;
}
}

/**
\fn initSCeneChangeDetector
\brief Init Scene Change Detector
*/
void initSCeneChangeDetector(ADMImage *img)
{
scChUtilCalcHisto(img, histogramGUISceneChange);
}
/**
\fn isSCeneChange
\brief Scene Change Detector
*/
bool isSCeneChange(ADMImage *img)
{
float * hist = histogramGUISceneChange;
float nextHist[64];
scChUtilCalcHisto(img, nextHist);
float diff = 0;
for (int i=0; i<64; i++)
{
diff += fabs(hist[i] - nextHist[i]);
}
diff = sqrt(diff);

//printf("diff=%f\n",diff);
if (diff > 0.5)
return true;

// adapt histogram
for (int i=0; i<64; i++)
{
hist[i] = nextHist[i];
}

return false;
}

/**
\fn GUI_PrevSceneChange
*/
void GUI_PrevSceneChange(void)
{
if (playing)
return;
if (! avifileinfo)
return;

admPreview::deferDisplay(true);
ADMImage *rdr;

admPreview::samePicture();
rdr=admPreview::getBuffer();
if(rdr->refType!=ADM_HW_NONE) // need to convert it to plain YV12
{
if(false==rdr->hwDownloadFromRef())
{
ADM_warning("Cannot convert hw image to yv12\n");
admPreview::deferDisplay(false);
return;
}
}
initSCeneChangeDetector(rdr);

uint64_t startTime=admPreview::getCurrentPts();
DIA_processingBase *work=createProcessing(QT_TRANSLATE_NOOP("scenechange", "Searching scene change.."),startTime);

bool scFound=false;
while(1)
{
UI_purge();

if(false==admPreview::previousPicture())
break;
rdr=admPreview::getBuffer();
if(rdr->refType!=ADM_HW_NONE) // need to convert it to plain YV12
{
if(false==rdr->hwDownloadFromRef())
{
ADM_warning("Cannot convert hw image to yv12\n");
break;
}
}
if(isSCeneChange(rdr))
{
scFound = true;
break;
}
if(work->update(1,startTime-admPreview::getCurrentPts()))
break;
}
delete work;
if (!scFound)
admPreview::seekToTime(startTime);
admPreview::deferDisplay(false);
admPreview::samePicture();
GUI_setCurrentFrameAndTime();
return;
}

/**
\fn GUI_NextSceneChange
*/
void GUI_NextSceneChange(void)
{
if (playing)
return;
if (! avifileinfo)
return;

admPreview::deferDisplay(true);
ADMImage *rdr;

admPreview::samePicture();
rdr=admPreview::getBuffer();
if(rdr->refType!=ADM_HW_NONE) // need to convert it to plain YV12
{
if(false==rdr->hwDownloadFromRef())
{
ADM_warning("Cannot convert hw image to yv12\n");
admPreview::deferDisplay(false);
return;
}
}
initSCeneChangeDetector(rdr);

uint64_t duration=video_body->getVideoDuration();
uint64_t startTime=admPreview::getCurrentPts();
DIA_processingBase *work=createProcessing(QT_TRANSLATE_NOOP("scenechange", "Searching scene change.."),duration-startTime);

bool scFound=false;
while(1)
{
UI_purge();

if(false==admPreview::nextPicture())
break;
rdr=admPreview::getBuffer();
if(rdr->refType!=ADM_HW_NONE) // need to convert it to plain YV12
{
if(false==rdr->hwDownloadFromRef())
{
ADM_warning("Cannot convert hw image to yv12\n");
break;
}
}
if(isSCeneChange(rdr))
{
scFound = true;
break;
}
if(work->update(1,admPreview::getCurrentPts()-startTime))
break;
}
delete work;
if (!scFound)
admPreview::seekToTime(startTime);
admPreview::deferDisplay(false);
admPreview::samePicture();
GUI_setCurrentFrameAndTime();
return;
}

//EOF
28 changes: 24 additions & 4 deletions avidemux/qt4/ADM_userInterfaces/ADM_gui/Q_gui2.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1426,7 +1426,7 @@ void MainWindow::updateActionShortcuts(void)
q = findAction(&myMenuGo, ACT_NextCutPoint);
if(q)
q->setShortcut(Qt::SHIFT | (swpud ? Qt::Key_Down : Qt::Key_Up));

q = findAction(&myMenuGo, ACT_Back1Mn);
if(q)
q->setShortcut(Qt::CTRL | (swpud ? Qt::Key_Up : Qt::Key_Down));
Expand Down Expand Up @@ -1604,7 +1604,13 @@ void MainWindow::widgetsUpdateTooltips(void)
tt += SHORTCUT(ACT_NextCutPoint,Go)
ui.toolButtonNextCutPoint->setToolTip(tt);

// go to black frame tooltips are static, the actions don't have shortcuts
tt = QString(QT_TRANSLATE_NOOP("qgui2","Search previous black frame"));
tt += SHORTCUT(ACT_PrevBlackFrame,Go)
ui.toolButtonPreviousBlackFrame->setToolTip(tt);

tt = QString(QT_TRANSLATE_NOOP("qgui2","Search next black frame"));
tt += SHORTCUT(ACT_NextBlackFrame,Go)
ui.toolButtonNextBlackFrame->setToolTip(tt);

tt = QString(QT_TRANSLATE_NOOP("qgui2","Go to first frame"));
tt += SHORTCUT(ACT_Begin,Go)
Expand Down Expand Up @@ -1759,7 +1765,14 @@ bool MainWindow::eventFilter(QObject* watched, QEvent* event)
switch (keyEvent->key())
{
case Qt::Key_Left:
if ((keyEvent->modifiers() & Qt::ShiftModifier) && (keyEvent->modifiers() & Qt::ControlModifier))
if (keyEvent->modifiers() & Qt::AltModifier)
{
if (keyEvent->modifiers() & Qt::ShiftModifier)
sendAction(ACT_PrevBlackFrame);
else
sendAction(ACT_PrevSceneChange);
}
else if ((keyEvent->modifiers() & Qt::ShiftModifier) && (keyEvent->modifiers() & Qt::ControlModifier))
sendAction(ACT_Back4Seconds);
else if (keyEvent->modifiers() & Qt::ShiftModifier)
sendAction(ACT_Back1Second);
Expand All @@ -1770,7 +1783,14 @@ bool MainWindow::eventFilter(QObject* watched, QEvent* event)

return true;
case Qt::Key_Right:
if ((keyEvent->modifiers() & Qt::ShiftModifier) && (keyEvent->modifiers() & Qt::ControlModifier))
if (keyEvent->modifiers() & Qt::AltModifier)
{
if (keyEvent->modifiers() & Qt::ShiftModifier)
sendAction(ACT_NextBlackFrame);
else
sendAction(ACT_NextSceneChange);
}
else if ((keyEvent->modifiers() & Qt::ShiftModifier) && (keyEvent->modifiers() & Qt::ControlModifier))
sendAction(ACT_Forward4Seconds);
else if (keyEvent->modifiers() & Qt::ShiftModifier)
sendAction(ACT_Forward1Second);
Expand Down
2 changes: 2 additions & 0 deletions avidemux/qt4/ADM_userInterfaces/ADM_gui/avidemux.qrc
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
<file>pics/next.png</file>
<file>pics/next_black.png</file>
<file>pics/next_cut.png</file>
<file>pics/next_scd.png</file>
<file>pics/player_end.png</file>
<file>pics/player_fwd.png</file>
<file>pics/player_play.png</file>
Expand All @@ -28,6 +29,7 @@
<file>pics/play_filtered.png</file>
<file>pics/prev_black.png</file>
<file>pics/prev_cut.png</file>
<file>pics/prev_scd.png</file>
<file>pics/preview_input.png</file>
<file>pics/preview_output.png</file>
<file>pics/preview_separate.png</file>
Expand Down
2 changes: 2 additions & 0 deletions avidemux/qt4/ADM_userInterfaces/ADM_gui/avidemux_osx.qrc
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
<file>pics/next.png</file>
<file>pics/next_black.png</file>
<file>pics/next_cut.png</file>
<file>pics/next_scd.png</file>
<file>pics/player_end.png</file>
<file>pics/player_fwd.png</file>
<file>pics/player_play.png</file>
Expand All @@ -28,6 +29,7 @@
<file>pics/play_filtered.png</file>
<file>pics/prev_black.png</file>
<file>pics/prev_cut.png</file>
<file>pics/prev_scd.png</file>
<file>pics/preview_input.png</file>
<file>pics/preview_output.png</file>
<file>pics/preview_separate.png</file>
Expand Down
2 changes: 2 additions & 0 deletions avidemux/qt4/ADM_userInterfaces/ADM_gui/avidemux_win32.qrc
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
<file>pics/next.png</file>
<file>pics/next_black.png</file>
<file>pics/next_cut.png</file>
<file>pics/next_scd.png</file>
<file>pics/player_end.png</file>
<file>pics/player_fwd.png</file>
<file>pics/player_play.png</file>
Expand All @@ -28,6 +29,7 @@
<file>pics/play_filtered.png</file>
<file>pics/prev_black.png</file>
<file>pics/prev_cut.png</file>
<file>pics/prev_scd.png</file>
<file>pics/preview_input.png</file>
<file>pics/preview_output.png</file>
<file>pics/preview_separate.png</file>
Expand Down
Loading