diff --git a/avidemux_plugins/ADM_videoFilters6/CMakeLists.txt b/avidemux_plugins/ADM_videoFilters6/CMakeLists.txt index 2d29597285..5d699dc3d9 100644 --- a/avidemux_plugins/ADM_videoFilters6/CMakeLists.txt +++ b/avidemux_plugins/ADM_videoFilters6/CMakeLists.txt @@ -83,3 +83,4 @@ ADD_SUBDIRECTORY(fadeFromImage) ADD_SUBDIRECTORY(fadeThrough) ADD_SUBDIRECTORY(deband) ADD_SUBDIRECTORY(cubicLUT) +ADD_SUBDIRECTORY(reverse) diff --git a/avidemux_plugins/ADM_videoFilters6/reverse/ADM_vidReverse.cpp b/avidemux_plugins/ADM_videoFilters6/reverse/ADM_vidReverse.cpp new file mode 100644 index 0000000000..4616d15316 --- /dev/null +++ b/avidemux_plugins/ADM_videoFilters6/reverse/ADM_vidReverse.cpp @@ -0,0 +1,468 @@ +/** ************************************************************************* + \fn ADM_vidReverse.cpp + + copyright: 2022 szlldm + + ***************************************************************************/ + +/*************************************************************************** + * * + * 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_default.h" +#include "ADM_coreVideoFilter.h" +#include "DIA_factory.h" +#include "ADM_vidMisc.h" + +#include "reverse.h" +#include "reverse_desc.cpp" +#include "ADM_vidReverse.h" + + +// Add the hook to make it valid plugin +DECLARE_VIDEO_FILTER( ADMVideoReverse, // Class + 1,0,1, // Version + ADM_UI_TYPE_BUILD, // UI + VF_TRANSFORM, // Category + "reverse", // internal name (must be uniq!) + QT_TRANSLATE_NOOP("reverse","Reverse"), // Display name + QT_TRANSLATE_NOOP("reverse","Play a short section backward.") // Description + ); + +#if 1 + #define aprintf(...) {} +#else + #define aprintf printf +#endif + +/** + \fn ADMVideoReverse + \brief constructor +*/ +ADMVideoReverse::ADMVideoReverse( ADM_coreVideoFilter *in,CONFcouple *setup) : ADM_coreVideoFilter(in,setup) +{ +UNUSED_ARG(setup); + + original=new ADMImageDefault(in->getInfo()->width,in->getInfo()->height); + if(!setup || !ADM_paramLoad(setup,reverse_param,¶m)) + { + // Default value + param.startTime = info.markerA / 1000LL; + param.endTime = info.markerB / 1000LL; + param.fileBuffer = ""; + } + frameCount = 0; + overrun = false; + overrunImg = new ADMImageDefault(in->getInfo()->width,in->getInfo()->height); + invalidatedBySeek = false; + internalError = false; + bufferCount = 0; + frameBuffer = NULL; + validFileBuffer = false; +} +/** + \fn ADMVideoReverse + \brief destructor +*/ +ADMVideoReverse::~ADMVideoReverse() +{ + if(original) delete original; + original=NULL; + if(overrunImg) delete overrunImg; + overrunImg=NULL; + clean(); + cleanFile(); +} + + +/** + * \fn clean + */ +void ADMVideoReverse::clean() +{ + frameCount = 0; + if (bufferCount > 0) + { + free(frameBuffer); + frameBuffer = NULL; + bufferCount = 0; + } +} + +/** + * \fn cleanFile + */ +void ADMVideoReverse::cleanFile() +{ + validFileBuffer = false; + FILE * fd = NULL; + fd = ADM_fopen(param.fileBuffer.c_str(), "w+"); + if(fd != NULL) + ADM_fclose(fd); +} + +/** + * \fn goToTime + */ +bool ADMVideoReverse::goToTime(uint64_t time) +{ + uint32_t timeMs = time / 1000; + if ((timeMs >= param.startTime) && (timeMs <= param.endTime)) + { + invalidatedBySeek = (timeMs > param.startTime); // special case is if seek to the start, we need to handle it, because if reverse start at the first frame, this can happen! + overrun = false; + clean(); + if (timeMs > param.startTime) + cleanFile(); + } + + return previousFilter->goToTime(time); +} + +/** + * \fn wrongImage + */ +void ADMVideoReverse::wrongImage(ADMImage * img, int Y, int U, int V, const char * msg) +{ + uint32_t w, h; + img->getWidthHeight(&w, &h); + uint8_t * wplanes[3]; + int strides[3]; + img->GetWritePlanes(wplanes); + img->GetPitches(strides); + memset(wplanes[0], Y, h*strides[0]); + memset(wplanes[1], U, (h/2)*strides[1]); + memset(wplanes[2], V, (h/2)*strides[2]); + img->printString(1,1,msg); +} + +/** + \fn getFrame + \brief Get a processed frame +*/ +bool ADMVideoReverse::getNextFrame(uint32_t *fn,ADMImage *image) +{ + if (internalError) + { + internalError = false; + clean(); + cleanFile(); + return false; + } + + if (frameCount == 0) + { + clean(); + if (overrun) + { + image->duplicateFull(overrunImg); + overrun = false; + *fn = _fn; + aprintf("[reverse] getNextFrame (fn==%u) - Return overrun\n",*fn); + return true; + } else { + if(false==previousFilter->getNextFrame(fn,original)) + { + ADM_warning("reverse : Cannot get frame\n"); + return false; + } + + uint32_t startMs = param.startTime; + uint32_t endMs = param.endTime; + + + if (startMs > endMs) + { + uint64_t tmp = endMs; + endMs = startMs; + startMs = tmp; + } + + uint32_t imgMs = (original->Pts+getAbsoluteStartTime())/1000LL; + + if ((startMs == endMs) || (imgMs < startMs) || (imgMs > endMs)) + { + invalidatedBySeek = false; + image->duplicateFull(original); + aprintf("[reverse] getNextFrame (fn==%u) - out of scope\n",*fn); + return true; + } + + + if ((imgMs > startMs+1) && (imgMs <= endMs)) + { + invalidatedBySeek = true; + clean(); + } + + if (invalidatedBySeek) + { + image->copyInfo(original); + // make it green + wrongImage(image, 64, 0, 0, "[reverse] preview not available"); + aprintf("[reverse] getNextFrame (fn==%u) - invalidated by seek\n",*fn); + return true; + } + + _fn = *fn; + + // we are in the time scope + // get and buffer frames + + FILE * fd = NULL; + if (!validFileBuffer) + { + fd = ADM_fopen(param.fileBuffer.c_str(), "w+"); + if (fd == NULL) + { + internalError = true; + *fn = _fn; + image->copyInfo(original); + ADM_error("[reverse] file open error\n"); + wrongImage(image, 64, 255, 0, "[reverse] file open error\n"); + return true; + } + } + + do { + imgMs = (original->Pts+getAbsoluteStartTime())/1000LL; + + if (imgMs > endMs) // reached out of scope frame + { + overrunImg->duplicateFull(original); + overrun = true; + break; + } + + bufferCount = frameCount+1; + frameBuffer = (buffered_frame_t*)realloc(frameBuffer, bufferCount*sizeof(buffered_frame_t)); + if (frameBuffer == NULL) + { + internalError = true; + *fn = _fn; + image->copyInfo(original); + ADM_error("[reverse] realloc error\n"); + wrongImage(image, 64, 255, 0, "[reverse] realloc error\n"); + if (fd) + ADM_fclose(fd); + return true; + } + + frameBuffer[frameCount].Pts = (original->Pts+getAbsoluteStartTime()); + frameBuffer[frameCount]._colorSpace = original->_colorSpace; + frameBuffer[frameCount]._range = original->_range; + + uint32_t w,h; + uint8_t * wplanes[3]; + int strides[3]; + original->getWidthHeight(&w, &h); + original->GetWritePlanes(wplanes); + original->GetPitches(strides); + + if (!validFileBuffer) + { + size_t count; + for (int i=0; i<3; i++) + { + if (i==1) + h /= 2; + count = strides[i]*h; + if (ADM_fwrite(wplanes[i], 1, count, fd) != count) + { + internalError = true; + *fn = _fn; + image->copyInfo(original); + ADM_error("[reverse] file write error\n"); + wrongImage(image, 64, 255, 0, "[reverse] file write error\n"); + if (fd) + ADM_fclose(fd); + return true; + } + } + } + + + frameCount += 1; + if(false==previousFilter->getNextFrame(fn,original)) // reached the end + { + break; + } + } while(1); + + if (fd) + { + validFileBuffer = true; + ADM_fclose(fd); + } + } + } + + if (frameCount == 0) // this should be not true, but in case it is, return false + { + clean(); + if (overrun) + { + image->duplicateFull(overrunImg); + overrun = false; + *fn = _fn; + aprintf("[reverse] getNextFrame (fn==%u) - Return overrun 2\n",*fn); + return true; + } + aprintf("[reverse] getNextFrame (fn==%u) - Return from impossible\n",*fn); + return false; + } + + + // serve the reverse ordered frames: + + frameCount -= 1; + + uint64_t startPts = param.startTime; + uint64_t endPts = param.endTime; + if (startPts > endPts) + { + uint64_t tmp = endPts; + endPts = startPts; + startPts = tmp; + } + startPts *= 1000; + endPts *= 1000; + + if (endPts < frameBuffer[frameCount].Pts) // due to rounding errors + image->Pts = 0; + else + image->Pts = (endPts - frameBuffer[frameCount].Pts)+startPts; + if (image->Pts < getAbsoluteStartTime()) + image->Pts = 0; + else + image->Pts -= getAbsoluteStartTime(); + image->_colorSpace = frameBuffer[frameCount]._colorSpace; + image->_range = frameBuffer[frameCount]._range; + + uint32_t w,h; + uint8_t * wplanes[3]; + int strides[3]; + image->getWidthHeight(&w, &h); + image->GetWritePlanes(wplanes); + image->GetPitches(strides); + + FILE * fd = ADM_fopen(param.fileBuffer.c_str(), "r"); + if (fd == NULL) + { + internalError = true; + *fn = _fn; + ADM_error("[reverse] file open error\n"); + wrongImage(image, 64, 255, 0, "[reverse] file open error\n"); + return true; + } + + long int offset = (strides[0]*h + strides[1]*(h/2) + strides[2]*(h/2)); + offset *= frameCount; + if (fseek(fd, offset, SEEK_SET) != 0) + { + internalError = true; + *fn = _fn; + ADM_error("[reverse] file seek error\n"); + wrongImage(image, 64, 255, 0, "[reverse] file seek error\n"); + if (fd) + ADM_fclose(fd); + return true; + } + + size_t count; + for (int i=0; i<3; i++) + { + if (i==1) + h /= 2; + count = strides[i]*h; + if (ADM_fread(wplanes[i], 1, count, fd) != count) + { + internalError = true; + *fn = _fn; + ADM_error("[reverse] file read error\n"); + wrongImage(image, 64, 255, 0, "[reverse] file read error\n"); + if (fd) + ADM_fclose(fd); + return true; + } + } + + ADM_fclose(fd); + + *fn = _fn; + _fn += 1; + aprintf("[reverse] getNextFrame (fn==%u) - Backward\n",*fn); + return true; +} + +/** + \fn getCoupledConf + \brief Return our current configuration as couple name=value +*/ +bool ADMVideoReverse::getCoupledConf(CONFcouple **couples) +{ + return ADM_paramSave(couples, reverse_param,¶m); +} + +void ADMVideoReverse::setCoupledConf(CONFcouple *couples) +{ + ADM_paramLoad(couples, reverse_param, ¶m); + clean(); + cleanFile(); + aprintf("[reverse] setCoupledConf\n"); +} + +/** + \fn getConfiguration + \brief Return current setting as a string +*/ +const char *ADMVideoReverse::getConfiguration(void) +{ + static char s[2512]; + + char startTimeStr[128]; + char endTimeStr[128]; + snprintf(startTimeStr,127,"%s",ADM_us2plain(param.startTime*1000LL)); + snprintf(endTimeStr,127,"%s",ADM_us2plain(param.endTime*1000LL)); + + uint32_t durationMs = (param.endTime - param.startTime); + double bytesPerSec; + bytesPerSec = previousFilter->getInfo()->width; + bytesPerSec *= previousFilter->getInfo()->height; + bytesPerSec *= 1.5; // YUV420 + double fps = 1000000.0 / (double)(previousFilter->getInfo()->frameIncrement); //frameIncrement: Average delta time between 2 frames in useconds ~ 1/fps + bytesPerSec *= fps; + bytesPerSec *= 1.1; ///margin + double gib = ((bytesPerSec * durationMs) / 1000.0) / 1073741824.0; + + snprintf(s,2511,"%s - %s: Buffer to %s\nRequired storage for buffering: %.3f GiB",startTimeStr,endTimeStr,param.fileBuffer.c_str(),gib); + + return s; +} +/** + \fn getInfo +*/ +FilterInfo *ADMVideoReverse::getInfo(void) +{ + return &info; +} + +extern bool DIA_reverse(reverse *param, ADM_coreVideoFilter *in); +/** + \fn configure + +*/ +bool ADMVideoReverse::configure(void) +{ + aprintf("[reverse] configure\n"); + clean(); + cleanFile(); + return DIA_reverse(¶m, previousFilter); +} + +//EOF diff --git a/avidemux_plugins/ADM_videoFilters6/reverse/ADM_vidReverse.h b/avidemux_plugins/ADM_videoFilters6/reverse/ADM_vidReverse.h new file mode 100644 index 0000000000..ebc311d09a --- /dev/null +++ b/avidemux_plugins/ADM_videoFilters6/reverse/ADM_vidReverse.h @@ -0,0 +1,64 @@ +/*************************************************************************** + \fn ADM_vidReverse.h + + copyright: 2022 szlldm + + ***************************************************************************/ + +/*************************************************************************** + * * + * 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. * + * * + ***************************************************************************/ +#pragma once +#include "ADM_default.h" +#include "ADM_image.h" +#include "ADM_coreVideoFilter.h" + + +/** + \class ADMVideoReverse +*/ +class ADMVideoReverse : public ADM_coreVideoFilter +{ + protected: + ADMImage * original; + reverse param; + unsigned int frameCount; + bool overrun; + ADMImage * overrunImg; + bool invalidatedBySeek; + bool internalError; + bool seekToStart; + uint32_t _fn; + unsigned int bufferCount; + bool validFileBuffer; + typedef struct + { + uint64_t Pts; + ADM_colorSpace _colorSpace; + ADM_colorRange _range; + } buffered_frame_t; + buffered_frame_t * frameBuffer; + + void clean(); + void cleanFile(); + void wrongImage(ADMImage * img, int Y, int U, int V, const char * msg); + + public: + ADMVideoReverse(ADM_coreVideoFilter *previous,CONFcouple *conf); + ~ADMVideoReverse(); + + virtual const char * getConfiguration(void); /// Return current configuration as a human readable string + virtual bool getNextFrame(uint32_t *fn,ADMImage *image); /// Return the next image + virtual FilterInfo * getInfo(void); /// Return picture parameters after this filter + virtual bool getCoupledConf(CONFcouple **couples) ; /// Return the current filter configuration + virtual void setCoupledConf(CONFcouple *couples); + virtual bool configure(void) ; /// Start graphical user interface + virtual bool goToTime(uint64_t time); +}; + + diff --git a/avidemux_plugins/ADM_videoFilters6/reverse/CMakeLists.txt b/avidemux_plugins/ADM_videoFilters6/reverse/CMakeLists.txt new file mode 100644 index 0000000000..63852e4ddd --- /dev/null +++ b/avidemux_plugins/ADM_videoFilters6/reverse/CMakeLists.txt @@ -0,0 +1,25 @@ +INCLUDE(vf_plugin) + +SET(ReverseCommon_SRCS ADM_vidReverse.cpp) + + +# ---------- QT4 Version ---------------- +INCLUDE(vf_plugin_qt4) +SET(ReverseQT4_SRCS qt4/Q_reverse.cpp) +SET(ReverseQT4_Headers qt4/Q_reverse.h) +SET(ReverseQT4_UI qt4/reverse) +INIT_VIDEO_FILTER_QT4(ADM_vf_reverse${QT_LIBRARY_EXTENSION} ${ReverseQT4_SRCS} ${ReverseQT4_Headers} ${ReverseQT4_UI} ${ReverseCommon_SRCS} ) +IF(DO_QT4) + TARGET_LINK_LIBRARIES(ADM_vf_reverse${QT_LIBRARY_EXTENSION} ADM_libswscale) +ENDIF(DO_QT4) +# /QT4 + +# ----------------- CLI Version ----------------------- +INCLUDE(vf_plugin_cli) +SET(ReverseCli_SRCS cli/DIA_reverse.cpp) +INIT_VIDEO_FILTER_CLI(ADM_vf_reverseCli ${ReverseCli_SRCS} ${ReverseCommon_SRCS}) +IF(DO_CLI) + TARGET_LINK_LIBRARIES(ADM_vf_reverseCli ADM_libswscale) +ENDIF(DO_CLI) + +# /QT4 diff --git a/avidemux_plugins/ADM_videoFilters6/reverse/cli/DIA_reverse.cpp b/avidemux_plugins/ADM_videoFilters6/reverse/cli/DIA_reverse.cpp new file mode 100644 index 0000000000..e2fc9c1435 --- /dev/null +++ b/avidemux_plugins/ADM_videoFilters6/reverse/cli/DIA_reverse.cpp @@ -0,0 +1,27 @@ +/*************************************************************************** + copyright : (C) 2001 by mean + email : fixounet@free.fr + ***************************************************************************/ + +/*************************************************************************** + * * + * 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_default.h" +#include "ADM_coreVideoFilter.h" +#include "reverse.h" +/** + \fn DIA_reverse +*/ +bool DIA_reverse(reverse *param, ADM_coreVideoFilter *in) +{ + return true; +} +//******************************************** +//EOF diff --git a/avidemux_plugins/ADM_videoFilters6/reverse/qt4/Q_reverse.cpp b/avidemux_plugins/ADM_videoFilters6/reverse/qt4/Q_reverse.cpp new file mode 100644 index 0000000000..5482c64900 --- /dev/null +++ b/avidemux_plugins/ADM_videoFilters6/reverse/qt4/Q_reverse.cpp @@ -0,0 +1,222 @@ +/*************************************************************************** + copyright : (C) 2001 by mean + email : fixounet@free.fr + ***************************************************************************/ + +/*************************************************************************** + * * + * 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 + +#include "Q_reverse.h" +#include "ADM_default.h" +#include "DIA_coreToolkit.h" +#include "ADM_toolkitQt.h" +#include "ADM_vidReverse.h" +#include "ADM_vidMisc.h" +#include "DIA_factory.h" +#include "ADM_last.h" +#include + +#if 0 +#define aprintf printf +#else +#define aprintf(...) {} +#endif + +reverseWindow::reverseWindow(QWidget *parent, reverse *param, ADM_coreVideoFilter *in) : QDialog(parent) +{ + ui.setupUi(this); + _param=param; + + markerA = in->getInfo()->markerA; + markerB = in->getInfo()->markerB; + duration = in->getInfo()->totalDuration; + bytesPerSec = in->getInfo()->width; + bytesPerSec *= in->getInfo()->height; + bytesPerSec *= 1.5; // YUV420 + double fps = 1000000.0 / (double)in->getInfo()->frameIncrement; //frameIncrement; /// Average delta time between 2 frames in useconds ~ 1/fps + bytesPerSec *= fps; + bytesPerSec *= 1.1; ///margin + + connect(ui.buttonBox, SIGNAL(accepted()), this, SLOT(okButtonClicked())); + + connect(ui.pushButtonTManual,SIGNAL(clicked(bool)),this,SLOT(manualTimeEntry(bool))); + connect(ui.pushButtonTMarker,SIGNAL(clicked(bool)),this,SLOT(timesFromMarkers(bool))); + + admCoreUtils::getLastReadFile(filePath); + + QString warning_text = QString(QT_TRANSLATE_NOOP("reverse","THIS FILTER SUFFER A FEW LIMITATION:")); + warning_text += QString("\n•"); + warning_text += QString(QT_TRANSLATE_NOOP("reverse","The start time MUST match a presentation timestamp (PTS) of a frame. Recommended to use the markers. Avoid filters that change timing and/or FPS.")); + warning_text += QString("\n•"); + warning_text += QString(QT_TRANSLATE_NOOP("reverse","This filter requires to buffer the entire section to be reversed, a temporary file will be saved in the same directory as the source video. Make sure there is enough space, and write premission.")); + warning_text += QString("\n•"); + warning_text += QString(QT_TRANSLATE_NOOP("reverse","The preview of the reverseal is ONLY possible, if you start palying before (or exactly at the start of) the time scope. Else you will see a green screen.")); + warning_text += QString("\n•"); + warning_text += QString(QT_TRANSLATE_NOOP("reverse","When encoding or play in preview reaches the filter's start time, the application may appear unresponsive, while buffering the section. Be patient.")); + ui.textEditWarnings->setText(warning_text); + + printInfo(); + +} + +void reverseWindow::gather(void) +{ + _param->fileBuffer = ui.lineEditFileName->text().toUtf8().constData(); +} + +void reverseWindow::showEvent(QShowEvent *event) +{ + QDialog::showEvent(event); + + QFontMetrics fm = ui.labelTScope->fontMetrics(); + QString text = QString(QT_TRANSLATE_NOOP("reverse","Time scope: ")); + text += QString("000:00:00,000 - 000:00:00,000"); + ui.labelTScope->setMinimumWidth(1.05 * fm.boundingRect(text).width()); + text = QString(QT_TRANSLATE_NOOP("reverse","Duration: ")); + text += QString("000:00:00,000---"); + ui.labelDuration->setMinimumWidth(1.05 * fm.boundingRect(text).width()); + + adjustSize(); +} + +void reverseWindow::manualTimeEntry(bool f) +{ + uint32_t mx=(uint32_t)(duration/1000LL); + + diaElemTimeStamp start(&(_param->startTime),QT_TRANSLATE_NOOP("reverse","_Start time:"),0,mx); + diaElemTimeStamp end(&(_param->endTime),QT_TRANSLATE_NOOP("reverse","_End time:"),0,mx); + diaElem *elems[2]={&start,&end}; + + if(diaFactoryRun(QT_TRANSLATE_NOOP("reverse","Manual time entry"),2+0*1,elems)) + { + if(_param->startTime > _param->endTime) + { + uint32_t tmp=_param->startTime; + _param->startTime=_param->endTime; + _param->endTime=tmp; + } + + printInfo(); + } +} + +void reverseWindow::timesFromMarkers(bool f) +{ + _param->startTime = markerA / 1000LL; + _param->endTime = markerB / 1000LL; + if(_param->startTime > _param->endTime) + { + uint32_t tmp=_param->startTime; + _param->startTime=_param->endTime; + _param->endTime=tmp; + } + + printInfo(); +} + +void reverseWindow::valueChanged(int f) +{ + printInfo(); +} + + +void reverseWindow::printInfo() +{ + + QString tstr = QString(QT_TRANSLATE_NOOP("reverse","Time scope: ")); + tstr += QString(ADM_us2plain(_param->startTime*1000LL)); + tstr += QString(" - "); + tstr += QString(ADM_us2plain(_param->endTime*1000LL)); + ui.labelTScope->setText(tstr); + + uint32_t durationMs = (_param->endTime - _param->startTime); + + tstr = QString(QT_TRANSLATE_NOOP("reverse","Duration: ")); + tstr += QString(ADM_us2plain(durationMs*1000LL)); + ui.labelDuration->setText(tstr); + + double GBytes = ((bytesPerSec * durationMs) / 1000.0) / 1073741824.0; + char GBstr[16]; + snprintf(GBstr, 16, "%.03f",GBytes); + ui.labelStorage->setTextFormat(Qt::RichText); + tstr = QString("

"); + tstr += QString(QT_TRANSLATE_NOOP("reverse","Required storage for buffering: ")); + tstr += QString(GBstr); + tstr += QString(QT_TRANSLATE_NOOP("reverse"," GiB")); + tstr += QString("


"); + ui.labelStorage->setText(tstr); + + QString fn = QString::fromStdString(filePath); + fn += QString("."); + char tshex[17]; + snprintf(tshex,17, "%08" PRIX32 "%08" PRIX32, _param->startTime, _param->endTime); + fn += QString(tshex); + fn += QString(".rev"); + ui.lineEditFileName->clear(); + ui.lineEditFileName->insert(fn); + ui.lineEditFileName->setDisabled(false); +} + + +void reverseWindow::okButtonClicked() +{ + bool fileError = false; + + fileError = true; + std::string fn = ui.lineEditFileName->text().toUtf8().constData(); + FILE * fd = ADM_fopen(fn.c_str(), "w+"); + if (fd) + { + if (ADM_fwrite("writetest16bytes",1,16,fd) == 16) // successfull write + fileError = false; + ADM_fclose(fd); + if (!fileError) + { + fileError = true; + fd = ADM_fopen(fn.c_str(), "w+"); + if (fd) + { + fileError = false; + ADM_fclose(fd); + } + } + } + + if (fileError) + GUI_Error_HIG(QT_TRANSLATE_NOOP("reverse","Could not create or write the buffer file!"), NULL); + else + accept(); +} + +/** + \fn DIA_reverse +*/ +bool DIA_reverse(reverse *param, ADM_coreVideoFilter *in) +{ + bool r=false; + + // Fetch info + reverseWindow reverseWindow(qtLastRegisteredDialog(), param, in); + + qtRegisterDialog(&reverseWindow); + + if(reverseWindow.exec()==QDialog::Accepted) + { + reverseWindow.gather(); + r=true; + } + + qtUnregisterDialog(&reverseWindow); + + return r; +} +//******************************************** +//EOF diff --git a/avidemux_plugins/ADM_videoFilters6/reverse/qt4/Q_reverse.h b/avidemux_plugins/ADM_videoFilters6/reverse/qt4/Q_reverse.h new file mode 100644 index 0000000000..8d2382588e --- /dev/null +++ b/avidemux_plugins/ADM_videoFilters6/reverse/qt4/Q_reverse.h @@ -0,0 +1,34 @@ +#ifndef Q_reverse_h +#define Q_reverse_h + +#include "ui_reverse.h" +#include "ADM_default.h" +#include "reverse.h" +#include "ADM_vidReverse.h" + +class reverseWindow : public QDialog +{ + Q_OBJECT + +private: + void printInfo(); + void showEvent(QShowEvent *event); + +protected: + reverse * _param; + uint64_t markerA, markerB, duration; + double bytesPerSec; + std::string filePath; + +public: + reverseWindow(QWidget *parent, reverse *param, ADM_coreVideoFilter *in); + Ui_reverseDialog ui; + +public slots: + void gather(void); + void okButtonClicked(); + void manualTimeEntry(bool f); + void timesFromMarkers(bool f); + void valueChanged(int f); +}; +#endif // Q_reverse_h diff --git a/avidemux_plugins/ADM_videoFilters6/reverse/qt4/reverse.ui b/avidemux_plugins/ADM_videoFilters6/reverse/qt4/reverse.ui new file mode 100644 index 0000000000..08f0ab734f --- /dev/null +++ b/avidemux_plugins/ADM_videoFilters6/reverse/qt4/reverse.ui @@ -0,0 +1,241 @@ + + + reverseDialog + + + + 0 + 0 + 477 + 400 + + + + Reverse + + + + 6 + + + 9 + + + 9 + + + 9 + + + 9 + + + + + Time scope + + + + 6 + + + 9 + + + 9 + + + 9 + + + 9 + + + + + 6 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + Time scope: + + + + + + + Duration: + + + + + + + Manual time entry + + + + + + + Set from A-B markers + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + + WARNINGS + + + + + + + + <html><head/><body><p><span style=" font-size:72pt; font-weight:600; color:#ff5500;">⚠</span></p></body></html> + + + + + + + + + Qt::ScrollBarAsNeeded + + + Qt::ScrollBarAlwaysOff + + + true + + + Qt::NoTextInteraction + + + + + + + + + + + + + + Buffering + + + + + + + + Required storage for buffering: + + + + + + + + + Buffer to: + + + + + + + true + + + + + + + + + + + + + + Qt::Vertical + + + QSizePolicy::MinimumExpanding + + + + 20 + 16 + + + + + + + + Qt::Horizontal + + + QDialogButtonBox::Cancel|QDialogButtonBox::Ok + + + + + + + + + buttonBox + rejected() + reverseDialog + reject() + + + 316 + 260 + + + 286 + 274 + + + + + diff --git a/avidemux_plugins/ADM_videoFilters6/reverse/reverse.conf b/avidemux_plugins/ADM_videoFilters6/reverse/reverse.conf new file mode 100644 index 0000000000..f342bce4ef --- /dev/null +++ b/avidemux_plugins/ADM_videoFilters6/reverse/reverse.conf @@ -0,0 +1,5 @@ +reverse{ +uint32_t:startTime; # in ms! +uint32_t:endTime; # in ms ! +string:fileBuffer; +} diff --git a/avidemux_plugins/ADM_videoFilters6/reverse/reverse.h b/avidemux_plugins/ADM_videoFilters6/reverse/reverse.h new file mode 100644 index 0000000000..dcdedf0121 --- /dev/null +++ b/avidemux_plugins/ADM_videoFilters6/reverse/reverse.h @@ -0,0 +1,8 @@ +// automatically generated by admSerialization.py do not edit +#include "string" +#pragma once +typedef struct { +uint32_t startTime; +uint32_t endTime; +std::string fileBuffer; +}reverse; diff --git a/avidemux_plugins/ADM_videoFilters6/reverse/reverse_desc.cpp b/avidemux_plugins/ADM_videoFilters6/reverse/reverse_desc.cpp new file mode 100644 index 0000000000..7d9541c803 --- /dev/null +++ b/avidemux_plugins/ADM_videoFilters6/reverse/reverse_desc.cpp @@ -0,0 +1,7 @@ +// automatically generated by admSerialization.py, do not edit! +extern const ADM_paramList reverse_param[]={ + {"startTime",offsetof(reverse,startTime),"uint32_t",ADM_param_uint32_t}, + {"endTime",offsetof(reverse,endTime),"uint32_t",ADM_param_uint32_t}, + {"fileBuffer",offsetof(reverse,fileBuffer),"std::string",ADM_param_stdstring}, +{NULL,0,NULL} +}; diff --git a/avidemux_plugins/ADM_videoFilters6/reverse/reverse_json.cpp b/avidemux_plugins/ADM_videoFilters6/reverse/reverse_json.cpp new file mode 100644 index 0000000000..dbf24c7d97 --- /dev/null +++ b/avidemux_plugins/ADM_videoFilters6/reverse/reverse_json.cpp @@ -0,0 +1,20 @@ +// automatically generated by admSerialization.py, do not edit! +#include "ADM_default.h" +#include "ADM_paramList.h" +#include "ADM_coreJson.h" +#include "reverse.h" +bool reverse_jserialize(const char *file, const reverse *key){ +admJson json; +json.addUint32("startTime",key->startTime); +json.addUint32("endTime",key->endTime); +json.addString("fileBuffer",key->fileBuffer); +return json.dumpToFile(file); +}; +bool reverse_jdeserialize(const char *file, const ADM_paramList *tmpl,reverse *key){ +admJsonToCouple json; +CONFcouple *c=json.readFromFile(file); +if(!c) {ADM_error("Cannot read json file");return false;} +bool r= ADM_paramLoadPartial(c,tmpl,key); +delete c; +return r; +};