コード例 #1
0
bool CMovieCut::truncateMovie(MI_MOVIE_INFO * minfo)
{
	off64_t secsize = getSecondSize(minfo);
	if (minfo->bookmarks.end == 0 || secsize == 0)
		return false;

	off64_t newsize = secsize * minfo->bookmarks.end;

	printf("CMovieCut::%s: [%s] truncate to %d sec, new size %" PRId64 "\n", __func__, minfo->file.Name.c_str(), minfo->bookmarks.end, newsize);
	if (truncate(minfo->file.Name.c_str(), newsize)) {
		perror(minfo->file.Name.c_str());
		return false;
	}
	minfo->file.Size = newsize;
	minfo->length = minfo->bookmarks.end/60;
	minfo->bookmarks.end = 0;
	reset_atime(minfo->file.Name.c_str(), minfo->file.Time);
	CMovieInfo cmovie;
	cmovie.saveMovieInfo(*minfo);
	WriteHeader(minfo->file.Name.c_str(), newsize/secsize*1000);
	return true;
}
コード例 #2
0
bool CMovieCut::copyMovie(MI_MOVIE_INFO * minfo, bool onefile)
{
	struct mybook books[MI_MOVIE_BOOK_USER_MAX+2];
	struct stat64 s;
	char dpart[255];
	unsigned char psi[PSI_SIZE];
	int dstfd = -1, srcfd = -1;
	off64_t spos = 0, btotal = 0;
	time_t tt = time(0);
	bool need_gop = 0;
	bool dst_done = 0;
	bool was_cancel = false;
	bool retval = false;
	int bcount = 0;
	off64_t newsize = 0;

	off64_t secsize = getSecondSize(minfo);
	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)
		return false;

	unsigned char * buf = new unsigned char[BUF_SIZE];
	if (buf == 0) {
		perror("new");
		return false;
	}

	paintProgress(true);

	printf("********* %d boormarks, to %s file(s), expected size to copy %" PRId64 ", start time %s", bcount, onefile ? "one" : "many", newsize, ctime(&tt));
	if (read_psi(minfo->file.Name.c_str(), &psi[0])) {
		perror(minfo->file.Name.c_str());
		goto ret_err;
	}
	srcfd = open(minfo->file.Name.c_str(), O_RDONLY | O_LARGEFILE);
	if (srcfd < 0) {
		perror(minfo->file.Name.c_str());
		goto ret_err;
	}
	stat64(minfo->file.Name.c_str(), &s);
	for (int i = 0; i < bcount; i++) {
		printf("\ncopy: processing bookmark %d at %" PRId64 " len %" PRId64 "\n", i, books[i].pos, books[i].len);

		if (!dst_done || !onefile) {
			findNewName(minfo->file.Name.c_str(), 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;

		off64_t offset = books[i].pos;
		lseek64(srcfd, offset, SEEK_SET);
		off64_t until = books[i].pos + books[i].len;
		printf("copy: read from %" PRId64 " to %" PRId64 " read size %d want gop %d\n", offset, until, BUF_SIZE, need_gop);
		while (offset < until) {
			size_t toread = (until-offset) > BUF_SIZE ? BUF_SIZE : until - offset;
			int msg = getInput();
			was_cancel = msg & 2;
			if (msg & 4) {
				unlink(dpart);
				retval = true;
				goto ret_err;
			}
			size_t r = read(srcfd, buf, toread);
			if (r > 0) {
				int wptr = 0;
				if (r != toread)
					printf("****** short read ? %d\n", (int)r);
				if (buf[0] != 0x47)
					printf("copy: buffer not aligned at %" PRId64 "\n", offset);
				if (need_gop) {
					int gop = find_gop(buf, r);
					if (gop >= 0) {
						printf("cut: GOP found at %" PRId64 " offset %d\n", (off64_t)(offset+gop), gop);
						newsize -= gop;
						wptr = gop;
					} else
						printf("cut: GOP needed, but not found\n");
					need_gop = 0;
				}
				offset += r;
				spos += r - wptr;
				btotal += r;
				percent = (int) ((float)(btotal)/(float)(newsize)*100.);
				paintProgress(msg != 0);

				size_t wr = write(dstfd, &buf[wptr], r-wptr);
				if (wr < (r-wptr)) {
					printf("write to %s failed\n", dpart);
					unlink(dpart);
					goto ret_err;
				}
			} else if (offset < s.st_size) {
				/* read error ? */
				perror(minfo->file.Name.c_str());
				break;
			}
		} /* while(offset < until) */

		if (!onefile) {
			close(dstfd);
			dstfd = -1;
			save_info(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) {
		save_info(minfo, dpart, spos, secsize);
		time_t tt1 = time(0);
		printf("copy: ********* %s: total written %" PRId64 " took %ld secs\n", dpart, spos, tt1-tt);
	}
	retval = true;
ret_err:
	if (srcfd >= 0)
		close(srcfd);
	if (dstfd >= 0)
		close(dstfd);
	delete [] buf;
	if (was_cancel)
		g_RCInput->postMsg(CRCInput::RC_home, 0);
	frameBuffer->paintBoxRel(x + 40, y+12, 200, 15, COL_INFOBAR_PLUS_0);//TODO: remove unneeded box paints
	return retval;
}
コード例 #3
0
bool CMovieCut::cutMovie(MI_MOVIE_INFO * minfo)
{
	struct mybook books[MI_MOVIE_BOOK_USER_MAX+2];
	unsigned char psi[PSI_SIZE];
	char dpart[255];
	int bcount = 0;
	int dstfd = -1, srcfd = -1;
	struct stat64 s;
	off64_t spos = 0;
	bool need_gop = 0;
	int was_cancel = 0;
	bool retval = false;
	time_t tt = time(0);
	time_t tt1;

	off64_t size = minfo->file.Size;
	off64_t secsize = getSecondSize(minfo);
	off64_t 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("CMovieCut::%s: start bookmark %d at %" PRId64 " len %" PRId64 "\n", __func__, 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("CMovieCut::%s: jump bookmark %d at %" PRId64 " len %" PRId64 " -> skip to %" PRId64 "\n", __func__, 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;
		books[bcount].ok = 1;
		printf("CMovieCut::%s: end bookmark %d at %" PRId64 "\n", __func__, bcount, books[bcount].pos);
		bcount++;
	}

	if (!bcount)
		return false;

	unsigned char * buf = new unsigned char[BUF_SIZE];
	if (buf == 0) {
		perror("new");
		return false;
	}

	paintProgress(true);

	qsort(books, bcount, sizeof(struct mybook), compare_book);
	for (int 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;
			/* check for overlapping bookmarks */
			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("CMovieCut::%s: bad bookmark %d, position %" PRId64 " len %" PRId64 ", adjusting..\n", __func__, j, books[j].pos, books[j].len);
						books[j].pos = curend;
						books[j].len = newend - curend;
					} else {
						printf("CMovieCut::%s: bad bookmark %d, position %" PRId64 " len %" PRId64 ", skipping..\n", __func__, j, books[j].pos, books[j].len);
						books[j].ok = 0;
					}
				}
			}
		}
	}
	findNewName(minfo->file.Name.c_str(), dpart, sizeof(dpart));

	int bindex = 0;
	off64_t bpos = books[bindex].pos;
	off64_t bskip = books[bindex].len;
	off64_t offset = 0;

	printf("CMovieCut::%s: new file %s, expected size %" PRId64 ", start time %s", __func__, dpart, newsize, ctime(&tt));
	dstfd = open(dpart, O_CREAT|O_WRONLY|O_TRUNC| O_LARGEFILE, 0644);
	if (dstfd < 0) {
		perror(dpart);
		goto ret_err;
	}
	if (read_psi(minfo->file.Name.c_str(), &psi[0])) {
		perror(minfo->file.Name.c_str());
		goto ret_err;
	}
	write(dstfd, psi, PSI_SIZE);

	stat64(minfo->file.Name.c_str(), &s);

	srcfd = open(minfo->file.Name.c_str(), O_RDONLY | O_LARGEFILE);
	if (srcfd < 0) {
		perror(minfo->file.Name.c_str());
		goto ret_err;
	}
	lseek64(srcfd, offset, SEEK_SET);

	/* process all bookmarks */
	while (true) {
		off64_t until = bpos;
		printf("CMovieCut::%s: bookmark #%d reading from %" PRId64 " to %" PRId64 " (%" PRId64 ") want gop %d\n", __func__, bindex, offset, until, until - offset, need_gop);
		/* read up to jump end */
		while (offset < until) {
			int msg = getInput();
			was_cancel = msg & 2;
			if (msg & 4) {
				unlink(dpart);
				retval = true;
				goto ret_err;
			}
			size_t toread = (until-offset) > BUF_SIZE ? BUF_SIZE : until - offset;
			size_t r = read(srcfd, buf, toread);
			if (r > 0) {
				int wptr = 0;
				if (r != toread) 
					printf("CMovieCut::%s: short read at %" PRId64 ": %d\n", __func__, offset, (int)r);
				if (buf[0] != 0x47)
					printf("CMovieCut::%s: buffer not aligned at %" PRId64 "\n", __func__, offset);
				if (need_gop) {
					int gop = find_gop(buf, r);
					if (gop >= 0) {
						printf("CMovieCut::%s: GOP found at %" PRId64 " offset %d\n", __func__, (off64_t)(offset+gop), gop);
						newsize -= gop;
						wptr = gop;
					} else
						printf("CMovieCut::%s: GOP not found\n", __func__);
					need_gop = 0;
				}
				offset += r;
				spos += r - wptr;
				percent = (int) ((float)(spos)/(float)(newsize)*100.);
				paintProgress(msg != 0);
				size_t wr = write(dstfd, &buf[wptr], r-wptr);
				if (wr < (r-wptr)) {
					perror(dpart);
					goto ret_err;
				}
			} else if (offset < s.st_size) {
				/* read error ? */
				perror(minfo->file.Name.c_str());
				goto ret_err;
			}
		}
		printf("CMovieCut::%s: current file pos %" PRId64 " write pos %" PRId64 " book pos %" PRId64 " next offset %" PRId64 "\n", __func__, offset, spos, bpos, bpos + bskip);
		need_gop = 1;
		offset = bpos + bskip;

		bindex++;
		while(bindex < bcount) {
			if(books[bindex].ok)
				break;
			else
				bindex++;
		}
		if(bindex < bcount) {
			bpos = books[bindex].pos;
			bskip = books[bindex].len;
		} else
			bpos = size;

		if (offset >= s.st_size) {
			printf("CMovieCut::%s: offset behind EOF: %" PRId64 " from %" PRId64 "\n", __func__, offset, s.st_size);
			break;
		}
		lseek64(srcfd, offset, SEEK_SET);
	}
	tt1 = time(0);
	printf("CMovieCut::%s: total written %" PRId64 " tooks %ld secs end time %s", __func__, spos, tt1-tt, ctime(&tt1));

	save_info(minfo, dpart, spos, secsize);
	retval = true;
ret_err:
	if (srcfd >= 0)
		close(srcfd);
	if (dstfd >= 0)
		close(dstfd);

	delete [] buf;
	if (was_cancel)
		g_RCInput->postMsg(CRCInput::RC_home, 0);

	frameBuffer->paintBoxRel(x + 40, y+12, 200, 15, COL_INFOBAR_PLUS_0);//TODO: remove unneeded box paints
	return retval;
}
コード例 #4
0
void InputMatrix::calculate(IrredundantMatrix &irredundantMatrix)
{
    Divide2Plan planBuilder(_r2Counts.data(), _r2Counts.size());
    std::vector<std::thread> threads(planBuilder.getMaxThreadsCount());

    std::mutex sync;
    std::condition_variable mcv;
    std::condition_variable wcv;
    int unblockedStep = -1;
    int waited = planBuilder.getMaxThreadsCount();

    for(auto threadId = 0; threadId < planBuilder.getMaxThreadsCount(); ++threadId) {
        START_COLLECT_TIME(threading, Counters::Threading);
        threads[threadId] = std::thread([this, threadId, &irredundantMatrix, &planBuilder,
                                         &sync, &mcv, &wcv, &unblockedStep, &waited]()
        {
            TimeCollector::ThreadInitialize();

            for(auto step = 0; step < planBuilder.getStepsCount(); ++step) {
                DEBUG_INFO("Worker " << threadId << ", step: " << step << ", waiting");

                {
                    std::unique_lock<std::mutex> locker(sync);
                    wcv.wait(locker, [step, &unblockedStep]{ return unblockedStep >= step; });
                }

                DEBUG_INFO("Worker " << threadId << ", step: " << step << ", started");

                if (threadId < planBuilder.getThreadsCountForStep(step))
                {
                    #ifdef DIFFERENT_MATRICES
                    IrredundantMatrix matrixForThread(_qColsCount);
                    auto currentMatrix = &matrixForThread;
                    #else
                    auto currentMatrix = &irredundantMatrix;
                    #endif

                    auto task = planBuilder.getTask(step, threadId);
                    if (!task->isEmpty())
                    {
                        DEBUG_INFO("Thread " << threadId << " is working on " <<
                                   task->getFirstSize() << ":" << task->getSecondSize());

                        for(auto i=0; i<task->getFirstSize(); ++i) {
                            for(auto j=0; j<task->getSecondSize(); ++j) {
                                processBlock(*currentMatrix,
                                             _r2Indexes[task->getFirst(i)], _r2Counts[task->getFirst(i)],
                                             _r2Indexes[task->getSecond(j)], _r2Counts[task->getSecond(j)]);
                            }
                        }

                        #ifdef DIFFERENT_MATRICES
                        irredundantMatrix.addMatrixConcurrent(std::move(matrixForThread));
                        #endif
                    }
                }

                {
                    std::unique_lock<std::mutex> locker(sync);
                    waited -= 1;
                    locker.unlock();
                    mcv.notify_one();
                }

                DEBUG_INFO("Worker " << threadId << ", step: " << step << ", finished");
            }

            DEBUG_INFO("Worker " << threadId << " finished");
            TimeCollector::ThreadFinalize();
        });
        STOP_COLLECT_TIME(threading);
    }

    for(auto step = 0; step < planBuilder.getStepsCount(); ++step) {
        DEBUG_INFO("Master, step: " << step << ", starting");
        {
            std::unique_lock<std::mutex> locker(sync);
            waited = planBuilder.getMaxThreadsCount();
            unblockedStep = step;
            sync.unlock();
            wcv.notify_all();
        }

        DEBUG_INFO("Master, step: " << step << ", started");
        
        {
            std::unique_lock<std::mutex> locker(sync);
            mcv.wait(locker, [&waited]{ return waited == 0; });
        }

        DEBUG_INFO("Master, step: " << step << ", finished");
    }
        
    for(auto threadId = 0; threadId < planBuilder.getMaxThreadsCount(); ++threadId) {
        threads[threadId].join();
    }
}