gui/moviebrowser.cpp: remove old TS cut code

This commit is contained in:
[CST] Focus
2015-02-20 18:37:56 +03:00
parent b96a087633
commit cc4f10297d

View File

@@ -67,23 +67,18 @@
#include <system/helpers.h> #include <system/helpers.h>
#include <system/ytcache.h> #include <system/ytcache.h>
#include <zapit/debug.h> #include <zapit/debug.h>
#include <driver/moviecut.h>
#include <timerdclient/timerdclient.h> #include <timerdclient/timerdclient.h>
#include <system/hddstat.h> #include <system/hddstat.h>
extern CPictureViewer * g_PicViewer; extern CPictureViewer * g_PicViewer;
static CProgressBar *timescale;
#define my_scandir scandir64 #define my_scandir scandir64
#define my_alphasort alphasort64 #define my_alphasort alphasort64
typedef struct stat64 stat_struct; typedef struct stat64 stat_struct;
typedef struct dirent64 dirent_struct; typedef struct dirent64 dirent_struct;
#define my_stat stat64 #define my_stat stat64
//static off64_t truncate_movie(char * name, off64_t size, int len, int seconds);
static off64_t truncate_movie(MI_MOVIE_INFO * minfo);
static off64_t cut_movie(MI_MOVIE_INFO * minfo, CMovieInfo * cmovie);
static off64_t copy_movie(MI_MOVIE_INFO * minfo, CMovieInfo * cmovie, bool onefile);
#define TRACE printf #define TRACE printf
#define NUMBER_OF_MOVIES_LAST 40 // This is the number of movies shown in last recored and last played list #define NUMBER_OF_MOVIES_LAST 40 // This is the number of movies shown in last recored and last played list
@@ -1769,7 +1764,8 @@ bool CMovieBrowser::onButtonPressMainFrame(neutrino_msg_t msg)
hintBox->hide(); hintBox->hide();
delete hintBox; delete hintBox;
framebuffer->paintBackground(); // clear screen framebuffer->paintBackground(); // clear screen
off64_t res = copy_movie(m_movieSelectionHandler, &m_movieInfo, msg == CRCInput::RC_radio); CMovieCut mc;
bool res = mc.copyMovie(m_movieSelectionHandler, &m_movieInfo, msg == CRCInput::RC_radio);
//g_RCInput->clearRCMsg(); //g_RCInput->clearRCMsg();
if (res == 0) if (res == 0)
ShowMsg(LOCALE_MESSAGEBOX_ERROR, LOCALE_MOVIEBROWSER_COPY_FAILED, CMessageBox::mbrCancel, CMessageBox::mbCancel, NEUTRINO_ICON_ERROR); ShowMsg(LOCALE_MESSAGEBOX_ERROR, LOCALE_MOVIEBROWSER_COPY_FAILED, CMessageBox::mbrCancel, CMessageBox::mbCancel, NEUTRINO_ICON_ERROR);
@@ -1792,13 +1788,14 @@ bool CMovieBrowser::onButtonPressMainFrame(neutrino_msg_t msg)
hintBox->hide(); hintBox->hide();
delete hintBox; delete hintBox;
framebuffer->paintBackground(); // clear screen framebuffer->paintBackground(); // clear screen
off64_t res = cut_movie(m_movieSelectionHandler, &m_movieInfo); CMovieCut mc;
bool res = mc.cutMovie(m_movieSelectionHandler, &m_movieInfo);
//g_RCInput->clearRCMsg(); //g_RCInput->clearRCMsg();
if (res == 0) if (!res)
ShowMsg(LOCALE_MESSAGEBOX_ERROR, LOCALE_MOVIEBROWSER_CUT_FAILED, CMessageBox::mbrCancel, CMessageBox::mbCancel, NEUTRINO_ICON_ERROR); ShowMsg(LOCALE_MESSAGEBOX_ERROR, LOCALE_MOVIEBROWSER_CUT_FAILED, CMessageBox::mbrCancel, CMessageBox::mbCancel, NEUTRINO_ICON_ERROR);
else { else
loadMovies(); loadMovies();
}
refresh(); refresh();
} }
} }
@@ -1812,11 +1809,13 @@ bool CMovieBrowser::onButtonPressMainFrame(neutrino_msg_t msg)
if (ShowMsg(LOCALE_MESSAGEBOX_INFO, LOCALE_MOVIEBROWSER_TRUNCATE, CMessageBox::mbrNo, CMessageBox::mbYes | CMessageBox::mbNo) == CMessageBox::mbrYes) { if (ShowMsg(LOCALE_MESSAGEBOX_INFO, LOCALE_MOVIEBROWSER_TRUNCATE, CMessageBox::mbrNo, CMessageBox::mbYes | CMessageBox::mbNo) == CMessageBox::mbrYes) {
CHintBox * hintBox = new CHintBox(LOCALE_MESSAGEBOX_INFO, LOCALE_MOVIEBROWSER_TRUNCATING); CHintBox * hintBox = new CHintBox(LOCALE_MESSAGEBOX_INFO, LOCALE_MOVIEBROWSER_TRUNCATING);
hintBox->paint(); hintBox->paint();
off64_t res = truncate_movie(m_movieSelectionHandler);
CMovieCut mc;
bool res = mc.truncateMovie(m_movieSelectionHandler);
hintBox->hide(); hintBox->hide();
delete hintBox; delete hintBox;
g_RCInput->clearRCMsg(); g_RCInput->clearRCMsg();
if (res == 0) if (!res)
ShowMsg(LOCALE_MESSAGEBOX_ERROR, LOCALE_MOVIEBROWSER_TRUNCATE_FAILED, CMessageBox::mbrCancel, CMessageBox::mbCancel, NEUTRINO_ICON_ERROR); ShowMsg(LOCALE_MESSAGEBOX_ERROR, LOCALE_MOVIEBROWSER_TRUNCATE_FAILED, CMessageBox::mbrCancel, CMessageBox::mbCancel, NEUTRINO_ICON_ERROR);
else { else {
//printf("New movie info: size %lld len %d\n", res, m_movieSelectionHandler->bookmarks.end/60); //printf("New movie info: size %lld len %d\n", res, m_movieSelectionHandler->bookmarks.end/60);
@@ -3888,669 +3887,3 @@ int CDirMenu::show(void)
int ret = dirMenu.exec(NULL," "); int ret = dirMenu.exec(NULL," ");
return ret; return ret;
} }
static void reset_atime(char * path, time_t tt)
{
struct utimbuf ut;
ut.actime = tt-1;
ut.modtime = tt-1;
utime(path, &ut);
}
#define BUF_SIZE 1395*188
#define SAFE_GOP 1395*188
#define MP_TS_SIZE 262072 // ~0.5 sec
#define MINUTEOFFSET 117*262072
#define SECONDOFFSET MP_TS_SIZE*2
static off64_t truncate_movie(MI_MOVIE_INFO * minfo)
{
struct stat64 s;
char spart[255];
int part = 0, tpart = 0;
bool found = 0;
const char *name = minfo->file.Name.c_str();
off64_t size = minfo->file.Size;
int len = minfo->length;
int seconds = minfo->bookmarks.end;
off64_t minuteoffset = len ? size / len : MINUTEOFFSET;
minuteoffset = (minuteoffset / MP_TS_SIZE) * MP_TS_SIZE;
if (minuteoffset < 10000000 || minuteoffset > 90000000)
minuteoffset = MINUTEOFFSET;
off64_t secsize = minuteoffset/60;
off64_t secoffset = secsize * seconds;
off64_t newsize = secoffset;
//printf("truncate: name %s size %lld len %d sec truncate to %d sec, new size %lld\n", name, size, len, seconds, secoffset);
snprintf(spart, sizeof(spart), "%s", name);
while (!stat64(spart, &s)) {
if (found) {
//printf("truncate: check part %d file %s - TO REMOVE\n", part, spart);
unlink(spart);
} else {
//printf("truncate: check part %d file %s - OK\n", part, spart);
if (secoffset < s.st_size) {
tpart = part;
found = 1;
} else
secoffset -= s.st_size;
}
snprintf(spart, sizeof(spart), "%s.%03d", name, ++part);
}
if (found) {
if (tpart)
snprintf(spart, sizeof(spart), "%s.%03d", name, tpart);
else
snprintf(spart, sizeof(spart), "%s", name);
printf("truncate: part %s to size %" PRId64 "\n", spart, secoffset);
truncate(spart, secoffset);
minfo->file.Size = newsize;
minfo->length = minfo->bookmarks.end/60;
minfo->bookmarks.end = 0;
reset_atime(spart, minfo->file.Time);
return newsize;
}
return 0;
}
struct mybook {
off64_t pos;
off64_t len;
bool ok;
};
#define REAL_CUT 1
static int check_pes_start (unsigned char *packet)
{
// PCKT: 47 41 91 37 07 50 3F 14 BF 04 FE B9 00 00 01 EA 00 00 8C ...
if (packet[0] == 0x47 && // sync byte 0x47
(packet[1] & 0x40)) // pusi == 1
{
/* good, now we have to check if it is video stream */
unsigned char *pes = packet + 4;
if (packet[3] & 0x20) // adaptation field is present
pes += packet[4] + 1;
if (!memcmp(pes, "\x00\x00\x01", 3) && (pes[3] & 0xF0) == 0xE0) // PES start & video type
{
//return 1; //(pes[4] << 8) | pes[5]; // PES packet len
pes += 4;
while (pes < (packet + 188 - 4))
if (!memcmp(pes, "\x00\x00\x01\xB8", 4)) // GOP detect
return 1;
else
pes++;
}
}
return 0;
}
int find_gop(unsigned char *buf, int r)
{
for (int j = 0; j < r/188; j++) {
if (check_pes_start(&buf[188*j])) {
return 188*j;
}
}
return -1;
}
#if 0
//never used
off64_t fake_read(int fd, unsigned char *buf, size_t size, off64_t fsize)
{
off64_t cur = lseek64(fd, 0, SEEK_CUR);
buf[0] = 0x47;
if((cur + size) > fsize)
return(fsize - cur);
else
return size;
}
#endif
#define PSI_SIZE 188*3
static int read_psi(char * spart, unsigned char * buf)
{
int srcfd = open(spart, O_RDONLY | O_LARGEFILE);
if (srcfd >= 0) {
/* read psi */
int r = read(srcfd, buf, PSI_SIZE);
close(srcfd);
if (r != PSI_SIZE) {
perror("read psi");
return -1;
}
return 0;
}
return -1;
}
static void save_info(CMovieInfo * cmovie, MI_MOVIE_INFO * minfo, char * dpart, off64_t spos, off64_t secsize)
{
MI_MOVIE_INFO ninfo = *minfo;
ninfo.file.Name = dpart;
ninfo.file.Size = spos;
ninfo.length = spos/secsize/60;
ninfo.bookmarks.end = 0;
ninfo.bookmarks.start = 0;
ninfo.bookmarks.lastPlayStop = 0;
for (int book_nr = 0; book_nr < MI_MOVIE_BOOK_USER_MAX; book_nr++) {
if (ninfo.bookmarks.user[book_nr].pos != 0 && ninfo.bookmarks.user[book_nr].length > 0) {
ninfo.bookmarks.user[book_nr].pos = 0;
ninfo.bookmarks.user[book_nr].length = 0;
}
}
cmovie->saveMovieInfo(ninfo);
reset_atime(dpart, minfo->file.Time);
}
static void find_new_part(char * npart, char * dpart,size_t dpart_len)
{
struct stat64 s;
int dp = 0;
snprintf(dpart, dpart_len, "%s_%d.ts", npart, dp);
while (!stat64(dpart, &s)) {
snprintf(dpart, dpart_len, "%s_%d.ts", npart, ++dp);
}
}
int compare_book(const void *x, const void *y)
{
struct mybook * px, * py;
int dx, dy;
px = (struct mybook*) x;
py = (struct mybook*) y;
dx = px->pos / (off64_t) 1024;
dy = py->pos / (off64_t) 1024;
int res = dx - dy;
//printf("SORT: %lld and %lld res %d\n", px->pos, py->pos, res);
return res;
}
static int get_input(bool * stop)
{
neutrino_msg_data_t data;
neutrino_msg_t msg;
int retval = 0;
* stop = false;
g_RCInput->getMsg(&msg, &data, 1, false);
if (msg == CRCInput::RC_home) {
if (ShowMsg(LOCALE_MESSAGEBOX_INFO, "Cancel movie cut/split ?", CMessageBox::mbrNo, CMessageBox::mbYes | CMessageBox::mbNo) == CMessageBox::mbrYes) {
* stop = true;
}
}
if (msg != CRCInput::RC_timeout)
retval |= 1;
if (CNeutrinoApp::getInstance()->handleMsg(msg, data) & messages_return::cancel_all)
retval |= 2;
//printf("input: msg %d (%x) ret %d\n", msg, msg, retval);
return retval;
}
static off64_t cut_movie(MI_MOVIE_INFO * minfo, CMovieInfo * cmovie)
{
struct mybook books[MI_MOVIE_BOOK_USER_MAX+2];
int bcount = 0;
int dstfd, srcfd;
int part = 0;
struct stat64 s;
char spart[255];
char dpart[255];
char npart[255];
unsigned char psi[PSI_SIZE];
int r, i;
off64_t sdone, spos;
off64_t newsize;
time_t tt;
int percent = 0;
char * name = (char *) minfo->file.Name.c_str();
CFile file;
MI_MOVIE_INFO ninfo;
bool need_gop = 0;
off64_t tdone = 0;
int was_cancel = 0;
int retval = 0;
time_t tt1;
off64_t bpos, bskip;
unsigned char * buf = new unsigned char[BUF_SIZE];
if (buf == 0) {
perror("new");
return 0;
}
CFrameBuffer * frameBuffer = CFrameBuffer::getInstance();
if (! timescale)
timescale = new CProgressBar();
timescale->setType(CProgressBar::PB_TIMESCALE);
int dx = 256;
int x = (((g_settings.screen_EndX- g_settings.screen_StartX)- dx) / 2) + g_settings.screen_StartX;
int y = g_settings.screen_EndY - 50;
frameBuffer->paintBoxRel(x + 40, y+12, 200, 15, COL_INFOBAR_PLUS_0);//TODO: remove unneeded box paints
timescale->setProgress(x + 41, y + 12, 200, 15, percent, 100);
timescale->paint();
int len = minfo->length;
off64_t size = minfo->file.Size;
//off64_t secsize = len ? size/len/60 : 511040;
off64_t minuteoffset = len ? size / len : MINUTEOFFSET;
minuteoffset = (minuteoffset / MP_TS_SIZE) * MP_TS_SIZE;
if (minuteoffset < 5000000 || minuteoffset > 190000000)
minuteoffset = MINUTEOFFSET;
off64_t secsize = minuteoffset/60;
newsize = size;
if (minfo->bookmarks.start != 0) {
books[bcount].pos = 0;
books[bcount].len = (minfo->bookmarks.start * secsize)/188 * 188;
if (books[bcount].len > SAFE_GOP)
books[bcount].len -= SAFE_GOP;
books[bcount].ok = 1;
printf("cut: start bookmark %d at %" PRId64 " len %" PRId64 "\n", bcount, books[bcount].pos, books[bcount].len);
bcount++;
}
for (int book_nr = 0; book_nr < MI_MOVIE_BOOK_USER_MAX; book_nr++) {
if (minfo->bookmarks.user[book_nr].pos != 0 && minfo->bookmarks.user[book_nr].length > 0) {
books[bcount].pos = (minfo->bookmarks.user[book_nr].pos * secsize)/188 * 188;
books[bcount].len = (minfo->bookmarks.user[book_nr].length * secsize)/188 * 188;
if (books[bcount].len > SAFE_GOP)
books[bcount].len -= SAFE_GOP;
books[bcount].ok = 1;
printf("cut: jump bookmark %d at %" PRId64 " len %" PRId64 " -> skip to %" PRId64 "\n", bcount, books[bcount].pos, books[bcount].len, books[bcount].pos+books[bcount].len);
bcount++;
}
}
if (minfo->bookmarks.end != 0) {
books[bcount].pos = ((off64_t) minfo->bookmarks.end * secsize)/188 * 188;
books[bcount].len = size - books[bcount].pos;
//if (books[bcount].pos > SAFE_GOP)
// books[bcount].pos -= SAFE_GOP;
books[bcount].ok = 1;
printf("cut: end bookmark %d at %" PRId64 "\n", bcount, books[bcount].pos);
bcount++;
}
printf("\n");
if (!bcount) {
delete [] buf;
return 0;
}
qsort(books, bcount, sizeof(struct mybook), compare_book);
for (i = 0; i < bcount; i++) {
if (books[i].ok) {
printf("cut: bookmark %d at %" PRId64 " len %" PRId64 " -> skip to %" PRId64 "\n", i, books[i].pos, books[i].len, books[i].pos+books[i].len);
newsize -= books[i].len;
off64_t curend = books[i].pos + books[i].len;
for (int j = i + 1; j < bcount; j++) {
if ((books[j].pos > books[i].pos) && (books[j].pos < curend)) {
off64_t newend = books[j].pos + books[j].len;
if (newend > curend) {
printf("cut: bad bookmark %d, position %" PRId64 " len %" PRId64 ", ajusting..\n", j, books[j].pos, books[j].len);
books[j].pos = curend;
books[j].len = newend - curend;
} else {
printf("cut: bad bookmark %d, position %" PRId64 " len %" PRId64 ", skipping..\n", j, books[j].pos, books[j].len);
books[j].ok = 0;
}
}
}
}
}
snprintf(npart, sizeof(npart), "%s", name);
char * ptr = strstr(npart+strlen(npart)-3, ".ts");
if (ptr)
*ptr = 0;
find_new_part(npart, dpart, sizeof(dpart));
tt = time(0);
printf("\n********* new file %s expected size %" PRId64 ", start time %s", dpart, newsize, ctime(&tt));
dstfd = open(dpart, O_CREAT|O_WRONLY|O_TRUNC| O_LARGEFILE, 0644);
if (dstfd < 0) {
perror(dpart);
delete [] buf;
return 0;
}
part = 0;
i = 0;
off64_t offset = 0;
spos = 0;
snprintf(spart, sizeof(spart), "%s", name);
if (read_psi(spart, &psi[0])) {
perror(spart);
goto ret_err;
}
write(dstfd, psi, PSI_SIZE);
bpos = books[i].pos;
bskip = books[i].len;
while (!stat64(spart, &s)) {
printf("cut: open part %d file %s size %" PRId64 " offset %" PRId64 " book pos %" PRId64 "\n", part, spart, s.st_size, offset, bpos);
srcfd = open(spart, O_RDONLY | O_LARGEFILE);
if (srcfd < 0) {
perror(spart);
goto ret_err;
}
if (offset >= s.st_size) {
offset -= s.st_size;
bpos -= s.st_size;
goto next_file;
}
lseek64(srcfd, offset, SEEK_SET);
sdone = offset;
while (true) {
off64_t until = bpos;
printf("\ncut: reading from %" PRId64 " to %" PRId64 " (%" PRId64 ") want gop %d\n", sdone, until, until - sdone, need_gop);
while (sdone < until) {
bool stop;
int msg = get_input(&stop);
was_cancel = msg & 2;
if (stop) {
close(srcfd);
unlink(dpart);
retval = 1;
goto ret_err;
}
if (msg) {
timescale->reset();
frameBuffer->paintBoxRel(x + 40, y+12, 200, 15, COL_INFOBAR_PLUS_0);//TODO: remove unneeded box paints
}
size_t toread = (until-sdone) > BUF_SIZE ? BUF_SIZE : until - sdone;
#if REAL_CUT
r = read(srcfd, buf, toread);
#else
r = fake_read(srcfd, buf, toread, s.st_size);
#endif
if (r > 0) {
int wptr = 0;
// FIXME: TEST
if (r != BUF_SIZE) printf("****** short read ? %d\n", r);
if (buf[0] != 0x47) printf("cut: buffer not aligned at %" PRId64 "\n", sdone);
if (need_gop) {
int gop = find_gop(buf, r);
if (gop >= 0) {
printf("cut: GOP found at %" PRId64 " offset %d\n", (off64_t)(sdone+gop), gop);
newsize -= gop;
wptr = gop;
} else
printf("cut: GOP needed, but not found\n");
need_gop = 0;
}
sdone += r;
spos += r - wptr;
percent = (int) ((float)(spos)/(float)(newsize)*100.);
timescale->setProgress(x + 41, y + 12, 200, 15, percent, 100);
timescale->paint();
#if REAL_CUT
int wr = write(dstfd, &buf[wptr], r-wptr);
if (wr < (r-wptr)) {
perror(dpart);
close(srcfd);
goto ret_err;
}
#endif
} else if (sdone < s.st_size) {
/* read error ? */
close(srcfd);
perror(spart);
goto ret_err;
} else {
printf("cut: next file -> sdone %" PRId64 " spos %" PRId64 " bpos %" PRId64 "\n", sdone, spos, bpos);
offset = 0;
bpos -= sdone;
goto next_file;
}
}
printf("cut: current file pos %" PRId64 " write pos %" PRId64 " book pos %" PRId64 " still to read %" PRId64 "\n", sdone, spos, bpos, sdone - bpos);
need_gop = 1;
offset = bpos + bskip;
i++;
while (i < bcount) {
if (books[i].ok)
break;
else
i++;
}
if (i < bcount) {
bpos = books[i].pos;
bskip = books[i].len;
} else
bpos = size;
printf("cut: next bookmark pos: %" PRId64 " abs %" PRId64 " relative next file pos %" PRId64 " cur file size %" PRId64 "\n", bpos, bpos - tdone, offset, s.st_size);
bpos -= tdone; /* all books from 0, converting to 0 + total size skipped */
if (offset >= s.st_size) {
offset -= s.st_size;
bpos -= s.st_size;
goto next_file;
}
lseek64(srcfd, offset, SEEK_SET);
sdone = offset;
}
next_file:
tdone += s.st_size;
close(srcfd);
snprintf(spart, sizeof(spart), "%s.%03d", name, ++part);
}
tt1 = time(0);
printf("********* total written %" PRId64 " tooks %ld secs end time %s", spos, tt1-tt, ctime(&tt1));
save_info(cmovie, minfo, dpart, spos, secsize);
retval = 1;
lseek64(dstfd, 0, SEEK_SET);
ret_err:
close(dstfd);
delete [] buf;
if (was_cancel)
g_RCInput->postMsg(CRCInput::RC_home, 0);
return retval;
}
static off64_t copy_movie(MI_MOVIE_INFO * minfo, CMovieInfo * cmovie, bool onefile)
{
struct mybook books[MI_MOVIE_BOOK_USER_MAX+2];
int bcount = 0;
int dstfd = -1, srcfd;
int part = 0;
struct stat64 s;
char spart[255];
char dpart[255];
char npart[255];
unsigned char psi[PSI_SIZE];
int r, i;
off64_t sdone, spos = 0, btotal = 0;
off64_t newsize;
time_t tt;
int percent = 0;
char * name = (char *) minfo->file.Name.c_str();
CFile file;
bool need_gop = 0;
bool dst_done = 0;
bool was_cancel = false;
int retval = 0;
unsigned char * buf = new unsigned char[BUF_SIZE];
if (buf == 0) {
perror("new");
return 0;
}
int len = minfo->length;
off64_t size = minfo->file.Size;
off64_t minuteoffset = len ? size / len : MINUTEOFFSET;
minuteoffset = (minuteoffset / MP_TS_SIZE) * MP_TS_SIZE;
if (minuteoffset < 5000000 || minuteoffset > 190000000)
minuteoffset = MINUTEOFFSET;
off64_t secsize = minuteoffset/60;
//off64_t secsize = len ? size/len/60 : 511040;
printf("copy: len %d minute %" PRId64 " second %" PRId64 "\n", len, len ? size/len : 511040*60, secsize);
CFrameBuffer * frameBuffer = CFrameBuffer::getInstance();
if (!timescale)
timescale = new CProgressBar();
timescale->setType(CProgressBar::PB_TIMESCALE);
int dx = 256;
int x = (((g_settings.screen_EndX- g_settings.screen_StartX)- dx) / 2) + g_settings.screen_StartX;
int y = g_settings.screen_EndY - 50;
frameBuffer->paintBoxRel(x + 40, y+12, 200, 15, COL_INFOBAR_PLUS_0); //TODO: remove unneeded box paints
timescale->setProgress(x + 41, y + 12, 200, 15, percent, 100);
timescale->paint();
newsize = 0;
for (int book_nr = 0; book_nr < MI_MOVIE_BOOK_USER_MAX; book_nr++) {
if (minfo->bookmarks.user[book_nr].pos != 0 && minfo->bookmarks.user[book_nr].length > 0) {
books[bcount].pos = (minfo->bookmarks.user[book_nr].pos * secsize)/188 * 188;
if (books[bcount].pos > SAFE_GOP)
books[bcount].pos -= SAFE_GOP;
books[bcount].len = (minfo->bookmarks.user[book_nr].length * secsize)/188 * 188;
books[bcount].ok = 1;
printf("copy: jump bookmark %d at %" PRId64 " len %" PRId64 "\n", bcount, books[bcount].pos, books[bcount].len);
newsize += books[bcount].len;
bcount++;
}
}
if (!bcount) {
delete [] buf;
return 0;
}
tt = time(0);
printf("********* %d boormarks, to %s file(s), expected size to copy %" PRId64 ", start time %s", bcount, onefile ? "one" : "many", newsize, ctime(&tt));
snprintf(npart, sizeof(npart), "%s", name);
char * ptr = strstr(npart+strlen(npart)-3, ".ts");
if (ptr)
*ptr = 0;
snprintf(spart, sizeof(spart), "%s", name);
srcfd = open(spart, O_RDONLY | O_LARGEFILE);
if (read_psi(spart, &psi[0])) {
perror(spart);
goto ret_err;
}
for (i = 0; i < bcount; i++) {
printf("\ncopy: processing bookmark %d at %" PRId64 " len %" PRId64 "\n", i, books[i].pos, books[i].len);
off64_t bpos = books[i].pos;
off64_t bskip = books[i].len;
part = 0;
snprintf(spart, sizeof(spart), "%s", name);
int sres;
while (!(sres = stat64(spart, &s))) {
if (bpos >= s.st_size) {
bpos -= s.st_size;
snprintf(spart, sizeof(spart), "%s.%03d", name, ++part);
//printf("copy: check src part %s\n", spart);
continue;
}
break;
}
if (sres != 0) {
printf("file for bookmark %d with offset %" PRId64 " not found\n", i, books[i].pos);
continue;
}
if (!dst_done || !onefile) {
find_new_part(npart, dpart, sizeof(dpart));
dstfd = open(dpart, O_CREAT|O_WRONLY|O_TRUNC| O_LARGEFILE, 0644);
printf("copy: new file %s fd %d\n", dpart, dstfd);
if (dstfd < 0) {
printf("failed to open %s\n", dpart);
goto ret_err;;
}
dst_done = 1;
spos = 0;
write(dstfd, psi, PSI_SIZE);
}
need_gop = 1;
next_file:
stat64(spart, &s);
printf("copy: open part %d file %s size %" PRId64 " offset %" PRId64 "\n", part, spart, s.st_size, bpos);
srcfd = open(spart, O_RDONLY | O_LARGEFILE);
if (srcfd < 0) {
printf("failed to open %s\n", spart);
close(dstfd);
goto ret_err;
}
lseek64(srcfd, bpos, SEEK_SET);
sdone = bpos;
off64_t until = bpos + bskip;
printf("copy: read from %" PRId64 " to %" PRId64 " read size %d want gop %d\n", bpos, until, BUF_SIZE, need_gop);
while (sdone < until) {
size_t toread = (until-sdone) > BUF_SIZE ? BUF_SIZE : until - sdone;
bool stop;
int msg = get_input(&stop);
was_cancel = msg & 2;
if (stop) {
close(srcfd);
close(dstfd);
unlink(dpart);
retval = 1;
goto ret_err;
}
if (msg) {
frameBuffer->paintBoxRel(x + 40, y+12, 200, 15, COL_INFOBAR_PLUS_0);//TODO: remove unneeded box paints
timescale->reset();
}
#if REAL_CUT
r = read(srcfd, buf, toread);
#else
r = fake_read(srcfd, buf, toread, s.st_size);
#endif
if (r > 0) {
int wptr = 0;
// FIXME: TEST
if (r != BUF_SIZE) printf("****** short read ? %d\n", r);
if (buf[0] != 0x47) printf("copy: buffer not aligned at %" PRId64 "\n", sdone);
if (need_gop) {
int gop = find_gop(buf, r);
if (gop >= 0) {
printf("cut: GOP found at %" PRId64 " offset %d\n", (off64_t)(sdone+gop), gop);
newsize -= gop;
wptr = gop;
} else
printf("cut: GOP needed, but not found\n");
need_gop = 0;
}
sdone += r;
bskip -= r;
spos += r - wptr;
btotal += r;
percent = (int) ((float)(btotal)/(float)(newsize)*100.);
timescale->setProgress(x + 41, y + 12, 200, 15, percent, 100);
timescale->paint();
#if REAL_CUT
int wr = write(dstfd, &buf[wptr], r-wptr);
if (wr < (r-wptr)) {
printf("write to %s failed\n", dpart);
close(srcfd);
close(dstfd);
goto ret_err;
}
#endif
} else if (sdone < s.st_size) {
/* read error ? */
printf("%s: read failed\n", spart);
close(srcfd);
close(dstfd);
goto ret_err;
} else {
printf("copy: -> next file, file pos %" PRId64 " written %" PRId64 " left %" PRId64 "\n", sdone, spos, bskip);
bpos = 0;
close(srcfd);
snprintf(spart, sizeof(spart), "%s.%03d", name, ++part);
goto next_file;
}
} /* while(sdone < until) */
close(srcfd);
if (!onefile) {
close(dstfd);
save_info(cmovie, minfo, dpart, spos, secsize);
time_t tt1 = time(0);
printf("copy: ********* %s: total written %" PRId64 " took %ld secs\n", dpart, spos, tt1-tt);
}
} /* for all books */
if (onefile) {
close(dstfd);
save_info(cmovie, minfo, dpart, spos, secsize);
time_t tt1 = time(0);
printf("copy: ********* %s: total written %" PRId64 " took %ld secs\n", dpart, spos, tt1-tt);
}
retval = 1;
ret_err:
delete [] buf;
if (was_cancel)
g_RCInput->postMsg(CRCInput::RC_home, 0);
return retval;
}
// vim:ts=4