Index: mythvideo/mtd/jobthread.cpp
===================================================================
--- mythvideo/mtd/jobthread.cpp (revision 24265)
+++ mythvideo/mtd/jobthread.cpp (working copy)
@@ -847,22 +847,40 @@
secs_mult = 1.0f / length_in_seconds;
}
+
+
void DVDTranscodeThread::run(void)
{
myth_nice(nice_level);
- // Make working directory
- if (IsCancelled() || !makeWorkingDirectory())
+ // Make working directory, errors -4 and -5 are files / direcotires
+ // already exist
+ int makedirecoryresult = makeWorkingDirectory();
+ if (IsCancelled() ||
+ ((makedirecoryresult < 0) && (makedirecoryresult >= -3)) )
+ {
+ SendProblemEvent("abandoned job cos of error "
+ "between 0 an -3");
+ cleanUp();
return;
+ }
- if (IsCancelled())
+ if (IsCancelled())
+ {
+ cleanUp();
return;
+ }
- // Build the transcode command line. We do this early
- // (before ripping) so we can figure out if this is
- // a two pass job or not (for the progress display)
- if (!buildTranscodeCommandLine(1))
+ // Build the transcode command line. We do this early (before ripping) so
+ // we can figure out if this is a two pass job or not
+ // (for the progress display)
+ int transcodejobno;
+
+ transcodejobno = buildTranscodeCommandLine(1);
+
+ if (transcodejobno < 0)
{
+ // building the transcode command line failed
cleanUp();
return;
}
@@ -878,17 +896,38 @@
sub_to_overall_multiple = 0.50;
}
- if (IsCancelled())
+ if (IsCancelled())
+ {
+ cleanUp();
return;
+ }
// Rip VOB to working directory
.arg(working_directory->path()).arg(rip_name);
- if (!ripTitle(dvd_title, rip_file_string, ".vob", true, &output_files))
- {
- cleanUp();
- return;
+
+ if (makedirecoryresult == 0)
+ {
+ if (!ripTitle(dvd_title, rip_file_string, ".vob", true, &output_files))
+ {
+ cleanUp();
+ return;
+ }
+ else
+ {
+ MSqlQuery sayweveripped_query(MSqlQuery::InitCon());
+
+ sayweveripped_query.prepare(
+ "UPDATE dvdtranscodejobs SET state=1 WHERE final_dir_and_file "
+ "LIKE :RIPNAME;");
+ sayweveripped_query.bindValue(":RIPNAME", '%' + rip_name);
+
+ if(!sayweveripped_query.exec())
+ {
+ SendProblemEvent("Couldnt update the job as ripped in the database");
+ }
+ }
}
// Get permission to start transcoding from MTD instance.
@@ -919,20 +958,30 @@
// Run the first (only?) crack at transcoding
if (!IsCancelled() && !runTranscode(1))
{
+ SendProblemEvent("Failed single pass transcode");
+
wipeClean();
return;
}
// Second pass, if enabled
if (two_pass && !IsCancelled() && !runTranscode(2))
+ {
+ SendProblemEvent("Failed 2nd pass transcode");
+
wipeClean();
-
+ }
+
#ifndef DEBUG_STAGE_2
if (!gContext->GetNumSetting("mythdvd.mtd.SaveTranscodeIntermediates", 0))
{
// remove any temporary titles that are now transcoded
std::for_each(output_files.begin(), output_files.end(), delete_file());
}
+ else
+ {
+ SendProblemEvent("failed to tidy up");
+ }
#endif
cleanUp();
@@ -949,13 +998,21 @@
}
}
-bool DVDTranscodeThread::makeWorkingDirectory(void)
+// int DVDTranscodeThread::makeWorkingDirectory(void)
+//
+// changed by m bennett 10/04/10
+
+// I have changed this to be more verbose about the error condition (if any)
+// This is so there can be a difference made between a failed condition
+// and mearly a previos attempt to transcode
+
+int DVDTranscodeThread::makeWorkingDirectory(void)
{
QString dir_name = gContext->GetSetting
("DVDRipLocation");
if (dir_name.isEmpty())
{
SendProblemEvent("could not find rip directory in settings");
- return false;
+ return -1;
}
working_directory =
new QDir(dir_name
);
@@ -963,7 +1020,7 @@
{
SendProblemEvent
(QString("rip directory '%1' does not seem to exist") .arg(dir_name));
- return false;
+ return -2;
}
#ifndef DEBUG_STAGE_2
@@ -971,7 +1028,8 @@
{
SendProblemEvent
(QString("Could not create directory called '%1/%2' ") .arg(dir_name).arg(rip_name));
- return false;
+ //return -4;
+ // we dont want to quit out just to tell the system that the dir is there
}
#endif
@@ -979,7 +1037,7 @@
{
SendProblemEvent
(QString("Could not cd into '%1/%2'") .arg(dir_name).arg(rip_name));
- return false;
+ return -3;
}
#ifndef DEBUG_STAGE_2
@@ -988,22 +1046,54 @@
SendProblemEvent
(QString("could not create a vob subdirectory " "in the working directory '%1/%2'")
.arg(dir_name).arg(rip_name));
- return false;
+ return -5;
}
#endif
- return true;
+ return 0;
}
-bool DVDTranscodeThread::buildTranscodeCommandLine(int which_run)
+// int DVDTranscodeThread::buildTranscodeCommandLine(int which_run)
+//
+// changed by m bennett 10/04/10
+
+// I am changing this to return the job number if sucessful
+// or a -1 if fail. This is so that when the DVDTranscodeThread::run
+// calls this routine, the job data in dvdtranscode can be updated
+// as sucessfully ripped, and therfore can be skipped if mtd
+// bails for some reason
+
+// error conditions are less than 0
+// -1 destination file already exists
+// -2 no TranscodeCommand setting
+// -3 buildTranscodeCommandLine query failed
+// -4 buildTranscodeCommandLine query null return 1
+// -5 buildTranscodeCommandLine query failed 2
+// -6 buildTranscodeCommandLine query null return 2
+// -7 Can't transcode without a codec
+
+// suggested improvemnets
+// it would be nice - if the ripped files were held cenrally, if
+// any backend configured to transcode would pick up the job
+// using the standard backends job running mechanisim and adhearing to the
+// run job on same backend option
+
+// originally this
+//bool DVDTranscodeThread::buildTranscodeCommandLine(int which_run)
+int DVDTranscodeThread::buildTranscodeCommandLine(int which_run)
{
// If our destination file already exists, bail out
+ // It seems strange to test for the destination file here
+ // all things being good, this error condition should not arise
+ // and even if it does should the routine that build the command line
+ // have power of vito over its creation, should we not pass this back up
+ // for the calling - high level routines to deal with?
QFile a_file
(QString("%1.avi").
arg(destination_file_string
));
if (a_file.exists())
{
SendProblemEvent("Transcode cannot run, "
"destination file already exists");
- return false;
+ return(-1);
}
tc_command = gContext->GetSetting("TranscodeCommand");
@@ -1011,7 +1101,7 @@
{
SendProblemEvent(
"There is no TranscodeCommand setting for this system");
- return false;
+ return(-2);
}
tc_arguments.clear();
@@ -1033,13 +1123,13 @@
if (!a_query.exec())
{
SendProblemEvent("buildTranscodeCommandLine query failed 1");
- return false;
+ return(-3);
}
if (!a_query.next())
{
SendProblemEvent("buildTranscodeCommandLine query null return 1");
- return false;
+ return(-4);
}
// Convert query results to named variables
@@ -1079,13 +1169,13 @@
if (!a_query.exec())
{
SendProblemEvent("buildTranscodeCommandLine query failed 2");
- return false;
+ return(-5);
}
if (!a_query.next())
{
SendProblemEvent("buildTranscodeCommandLine query null return 2");
- return false;
+ return(-6);
}
int input_hsize = a_query.value(0).toInt();
@@ -1176,7 +1266,7 @@
if (codec.isEmpty())
{
SendProblemEvent("Yo! Kaka-brain! Can't transcode without a codec");
- return false;
+ return(-7);
}
if (codec.contains("divx") && gContext->GetNumSetting("MTDxvidFlag"))
@@ -1264,24 +1354,25 @@
for (int i = 0; i < tc_arguments.size(); i++)
args.push_back(shell_escape(tc_arguments[i]));
-
QString("transcode command will be: '%1 %2'") .arg(tc_command).arg(args.join(" "));
+ SendLoggingEvent("transcode command will be: ");
SendLoggingEvent(transcode_command_string);
- return true;
+ return(0);
}
bool DVDTranscodeThread::runTranscode(int which_run)
{
// Set description strings to let the user
// know what is going on.
-
SetSubName
(QObject::
tr("Transcode is thinking..."),
1);
SetSubProgress(0.0, 1);
// Second pass?
- if ((which_run > 1) && !buildTranscodeCommandLine(which_run))
+ // This builds the final transcode line
+ if ((which_run > 1) && (buildTranscodeCommandLine(which_run) < 0))
{
SendProblemEvent("Problem building second pass command line.");
return false;
@@ -1491,6 +1582,21 @@
working_directory->rmdir("vob");
working_directory->cd("..");
working_directory->rmdir(rip_name);
+
+ // remove the database entry
+ MSqlQuery removedonejob_query(MSqlQuery::InitCon());
+ // and the one before (buildtrancodeCommandLine is called twice
+ // change this to search for like filnames
+ removedonejob_query.prepare(
+ "DELETE FROM dvdtranscodejobs WHERE `final_dir_and_file` LIKE "
+ ":RIPNAME;");
+ removedonejob_query.bindValue(":RIPNAME", '%' + rip_name);
+
+ if(!removedonejob_query.exec())
+ {
+ SendProblemEvent("Couldnt remove the finished job from the database");
+ }
+
delete working_directory;
working_directory = NULL;
SetSubProgress(1, 1);
Index: mythvideo/mtd/mtd.cpp
===================================================================
--- mythvideo/mtd/mtd.cpp (revision 24265)
+++ mythvideo/mtd/mtd.cpp (working copy)
@@ -794,12 +794,18 @@
DVDTitle which_title = dvd_probe->GetTitle(dvd_title);
titles_mutex->unlock();
+ // this is a senible check to do, unfortnatley since I changed mtd
+ // to pick up on previous jobs it is likely to fial when adding a job
+ // when there is no disk in the drive
if (!which_title.IsValid())
{
VERBOSE(VB_IMPORTANT, LOC_ERR + "Title number not valid?");
- return;
+ // so we will try anyway after logging this error just to
+ // the flip side of this is is could now go wrong when adding a job
+ //return;
}
+ // Why do we not need to record this in the database?
uint numb_seconds = which_title.GetPlayLength();
emit writeToLog
(QString("launching job: %1").
arg(flat
));
Index: mythvideo/mtd/logging.cpp
===================================================================
--- mythvideo/mtd/logging.cpp (revision 24265)
+++ mythvideo/mtd/logging.cpp (working copy)
@@ -26,6 +26,11 @@
{
}
+// changed by m bennett 06/04/10
+//
+// Appends the mtd log file rather than rewrites it every time, this is for
+// debug
+//
bool MTDLogger::Init(void)
{
QString logfile_name = gContext->GetSetting
("DVDRipLocation");
@@ -41,7 +46,7 @@
if (!log_to_stdout)
{
logging_file.setFileName(logfile_name);
-
if (!logging_file.
open(QIODevice::
WriteOnly)) {
VERBOSE(VB_IMPORTANT, LOC_ERR + "\n\t\t\t" +
QString("Could not open logfile '%1' for writing") Index: mythvideo/mtd/jobthread.h
===================================================================
--- mythvideo/mtd/jobthread.h (revision 24265)
+++ mythvideo/mtd/jobthread.h (working copy)
@@ -206,8 +206,8 @@
virtual bool transcodeSlotUsed(void) const { return used_transcode_slot; }
- bool makeWorkingDirectory(void);
- bool buildTranscodeCommandLine(int which_run);
+ int makeWorkingDirectory(void);
+ int buildTranscodeCommandLine(int which_run);
bool runTranscode(int run);
void cleanUp(void);
void wipeClean(void);
Index: mythvideo/mythvideo/dvdripbox.cpp
===================================================================
--- mythvideo/mythvideo/dvdripbox.cpp (revision 24265)
+++ mythvideo/mythvideo/dvdripbox.cpp (working copy)
@@ -188,10 +188,155 @@
return true;
}
+// DVDRipBox::Init
+//
+// changed by m bennett 26/04/10
+
+// I have changed this to check for jobs not yet fully ripped and delete then
+// from the db, then place any jobs (in dvdtranscodejobs) that were fully
+// copied (state = 1) back into mtd
+
+// suggested improvemnets
+// The frontend would reprompt for the unripped jobs rather than delete them
+
void DVDRipBox::Init()
{
ConnectToMTD();
+ // here i would like to check for jobs stashed in the database
+ // and kick em off
+ // get the jobs out of the db
+ // Ideally Id like to repropmt the user for dvds that failed to be ripped
+ // the first time, but well just bin em for now
+ MSqlQuery getnoofnonrippedjobs_query(MSqlQuery::InitCon());
+ getnoofnonrippedjobs_query.prepare(
+ "SELECT COUNT(*) FROM dvdtranscodejobs WHERE state=0;");
+
+ if(!getnoofnonrippedjobs_query.exec())
+ {
+ VERBOSE(VB_IMPORTANT, "DIDNT get no of unrippedjobs");
+ }
+
+ if (!getnoofnonrippedjobs_query.next())
+ {
+ VERBOSE(VB_IMPORTANT, "get no of unrippedjobs query null return 1");
+ }
+
+ // this currently gets only the unripped first job - need to fix this
+ int noofunrippedjobs = getnoofnonrippedjobs_query.value(0).toInt();
+
+ if (noofunrippedjobs > 0)
+ {
+ // delete the jobs that havent been ripped both off the disk and the db
+ // it would be nice if the frontend demanded for these items after
+ // purging them
+
+ // remove any temporary titles that are now transcoded
+ MSqlQuery getunrippedjobs_query(MSqlQuery::InitCon());
+ getunrippedjobs_query.prepare(
+ "SELECT * FROM dvdtranscodejobs WHERE state=0;");
+
+ if(!getunrippedjobs_query.exec())
+ {
+ VERBOSE(VB_IMPORTANT, "DIDNT get unrippedjobs");
+ }
+
+
QString unused_final_dir_and_file;
+
+ MSqlQuery removenotdonejob_query(MSqlQuery::InitCon());
+
+ while(getunrippedjobs_query.next())
+ {
+// std::for_each(output_files.begin(), output_files.end(), delete_file());
+
+ unused_final_dir_and_file = getunrippedjobs_query.value(1).toString();
+
+ // remove the database entry
+ // and the one before (buildtrancodeCommandLine is called twice
+ // change this to search for like filnames
+ removenotdonejob_query.prepare(
+ "DELETE FROM dvdtranscodejobs WHERE `final_dir_and_file`"
+ " LIKE :RIPNAME;");
+ removenotdonejob_query.bindValue(":RIPNAME",
+ '%' + unused_final_dir_and_file);
+
+ if(!removenotdonejob_query.exec())
+ {
+ VERBOSE(VB_IMPORTANT, "Couldnt remove the unfinished job from"
+ "the database");
+ }
+
+ } // end while loop
+ }
+
+ VERBOSE(VB_IMPORTANT, "Got rid of blank entries");
+
+ // Now get the much more intresting ripped but not yet transcoded jobs
+ MSqlQuery getnoofrippedjobs_query(MSqlQuery::InitCon());
+ getnoofrippedjobs_query.prepare(
+ "SELECT COUNT(*) FROM dvdtranscodejobs WHERE state=1;");
+
+ if(!getnoofrippedjobs_query.exec())
+ {
+ VERBOSE(VB_IMPORTANT, "DIDNT get rippedjobs");
+ }
+
+ if (!getnoofrippedjobs_query.next())
+ {
+ VERBOSE(VB_IMPORTANT, "get noofrippedjobs query null return 1");
+ }
+
+ // this currently gets only the unripped first job - need to fix this
+ int noofrippedjobs = getnoofrippedjobs_query.value(0).toInt();
+
+ if (noofrippedjobs > 0)
+ {
+ // I dont know how clever the compiler is but im better we probablly
+ // have enough ram for an extra struct
+ MSqlQuery getrippedjobs_query(MSqlQuery::InitCon());
+ getrippedjobs_query.prepare(
+ "SELECT * FROM dvdtranscodejobs WHERE state=1;");
+
+ if(!getrippedjobs_query.exec())
+ {
+ VERBOSE(VB_IMPORTANT, "DIDNT get rippedjobs");
+ }
+
+ int rippedjobsindex;
+ int Track;
+ int Audio;
+ int Quality;
+ int AC3;
+ int SubTitle;
+
+ while(getrippedjobs_query.next())
+ {
+ rippedjobsindex = getrippedjobs_query.value(0).toInt();
+ final_dir_and_file = getrippedjobs_query.value(1).toString();
+ Track = getrippedjobs_query.value(2).toInt();
+ Audio = getrippedjobs_query.value(3).toInt();
+ Quality = getrippedjobs_query.value(4).toInt();
+ AC3 = getrippedjobs_query.value(5).toInt();
+ SubTitle = getrippedjobs_query.value(6).toInt();
+
+ // pipe them into mtd
+
+ .arg(Track)
+ .arg(Audio)
+ .arg(Quality)
+ .arg(AC3)
+ .arg(SubTitle)
+ .arg(final_dir_and_file);
+
+ os << job_string << "\n" ;
+ } // end while loop
+ }
+
+ VERBOSE(VB_IMPORTANT, "put in job entries");
+
// Create (but do not open) the DVD probing object
// and then ask a thread to check it for us. Make a
// timer to query whether the thread is done or not
@@ -827,7 +972,7 @@
&m_clientSocket,
m_dvdInfo->getName(),
m_dvdInfo->getTitles());
-
+
if (title_dialog->Create())
screenStack->AddScreen(title_dialog);
Index: mythvideo/mythvideo/titledialog.cpp
===================================================================
--- mythvideo/mythvideo/titledialog.cpp (revision 24265)
+++ mythvideo/mythvideo/titledialog.cpp (working copy)
@@ -190,7 +190,8 @@
else
m_ripacthreeCheck->SetCheckState(MythUIStateType::Off);
- m_numbtitlesText->SetText
(QString(tr
("Title %1 of %2")).
arg(m_currentTitle->getTrack
()).
arg(m_dvdTitles->size
()));
+ m_numbtitlesText->SetText
(QString(tr
("Title %1 of %2"))+ .arg(m_currentTitle->getTrack()).arg(m_dvdTitles->size()));
}
}
@@ -302,7 +303,8 @@
if(m_currentTitle)
{
audio_track = m_currentTitle->getAudio();
- DVDAudioInfo *audio_in_question = m_currentTitle->getAudioTrack(audio_track - 1);
+ DVDAudioInfo *audio_in_question =
+ m_currentTitle->getAudioTrack(audio_track - 1);
if(audio_in_question)
{
channels = audio_in_question->getChannels();
@@ -318,16 +320,20 @@
}
player_string = player_string.
replace(QRegExp("%d"), dvd_device
);
- player_string = player_string.
replace(QRegExp("%t"),
QString("%1").
arg(m_currentTitle->getTrack
()));
- player_string = player_string.
replace(QRegExp("%a"),
QString("%1").
arg(audio_track
));
- player_string = player_string.
replace(QRegExp("%c"),
QString("%1").
arg(channels
));
+ player_string = player_string.
replace(QRegExp("%t"),
+
QString("%1").
arg(m_currentTitle->getTrack
()));
+ player_string = player_string.
replace(QRegExp("%a"),
+ player_string = player_string.
replace(QRegExp("%c"),
if(m_currentTitle->getSubTitle() > -1)
{
QString player_append = gContext->GetSetting
("SubTitleCommand");
if(player_append.length() > 1)
{
- player_append = player_append.
replace(QRegExp("%s"),
QString("%1").
arg(m_currentTitle->getSubTitle
()));
+ player_append = player_append.
replace(QRegExp("%s"),
+
QString("%1").
arg(m_currentTitle->getSubTitle
()));
player_string += " ";
player_string += player_append;
}
@@ -337,6 +343,13 @@
myth_system(player_string);
}
+// void TitleDialog::ripTitles()
+//
+// changed by m bennett 18/04/10
+
+// I have changed this to insert a copy of the job string details into
+// dvdtranscodejobs with a state of 0
+
void TitleDialog::ripTitles()
{
//
@@ -388,11 +401,13 @@
if(destination_directory.length() < 1)
{
- VERBOSE(VB_IMPORTANT, "titledialog.o: I can't rip, as I have nowhere to put finished files. MythVideo installed?");
+ VERBOSE(VB_IMPORTANT, "titledialog.o: I can't rip, as I have "
+ "nowhere to put finished files. MythVideo installed?");
return;
}
-
QString final_dir_and_file = destination_directory +
"/" + m_dvdTitles->at
(i
)->getName
();
+
QString final_dir_and_file = destination_directory +
"/" + + m_dvdTitles->at(i)->getName();
.arg(m_dvdTitles->at(i)->getTrack())
@@ -401,7 +416,80 @@
.arg(m_dvdTitles->at(i)->getAC3())
.arg(m_dvdTitles->at(i)->getSubTitle())
.arg(final_dir_and_file);
+
+ // read back the data
+ "getAC3,getSubTitle,getSubTitle "
+ "FROM dvdtranscode ;");
+ MSqlQuery a_query(MSqlQuery::InitCon());
+
+ if(a_query.exec(q_string))
+ {
+ while(a_query.next())
+ {
+ new MythUIButtonListItem(m_qualityList,
+ a_query.value(0).toString(), a_query.value(1).toInt());
+ }
+ } // end make job string
+
+ VERBOSE(VB_IMPORTANT, job_string);
+
+ // here is the magic place, we need to put this data into the db
+ // so that if mtd or the box it is on dies, that mtd can pick up
+ // this data on restart
+
+ MSqlQuery getjobindex_query(MSqlQuery::InitCon());
+ getjobindex_query.prepare(
+ "SELECT max(jobindex) from dvdtranscodejobs;");
+
+ if(!getjobindex_query.exec())
+ {
+ VERBOSE(VB_IMPORTANT, "DIDNT get max result");
+ }
+
+ if (!getjobindex_query.next())
+ {
+ VERBOSE(VB_IMPORTANT, "get next jobs query null return");
+ }
+
+ int current_dvdtranscode_job_index =
+ getjobindex_query.value(0).toInt();
+
+ .arg(current_dvdtranscode_job_index);
+
+ VERBOSE(VB_IMPORTANT, op_string);
+
+ int new_dvdtranscode_job_index = current_dvdtranscode_job_index + 1;
+
+ MSqlQuery dvdtranscodejob_query(MSqlQuery::InitCon());
+
+ dvdtranscodejob_query.prepare(
+ "INSERT INTO dvdtranscodejobs VALUES (:JOBID, :FINALDIRANDFILE"
+ ", :TRACK, :AUDIO, :QUALITY, :AC3, :SUBTITLE, 0, :BACKEND);");
+ dvdtranscodejob_query.bindValue(":JOBID",
+ new_dvdtranscode_job_index);
+ dvdtranscodejob_query.bindValue(":FINALDIRANDFILE",
+ final_dir_and_file);
+ dvdtranscodejob_query.bindValue(":TRACK",
+ m_dvdTitles->at(i)->getTrack());
+ dvdtranscodejob_query.bindValue(":AUDIO",
+ m_dvdTitles->at(i)->getAudio());
+ dvdtranscodejob_query.bindValue(":QUALITY",
+ m_dvdTitles->at(i)->getQuality());
+ dvdtranscodejob_query.bindValue(":AC3",
+ m_dvdTitles->at(i)->getAC3());
+ dvdtranscodejob_query.bindValue(":SUBTITLE",
+ m_dvdTitles->at(i)->getSubTitle());
+ dvdtranscodejob_query.bindValue(":BACKEND", "");
+
+ if(!dvdtranscodejob_query.exec())
+ {
+ VERBOSE(VB_IMPORTANT,
+ "DIDNT insert into transcode values into db");
+ }
+
os << job_string << "\n" ;
}