root/branches/perian-1.1/ff_dataref.c

Revision 745, 5.8 kB (checked in by astrange, 1 year ago)

Match the new lavf API.

Line 
1 /*****************************************************************************
2 *
3 *  Avi Import Component dataref interface for libavformat
4 *
5 *  Copyright(C) 2006 Christoph Naegeli <chn1@mac.com>
6 *
7 *  This library is free software; you can redistribute it and/or
8 *  modify it under the terms of the GNU Lesser General Public
9 *  License as published by the Free Software Foundation; either
10 *  version 2.1 of the License, or (at your option) any later version.
11
12 *  This library is distributed in the hope that it will be useful,
13 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
14 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15 *  Lesser General Public License for more details.
16
17 *  You should have received a copy of the GNU Lesser General Public
18 *  License along with this library; if not, write to the Free Software
19 *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
20 *
21 ****************************************************************************/
22
23 #include "avformat.h"
24
25 #include <QuickTime/QuickTime.h>
26
27 struct _dataref_private {
28         Handle dataRef;
29         OSType dataRefType;
30         DataHandler dh;
31         int64_t pos;
32         int64_t size;
33         unsigned char supportsWideOffsets;
34 };
35 typedef struct _dataref_private dataref_private;
36
37 /* DataRef Wrapper for QuickTime */
38
39 /* !!! THIS FUNCTION ASSUMES h->priv_data IS VALID in contrary to the other open functions
40 * found in ffmpeg */
41 static int dataref_open(URLContext *h, const char *filename, int flags)
42 {
43         ComponentResult result;
44         dataref_private *private;
45         wide fsize;
46         long access = 0;
47        
48         if(flags & URL_RDWR) {
49                 access = kDataHCanRead | kDataHCanWrite;
50         } else if(flags & URL_WRONLY) {
51                 access = kDataHCanWrite;
52         } else {
53                 access = kDataHCanRead;
54         }
55        
56         private = h->priv_data;
57         result = OpenAComponent(GetDataHandler(private->dataRef, private->dataRefType, access), &private->dh);
58         require_noerr(result,bail);
59        
60         result = DataHSetDataRef(private->dh, private->dataRef);
61         require_noerr(result,bail);
62        
63         if(access & kDataHCanRead) {
64                 result = DataHOpenForRead(private->dh);
65                 require_noerr(result,bail);
66         }
67         if(access & kDataHCanWrite) {
68                 result = DataHOpenForWrite(private->dh);
69                 require_noerr(result,bail);
70         }
71        
72         private->pos = 0ll;
73         private->size = 0ll;
74        
75         result = DataHGetFileSize64(private->dh, &fsize);
76         if(result == noErr) {
77                 private->size = (int64_t)fsize.lo;
78                 private->size += (int64_t)fsize.hi << 32;
79                 // Our data handler supports wide offsets. Remember for later use.
80                 private->supportsWideOffsets = 1;
81         } else {
82                 long size32;
83                 result = DataHGetFileSize(private->dh, &size32);
84                 require_noerr(result, bail);
85                 private->size = size32;
86         }
87        
88 bail:
89                 return result;
90 } /* dataref_open() */
91
92 static int dataref_read(URLContext *h, unsigned char *buf, int size)
93 {
94         int result;
95         int64_t read;
96
97         dataref_private *p = (dataref_private*)h->priv_data;
98        
99         read = p->size - p->pos;
100         read = (read < size) ? read : size;
101        
102         if(p->supportsWideOffsets) {
103                 wide offset;
104                 offset.hi = p->pos >> 32;
105                 offset.lo = (UInt32)p->pos;
106                
107                 result = DataHScheduleData64(p->dh, (Ptr)buf, &offset, (long)read, 0, NULL, NULL);
108                 if (result == badComponentSelector && offset.hi == 0) {
109                         result = DataHScheduleData(p->dh, (Ptr)buf, offset.lo, (long)read, 0, NULL, NULL);
110                 }
111         } else {
112                 result = DataHScheduleData(p->dh, (Ptr)buf, (long)p->pos, (long)read, 0, NULL, NULL);
113         }
114        
115         if(result != noErr) {
116                 read = -1;
117                 goto bail;
118         }
119        
120         p->pos += read;
121        
122 bail:
123                 return (int)read;
124 } /* dataref_read() */
125
126 static int dataref_write(URLContext *h, unsigned char *buf, int size)
127 {
128         int result;
129         int written = size;
130         dataref_private *p = (dataref_private*)h->priv_data;
131        
132         if(p->supportsWideOffsets) {
133                 wide offset;
134                 offset.hi = p->pos >> 32;
135                 offset.lo = (UInt32)p->pos;
136                
137                 result = DataHWrite64(p->dh, (Ptr)buf, &offset, size, NULL, 0);
138         } else {
139                 result = DataHWrite(p->dh, (Ptr)buf, (long)p->pos, size, NULL, 0);
140         }
141        
142         if(result != noErr) {
143                 written = -1;
144                 goto bail;
145         }
146        
147         p->pos += written;
148        
149 bail:
150                 return written;
151 } /* dataref_write() */
152
153 static offset_t dataref_seek(URLContext *h, offset_t pos, int whence)
154 {
155         dataref_private *p = (dataref_private*)h->priv_data;
156        
157         switch(whence) {
158                 case SEEK_SET:
159                         p->pos = pos;
160                         break;
161                 case SEEK_CUR:
162                         p->pos += pos;
163                         break;
164                 case SEEK_END:
165                         p->pos = p->size + pos;
166                         break;
167                 case AVSEEK_SIZE:
168                         return p->size;
169                 default:
170                         return -1;
171         }
172        
173         return p->pos;
174 } /* dataref_seek() */
175
176 static int dataref_close(URLContext *h)
177 {
178         dataref_private *p = (dataref_private*)h->priv_data;
179        
180         CloseComponent(p->dh);
181         p->dh = 0;
182         p->pos = 0;
183         p->size = 0;
184        
185         av_free(p);
186         h->priv_data = NULL;
187        
188         return 0;
189 } /* dataref_close() */
190
191 URLProtocol dataref_protocol = {
192     "Data Ref",
193     dataref_open,
194     dataref_read,
195     dataref_write,
196     dataref_seek,
197     dataref_close,
198 };
199
200 /* This is the public function to open bytecontext withs datarefs */
201 OSStatus url_open_dataref(ByteIOContext **pb, Handle dataRef, OSType dataRefType, DataHandler *dataHandler, Boolean *wideSupport, int64_t *dataSize)
202 {
203         URLContext *uc;
204         URLProtocol *up;
205         OSStatus err;
206         dataref_private *private;
207        
208         private = av_mallocz(sizeof(dataref_private));
209         private->dataRef = dataRef;
210         private->dataRefType = dataRefType;
211        
212         up = &dataref_protocol;
213        
214         uc = av_mallocz(sizeof(URLContext));
215         if(!uc) {
216                 err = -ENOMEM;
217                 return err;
218         }
219         uc->filename = NULL;
220         uc->prot = up;
221         uc->flags = URL_RDONLY; // we're just using the read access...
222         uc->is_streamed = 0; // not streamed...
223         uc->max_packet_size = 0; // stream file
224         uc->priv_data = private;
225        
226         err = up->url_open(uc, uc->filename, URL_RDONLY);
227                
228         if(err < 0) {
229                 av_free(uc);
230                 return err;
231         }
232         err = url_fdopen(pb, uc);
233         if(err < 0) {
234                 url_close(uc);
235                 return err;
236         }
237        
238         if(dataHandler)
239                 *dataHandler = private->dh;
240        
241         if(wideSupport)
242                 *wideSupport = private->supportsWideOffsets;
243        
244         if(dataSize)
245                 *dataSize = private->size;     
246        
247         return noErr;
248 } /* url_open_dataref() */
Note: See TracBrowser for help on using the browser.