/[tivodecode]/tivocom/trunk/CTivoFile.cpp
ViewVC logotype

Diff of /tivocom/trunk/CTivoFile.cpp

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 253 by jeremyd2019, Wed Aug 29 06:53:05 2007 UTC revision 254 by jeremyd2019, Sun Sep 9 23:26:20 2007 UTC
# Line 3  Line 3 
3  #include "stdafx.h"  #include "stdafx.h"
4  #include "CTivoFile.h"  #include "CTivoFile.h"
5  #include "CChunkCollection.h"  #include "CChunkCollection.h"
6    #include "FileStream.h"
7    #include "CTivoChunk.h"
8    
9    /* I want to use std::min */
10    #ifdef min
11    #undef min
12    #endif
13    
14  extern "C" {  extern "C" {
15  int o_verbose = 0;  int o_verbose = 0;
16  int fread_wrapper (void* mem, int size, void* fh)  int o_no_verify = 0;
17    
18    int stream_read_wrapper(void* mem, int size, void* fh)
19  {  {
20          return (int)fread(mem, 1, size, (FILE*)fh);          IStream* pStm = reinterpret_cast<IStream*>(fh);
21            ULONG retval = 0;
22            HRESULT hr = pStm->Read(mem, size, &retval);
23            return (int)retval;
24  }  }
25    
26    int stream_write_wrapper(void* mem, int size, void* fh)
27    {
28            IStream* pStm = reinterpret_cast<IStream*>(fh);
29            ULONG retval = 0;
30            HRESULT hr = pStm->Write(mem, size, &retval);
31            return (int)retval;
32  }  }
33    }
34    
35    
36  // CTivoFile  // CTivoFile
37    
38  STDMETHODIMP CTivoFile::Init(const std::string & mak, BSTR filename)  void CTivoFile::FinalRelease()
39  {  {
40            if (m_mpeg_turing_inited)
41                    destruct_turing (&m_mpeg_turing);
42    }
43    
44    
45    STDMETHODIMP CTivoFile::Init(BSTR mak, IStream* stream)
46    {
47          try          try
48          {          {
49                  USES_CONVERSION;                  USES_CONVERSION;
                 m_fname = OLE2CA(filename);  
                 m_mak = mak;  
                 _com_util::CheckError(AtlHresultFromWin32(fopen_s(&m_fh, m_fname.c_str(), "rb")));  
50    
51                  if (read_tivo_header(m_fh, &m_fileheader, &fread_wrapper) < 0)                  m_pStm = stream;
52                    m_mak = OLE2CA(mak);
53    
54                    if (read_tivo_header(m_pStm, &m_fileheader, &stream_read_wrapper) < 0)
55                          _com_raise_error(E_FAIL);                          _com_raise_error(E_FAIL);
56    
57                  m_endoffileheader = ftell(m_fh);                  m_endoffileheader.QuadPart = SIZEOF_STREAM_HEADER;
58    
59                    CComObject<CChunkCollection>* chunkColl = new CComObject<CChunkCollection> ();
60                    m_chunkcoll = chunkColl;
61                    _com_util::CheckError(chunkColl->Init(m_mak, m_fileheader.chunks, &m_endoffileheader, m_pStm));
62                    /* need to get to the start of the MPG stream, but cannot rely on Seek being
63                     * implemented (to support streaming)
64                     */
65                    ULONG bytesToMPEG = m_fileheader.mpeg_offset - m_endoffileheader.QuadPart;
66                    while(bytesToMPEG > 0)
67                    {
68                            BYTE tmp[1024];
69                            ULONG bytesRead;
70                            _com_util::CheckError(m_pStm->Read (tmp, std::min(bytesToMPEG, (ULONG)1024), &bytesRead));
71                            bytesToMPEG -= bytesRead;
72                    }
73    
74                    CComPtr<ITivoChunk> pChunk0;
75                    _com_util::CheckError(m_chunkcoll->get_Item(1, &pChunk0));
76                    CTivoChunk* pCChunk = dynamic_cast<CTivoChunk*>(pChunk0.p);
77                    setup_turing_key(&m_mpeg_turing, pCChunk->m_chunk, const_cast<char*>(m_mak.c_str()));
78                    m_mpeg_turing_inited = true;
79          }          }
80          catch (const _com_error & ex)          catch (const _com_error & ex)
81          {          {
# Line 40  STDMETHODIMP CTivoFile::Init(const std::string & mak, Line 88  STDMETHODIMP CTivoFile::Init(const std::string & mak,
88    
89  STDMETHODIMP CTivoFile::get_filename(BSTR* pVal)  STDMETHODIMP CTivoFile::get_filename(BSTR* pVal)
90  {  {
91          CComBSTR retval (m_fname.c_str());          return E_NOTIMPL;
         return retval.CopyTo(pVal);  
92  }  }
93    
94  STDMETHODIMP CTivoFile::get_filetype(BSTR* pVal)  STDMETHODIMP CTivoFile::get_filetype(BSTR* pVal)
# Line 104  STDMETHODIMP CTivoFile::get_chunks(IChunkCollection** Line 151  STDMETHODIMP CTivoFile::get_chunks(IChunkCollection**
151  {  {
152          try          try
153          {          {
154                  CComObject<CChunkCollection>* chunkColl = new CComObject<CChunkCollection> ();                  _com_util::CheckError(m_chunkcoll.CopyTo(pVal));
                 CComPtr<IChunkCollection> ref (chunkColl);  
                 _com_util::CheckError(chunkColl->Init(m_mak, m_fileheader.chunks, m_endoffileheader, this));  
                 _com_util::CheckError(ref.CopyTo(pVal));  
155          }          }
156          catch (const _com_error & ex)          catch (const _com_error & ex)
157          {          {
# Line 126  STDMETHODIMP CTivoFile::put_mak(BSTR newVal) Line 170  STDMETHODIMP CTivoFile::put_mak(BSTR newVal)
170  {  {
171          USES_CONVERSION;          USES_CONVERSION;
172          m_mak = OLE2CA(newVal);          m_mak = OLE2CA(newVal);
173    
174            return S_OK;
175    }
176    
177    STDMETHODIMP CTivoFile::DecryptMPEGToFile(BSTR bstrFileName)
178    {
179            try
180            {
181                    IStream * pFileStm;
182                    CComPtr<IStream> pStm;
183                    _com_util::CheckError(FileStream::OpenFile(OLE2CW(bstrFileName), &pFileStm, TRUE));
184                    pStm.Attach(pFileStm);
185                    _com_util::CheckError(this->DecryptMPEGToStream(pStm));
186            }
187            catch (const _com_error & ex)
188            {
189                    return ex.Error();
190            }
191    
192            return S_OK;
193    }
194    
195    STDMETHODIMP CTivoFile::DecryptMPEGToStream(IStream* pStm)
196    {
197            //ATLTRACENOTIMPL("DecryptMPEGToStream");
198            ULARGE_INTEGER filesize, filepos;
199            LARGE_INTEGER zero = {0};
200            bool percentage_determinable = false;
201    
202            try
203            {
204                    STATSTG stats;
205                    _com_util::CheckError(m_pStm->Stat(&stats, STATFLAG_NONAME));
206                    filesize = stats.cbSize;
207                    _com_util::CheckError(m_pStm->Seek(zero, STREAM_SEEK_CUR, &filepos));
208                    percentage_determinable = true;
209            }
210            catch (const _com_error & ex)
211            {
212                    /* non-determinable */
213                    UNREFERENCED_PARAMETER(ex);
214                    percentage_determinable = false;
215            }
216    
217            try
218            {
219                    ULONG t;
220                    UINT32 marker = 0xFFFFFFFF;
221                    DWORD dwFrames = 0, dwLastNotifiedFrames = 0;
222                    UINT8  byte;
223                    bool first=true, running=true;
224    
225                    while (running)
226                    {
227                            if ((marker & 0xFFFFFF00) == 0x100)
228                            {
229                                    int ret = process_frame(byte, &m_mpeg_turing, 0, m_pStm.p, &stream_read_wrapper, pStm, &stream_write_wrapper);
230                                    if (ret == 1)
231                                    {
232                                            marker = 0xFFFFFFFF;
233                                            if ((++dwFrames) >= (dwLastNotifiedFrames + 100))
234                                            {
235                                                    double percent = -1.0;
236                                                    if (percentage_determinable)
237                                                    {
238                                                            _com_util::CheckError(m_pStm->Seek(zero, STREAM_SEEK_CUR, &filepos));
239                                                            percent = (double)filepos.QuadPart / (double)filesize.QuadPart;
240                                                    }
241    
242                                                    if (Fire_OnProgressChange(dwFrames, percent) == S_FALSE)
243                                                    {
244                                                            return S_FALSE;
245                                                    }
246    
247                                                    dwLastNotifiedFrames = dwFrames;
248                                            }
249                                    }
250                                    else if (ret == 0)
251                                    {
252                                            _com_util::CheckError(pStm->Write(&byte, 1, &t));
253                                            ATLASSERT (t == 1);
254                                    }
255                                    else if (ret < 0)
256                                    {
257                                            ATLTRACE("Error processing frame!\n");
258                                            return Error(OLESTR("Error processing frame"), GUID_NULL, AtlHresultFromLastError());
259                                    }
260                            }
261                            else if (!first)
262                            {
263                                    _com_util::CheckError(pStm->Write(&byte, 1, &t));
264                                    ATLASSERT (t == 1);
265                            }
266                            marker <<= 8;
267                            _com_util::CheckError(m_pStm->Read(&byte, 1, &t));
268                            if (t == 0)
269                            {
270                                    running = false;
271                            }
272                            else
273                                    marker |= byte;
274                            first = false;
275                    }
276            }
277            catch (const _com_error & ex)
278            {
279                    ATLTRACE("Got error 0x%08x: %s\n", ex.Error(), ex.ErrorMessage());
280                    return ex.Error();
281            }
282    
283          return S_OK;          return S_OK;
284  }  }

Legend:
Removed from v.253  
changed lines
  Added in v.254

cvs@jdrake.com
ViewVC Help
Powered by ViewVC 1.1.13