Ticket #3696: mtd.patch

File mtd.patch, 12.6 KB (added by Bradley Kite <bradley.kite@…>, 17 years ago)

Patch

  • jobthread.cpp

     
    331331    //  Can't do much until I have a
    332332    //  lock on the device
    333333    //
     334    dvdnav_t *dvdnav;
     335    int finished, len, event;
     336    uint8_t packetBuf[DVD_VIDEO_LB_LEN];
     337    uint8_t *blockBuf;
    334338
     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
    335347    bool loop = true;
    336    
     348
    337349    setSubName(QObject::tr("Waiting For Access to DVD"), 1);
    338350
    339351    while(loop)
     
    354366                return false;
    355367            }
    356368        }
    357     }   
     369    }
    358370
    359371    MutexUnlocker qmul(dvd_device_access);
    360372
     
    366378
    367379    sendLoggingEvent("job thread beginning to rip dvd title");
    368380
    369    
     381
    370382    //
    371     //  OK, we got the device. 
     383    //  OK, we got the device.
    372384    //  Lets open our destination file
    373385    //
    374    
     386
    375387    RipFile ripfile(to_location, extension, true);
    376388    if(!ripfile.open(IO_WriteOnly | IO_Raw | IO_Truncate, multiple_files))
    377389    {
     
    380392        return false;
    381393    }
    382394
     395    QTime job_time;
     396    job_time.start();
     397
    383398    //
    384     //  Time to open up access with all 
     399    //  Time to open up access with all
    385400    //  the funky structs from libdvdnav
    386401    //
    387    
    388     int angle = 0;  // Change that at some point
     402    dvdRet = dvdnav_open(&dvdnav, dvd_device_location);
    389403
    390     SmartHandle<dvd_reader_t *> the_dvd(DVDOpen(dvd_device_location),
    391             DVDClose);
    392     if(!the_dvd.get())
     404    if (dvdRet == DVDNAV_STATUS_ERR)
    393405    {
    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);
    395408        return false;
    396409    }
     410    dvdnav_set_readahead_flag(dvdnav, 1);
     411    dvdnav_set_PGC_positioning_flag(dvdnav, 1);
    397412
    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)
    401416    {
    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);
    403420        return false;
    404421    }
    405     tt_srpt_t *tt_srpt = vmg_file->tt_srpt;
     422    dvdnav_free_cache_block(dvdnav, blockBuf);
    406423
    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)
    412428    {
    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);
    414432        return false;
    415433    }
    416434
    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));
    425437
    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;
    435439
    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)
    446441    {
    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        }
    450451
    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)
    478453        {
    479            
    480             cur_cell += angle;
    481             for(int i=0;; ++i)
     454            case DVDNAV_BLOCK_OK:
    482455            {
    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))
    484460                {
    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;
    487465                }
    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:
    512469            {
    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;
    516473            }
    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:
    538475            {
    539                 next_vobu = cur_pack + ( dsi_pack.vobu_sri.next_vobu & 0x7fffffff );
     476                finished = 1;
     477                break;
    540478            }
    541             else
     479            case DVDNAV_WAIT:
    542480            {
    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);
    549489
    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:
    557499            {
    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;
    563510            }
    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:
    571512            {
    572                 problem("Couldn't write blocks during a rip. Filesystem size exceeded? Disc full?");
    573                 return false;
     513                break;
    574514            }
     515            default:
     516            {
     517                // sendLoggingEvent(QString("Unhandled event (%i)\n").arg(event));
     518                break;
     519            }
    575520
    576             sector_counter += next_vobu - cur_pack;
    577             cur_pack = next_vobu;
    578 
    579 
    580521            //
    581522            //  Escape out and clean up if mtd main thread
    582523            //  tells us to
    583524            //
    584            
     525
    585526            if(!keepGoing())
    586527            {
    587528                problem("abandoned job because master control said we need to shut down");
     529                dvdnav_free_cache_block(dvdnav, blockBuf);
     530                dvdnav_close(dvdnav);
    588531                return false;
    589532            }
    590533        }
    591534    }
     535    dvdnav_free_cache_block(dvdnav, blockBuf);
     536    dvdnav_close(dvdnav);
    592537
    593538    //
    594539    //  Wow, we're done.
  • dvdprobe.h

     
    2323#include <mythtv/dvdnav/ifo_read.h>
    2424#include <mythtv/dvdnav/dvd_reader.h>
    2525#include <mythtv/dvdnav/nav_read.h>
     26#include <mythtv/dvdnav/dvdnav.h>
     27#include <mythtv/dvdnav/dvdnav_events.h>
    2628
    2729#ifdef MAXDEFS
    2830#undef UINT8_MAX