summaryrefslogtreecommitdiffstats
path: root/core/DVDReader.cpp
blob: 27c20d08ab2358ccab0a1ebc7d6c542d60379b21 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
/* $Id: DVDReader.cpp,v 1.12 2003/10/03 16:49:19 titer Exp $

   This file is part of the HandBrake source code.
   Homepage: <http://beos.titer.org/handbrake/>.
   It may be used under the terms of the GNU General Public License. */

#include "DVDReader.h"
#include "Manager.h"
#include "Fifo.h"

#include <dvdread/ifo_types.h>
#include <dvdplay/dvdplay.h>
#include <dvdplay/info.h>
#include <dvdplay/state.h>
#include <dvdplay/nav.h>

HBDVDReader::HBDVDReader( HBManager * manager, HBTitle * title )
    : HBThread( "dvdreader" )
{
    fManager = manager;
    fTitle   = title;
}

void HBDVDReader::DoWork()
{
    /* Open the device */
    dvdplay_ptr vmg;
    vmg = dvdplay_open( fTitle->fDevice, NULL, NULL );
    if( !vmg )
    {
        Log( "HBDVDReader: dvdplay_open() failed" );
        fManager->Error();
        return;
    }

    bool die = false;
    for( int i = 0; i < ( fTitle->fTwoPass ? 2 : 1 ); i++ )
    {
        /* Open the title */
        dvdplay_start( vmg, fTitle->fIndex );

        /* Read */
        HBBuffer * dvdBuffer;
        int        beginPosition = dvdplay_position( vmg );
        int        endPosition   = dvdplay_title_end( vmg );

        while( dvdplay_position( vmg ) < endPosition )
        {
            while( fSuspend )
            {
                Snooze( 10000 );
            }

            dvdBuffer = new HBBuffer( DVD_VIDEO_LB_LEN );
            dvdBuffer->fPosition = (float) ( dvdplay_position( vmg )
                                             - beginPosition ) /
                                   (float) ( endPosition - beginPosition ) ;
            if( fTitle->fTwoPass )
            {
                dvdBuffer->fPosition /= 2;
                if( i == 1 )
                {
                    dvdBuffer->fPosition += 0.5;
                }
            }
            dvdBuffer->fPass = fTitle->fTwoPass ? ( i + 1 ) : 0;

            if( dvdplay_read( vmg, dvdBuffer->fData, 1 ) < 0 )
            {
                Log( "HBDVDReader: could not dvdplay_read()" );
                delete dvdBuffer;
                fManager->Error();
                break;
            }

            if( !Push( fTitle->fPSFifo, dvdBuffer ) )
            {
                die = true;
                break;
            }
        }

        if( die )
        {
            break;
        }
    }

    if( !die )
    {
        fManager->Done();
    }

    /* Clean up */
    dvdplay_close( vmg );
}