Ticket #3696: mtd.patch
File mtd.patch, 12.6 KB (added by , 17 years ago) |
---|
-
jobthread.cpp
331 331 // Can't do much until I have a 332 332 // lock on the device 333 333 // 334 dvdnav_t *dvdnav; 335 int finished, len, event; 336 uint8_t packetBuf[DVD_VIDEO_LB_LEN]; 337 uint8_t *blockBuf; 334 338 339 dvdnav_status_t dvdRet; 340 341 int32_t titleParts = 0; 342 int32_t curTitle = 0; 343 int32_t curTitlePart = 0; 344 int32_t prevTitle = 0; 345 int32_t prevTitlePart = 0; 346 335 347 bool loop = true; 336 348 337 349 setSubName(QObject::tr("Waiting For Access to DVD"), 1); 338 350 339 351 while(loop) … … 354 366 return false; 355 367 } 356 368 } 357 } 369 } 358 370 359 371 MutexUnlocker qmul(dvd_device_access); 360 372 … … 366 378 367 379 sendLoggingEvent("job thread beginning to rip dvd title"); 368 380 369 381 370 382 // 371 // OK, we got the device. 383 // OK, we got the device. 372 384 // Lets open our destination file 373 385 // 374 386 375 387 RipFile ripfile(to_location, extension, true); 376 388 if(!ripfile.open(IO_WriteOnly | IO_Raw | IO_Truncate, multiple_files)) 377 389 { … … 380 392 return false; 381 393 } 382 394 395 QTime job_time; 396 job_time.start(); 397 383 398 // 384 // Time to open up access with all 399 // Time to open up access with all 385 400 // the funky structs from libdvdnav 386 401 // 387 388 int angle = 0; // Change that at some point 402 dvdRet = dvdnav_open(&dvdnav, dvd_device_location); 389 403 390 SmartHandle<dvd_reader_t *> the_dvd(DVDOpen(dvd_device_location), 391 DVDClose); 392 if(!the_dvd.get()) 404 if (dvdRet == DVDNAV_STATUS_ERR) 393 405 { 394 problem(QString("DVDPerfectThread could not access this dvd device: %1").arg(dvd_device_location)); 406 problem(QString("Failed to open DVD devise: %1 (%2)\n").arg(dvd_device_location).arg(dvdnav_err_to_string(dvdnav))); 407 dvdnav_close(dvdnav); 395 408 return false; 396 409 } 410 dvdnav_set_readahead_flag(dvdnav, 1); 411 dvdnav_set_PGC_positioning_flag(dvdnav, 1); 397 412 398 399 SmartHandle<ifo_handle_t *> vmg_file(ifoOpen(the_dvd.get(), 0), ifoClose);400 if (!vmg_file.get())413 dvdnav_title_play(dvdnav, 0); 414 dvdRet = dvdnav_get_next_cache_block(dvdnav, &blockBuf, &event, &len); 415 if (dvdRet == DVDNAV_STATUS_ERR) 401 416 { 402 problem("DVDPerfectThread could not open VMG info."); 417 problem(QString("Error Getting Next Block (%1)\n").arg(dvdnav_err_to_string(dvdnav))); 418 dvdnav_free_cache_block(dvdnav, blockBuf); 419 dvdnav_close(dvdnav); 403 420 return false; 404 421 } 405 tt_srpt_t *tt_srpt = vmg_file->tt_srpt;422 dvdnav_free_cache_block(dvdnav, blockBuf); 406 423 407 // 408 // Check title # is valid 409 // 410 411 if(title_number < 0 || title_number > tt_srpt->nr_of_srpts ) 424 dvdnav_title_play(dvdnav, title_number + 1); 425 dvdRet = dvdnav_get_number_of_parts(dvdnav, title_number + 1, &titleParts); 426 sendLoggingEvent(QString("Title %1 has %2 Parts\n").arg(title_number + 1).arg(titleParts)); 427 if (dvdRet == DVDNAV_STATUS_ERR) 412 428 { 413 problem(QString("DVDPerfectThread could not open title number %1").arg(title_number + 1)); 429 problem(QString("Failed to get number of parts: %1\n").arg(dvdnav_err_to_string(dvdnav))); 430 dvdnav_free_cache_block(dvdnav, blockBuf); 431 dvdnav_close(dvdnav); 414 432 return false; 415 433 } 416 434 417 SmartHandle<ifo_handle_t *> vts_file( 418 ifoOpen(the_dvd.get(), tt_srpt->title[title_number].title_set_nr), 419 ifoClose); 420 if(!vts_file.get()) 421 { 422 problem("DVDPerfectThread could not open the title's info file"); 423 return false; 424 } 435 dvdRet = dvdnav_current_title_info(dvdnav, &curTitle, &curTitlePart); 436 sendLoggingEvent(QString("Now playing Title %1 - Part %2\n").arg(curTitle).arg(curTitlePart)); 425 437 426 // 427 // Determine the program chain (?) 428 // 429 int ttn = tt_srpt->title[title_number].vts_ttn; 430 vts_ptt_srpt_t *vts_ptt_srpt = vts_file->vts_ptt_srpt; 431 int pgc_id = vts_ptt_srpt->title[ ttn - 1 ].ptt[ 0 ].pgcn; 432 int pgn = vts_ptt_srpt->title[ ttn - 1 ].ptt[ 0 ].pgn; 433 pgc_t *cur_pgc = vts_file->vts_pgcit->pgci_srp[ pgc_id - 1 ].pgc; 434 int start_cell = cur_pgc->program_map[ pgn - 1 ] - 1; 438 finished = 0; 435 439 436 437 // 438 // Hmmmm ... need some sort of total to calculate 439 // progress display against .... I guess disc 440 // sectors will have to do .... 441 // 442 443 int total_sectors = 0; 444 445 for(int i = start_cell; i < cur_pgc->nr_of_cells; i++) 440 while (!finished) 446 441 { 447 total_sectors += cur_pgc->cell_playback[i].last_sector - 448 cur_pgc->cell_playback[i].first_sector; 449 } 442 blockBuf = packetBuf; 443 dvdRet = dvdnav_get_next_cache_block(dvdnav, &blockBuf, &event, &len); 444 if (dvdRet == DVDNAV_STATUS_ERR) 445 { 446 problem(QString("Error Getting Next Block (%1)\n").arg(dvdnav_err_to_string(dvdnav))); 447 dvdnav_free_cache_block(dvdnav, blockBuf); 448 dvdnav_close(dvdnav); 449 return false; 450 } 450 451 451 // 452 // OK ... now actually open 453 // 454 455 SmartHandle<dvd_file_t *> title( 456 DVDOpenFile(the_dvd.get(), 457 tt_srpt->title[title_number].title_set_nr, 458 DVD_READ_TITLE_VOBS), 459 DVDCloseFile); 460 if(!title.get()) 461 { 462 problem("DVDPerfectThread could not open the title's actual VOB(s)"); 463 return false; 464 } 465 466 int sector_counter = 0; 467 468 QTime job_time; 469 job_time.start(); 470 471 std::vector<unsigned char> video_data(1024 * DVD_VIDEO_LB_LEN); 472 473 int next_cell = start_cell; 474 for(int cur_cell = start_cell; next_cell < cur_pgc->nr_of_cells; ) 475 { 476 cur_cell = next_cell; 477 if(cur_pgc->cell_playback[ cur_cell ].block_type == BLOCK_TYPE_ANGLE_BLOCK) 452 switch(event) 478 453 { 479 480 cur_cell += angle; 481 for(int i=0;; ++i) 454 case DVDNAV_BLOCK_OK: 482 455 { 483 if(cur_pgc->cell_playback[ cur_cell + i ].block_mode == BLOCK_MODE_LAST_CELL) 456 updateSubjobString(job_time.elapsed() / 1000, 457 QObject::tr("Ripping to file ~")); 458 if(!ripfile.writeBlocks(blockBuf, 459 len)) 484 460 { 485 next_cell = cur_cell + i + 1; 486 break; 461 problem("Couldn't write blocks during a rip. Filesystem size exceeded? Disc full?"); 462 dvdnav_free_cache_block(dvdnav, blockBuf); 463 dvdnav_close(dvdnav); 464 return false; 487 465 } 488 } 489 } 490 else 491 { 492 next_cell = cur_cell + 1; 493 } 494 495 // 496 // Loop until we're out of this cell 497 // 498 499 for(uint cur_pack = cur_pgc->cell_playback[ cur_cell ].first_sector; 500 cur_pack < cur_pgc->cell_playback[ cur_cell ].last_sector; ) 501 { 502 dsi_t dsi_pack; 503 unsigned int next_vobu, next_ilvu_start, cur_output_size; 504 505 // 506 // Read the NAV packet. 507 // 508 509 int len = DVDReadBlocks(title.get(), (int) cur_pack, 1, 510 &video_data[0]); 511 if( len != 1) 466 break; 467 } 468 case DVDNAV_STILL_FRAME: 512 469 { 513 problem(QString("DVDPerfectThread read failed for block %1")514 .arg(cur_pack));515 return false;470 sendLoggingEvent("Skipping still frame\n"); 471 dvdnav_still_skip(dvdnav); 472 break; 516 473 } 517 518 // 519 // libdvdread example code has an assertion here 520 // 521 // assert( is_nav_pack( video_data ) ); 522 523 // 524 // Parse the contained dsi packet 525 // 526 527 navRead_DSI(&dsi_pack, &video_data[DSI_START_BYTE]); 528 // and another assertion here: assert( cur_pack == dsi_pack.dsi_gi.nv_pck_lbn ); 529 530 // 531 // Figure out where to go next 532 // 533 534 next_ilvu_start = cur_pack+ dsi_pack.sml_agli.data[ angle ].address; 535 cur_output_size = dsi_pack.dsi_gi.vobu_ea; 536 537 if(dsi_pack.vobu_sri.next_vobu != SRI_END_OF_CELL ) 474 case DVDNAV_STOP: 538 475 { 539 next_vobu = cur_pack + ( dsi_pack.vobu_sri.next_vobu & 0x7fffffff ); 476 finished = 1; 477 break; 540 478 } 541 else479 case DVDNAV_WAIT: 542 480 { 543 next_vobu = cur_pack + cur_output_size + 1; 544 } 545 546 // another assert: assert( cur_output_size < 1024 ); 547 cur_pack++; 548 sector_counter++; 481 dvdnav_wait_skip(dvdnav); 482 break; 483 } 484 case DVDNAV_CELL_CHANGE: 485 { 486 prevTitle = curTitle; 487 prevTitlePart = curTitlePart; 488 dvdRet = dvdnav_current_title_info(dvdnav, &curTitle, &curTitlePart); 549 489 550 // 551 // Read in and output cursize packs 552 // 553 554 len = DVDReadBlocks(title.get(), (int)cur_pack, cur_output_size, 555 &video_data[0]); 556 if( len != (int) cur_output_size ) 490 setSubProgress((double) (curTitlePart) / (double) (titleParts), 1); 491 overall_progress = subjob_progress * sub_to_overall_multiple; 492 sendLoggingEvent(QString("Percent Complete: %1 (%2/%3)").arg(subjob_progress).arg(curTitlePart).arg(titleParts)); 493 494 if (prevTitle != curTitle || prevTitlePart != curTitlePart) 495 sendLoggingEvent(QString("Now playing Title %1 - Part %2\n").arg(curTitle).arg(curTitlePart)); 496 break; 497 } 498 case DVDNAV_VTS_CHANGE: 557 499 { 558 problem(QString("DVDPerfectThread read failed for %1 blocks at %2") 559 .arg(cur_output_size) 560 .arg(cur_pack) 561 ); 562 return false; 500 prevTitle = curTitle; 501 prevTitlePart = curTitlePart; 502 dvdRet = dvdnav_current_title_info(dvdnav, &curTitle, &curTitlePart); 503 504 if (prevTitle != curTitle || prevTitlePart != curTitlePart) 505 sendLoggingEvent(QString("Now playing Title %1 - Part %2\n").arg(curTitle).arg(curTitlePart)); 506 if (curTitle == 0 || curTitlePart == 0) 507 finished = 1; 508 509 break; 563 510 } 564 565 setSubProgress((double) (sector_counter) / (double) (total_sectors), 1); 566 overall_progress = subjob_progress * sub_to_overall_multiple; 567 updateSubjobString(job_time.elapsed() / 1000, 568 QObject::tr("Ripping to file ~")); 569 if(!ripfile.writeBlocks(&video_data[0], 570 cur_output_size * DVD_VIDEO_LB_LEN)) 511 case DVDNAV_NOP: 571 512 { 572 problem("Couldn't write blocks during a rip. Filesystem size exceeded? Disc full?"); 573 return false; 513 break; 574 514 } 515 default: 516 { 517 // sendLoggingEvent(QString("Unhandled event (%i)\n").arg(event)); 518 break; 519 } 575 520 576 sector_counter += next_vobu - cur_pack;577 cur_pack = next_vobu;578 579 580 521 // 581 522 // Escape out and clean up if mtd main thread 582 523 // tells us to 583 524 // 584 525 585 526 if(!keepGoing()) 586 527 { 587 528 problem("abandoned job because master control said we need to shut down"); 529 dvdnav_free_cache_block(dvdnav, blockBuf); 530 dvdnav_close(dvdnav); 588 531 return false; 589 532 } 590 533 } 591 534 } 535 dvdnav_free_cache_block(dvdnav, blockBuf); 536 dvdnav_close(dvdnav); 592 537 593 538 // 594 539 // Wow, we're done. -
dvdprobe.h
23 23 #include <mythtv/dvdnav/ifo_read.h> 24 24 #include <mythtv/dvdnav/dvd_reader.h> 25 25 #include <mythtv/dvdnav/nav_read.h> 26 #include <mythtv/dvdnav/dvdnav.h> 27 #include <mythtv/dvdnav/dvdnav_events.h> 26 28 27 29 #ifdef MAXDEFS 28 30 #undef UINT8_MAX