root/tags/perian-0.5/ff_dataref.c

Revision 45, 4.8 kB (checked in by gbooker, 2 years ago)

Change spaces to tabs to make things pretty.

Line 
1 /*****************************************************************************
2 *
3 *  Avi Import Component dataref interface for libavformat
4 *
5 *  Copyright(C) 2006 Christoph Naegeli <chn1@mac.com>
6 *
7 *  This program is free software ; you can redistribute it and/or modify
8 *  it under the terms of the GNU General Public License as published by
9 *  the Free Software Foundation ; either version 2 of the License, or
10 *  (at your option) any later version.
11 *
12 *  This program 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
15 *  GNU General Public License for more details.
16 *
17 *  You should have received a copy of the GNU General Public License
18 *  along with this program ; if not, write to the Free Software
19 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 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 };
34 typedef struct _dataref_private dataref_private;
35
36 /* DataRef Wrapper for QuickTime */
37
38 /* !!! THIS FUNCTION ASSUMES h->priv_data IS VALID in contrary to the other open functions
39 * found in ffmpeg */
40 static int dataref_open(URLContext *h, const char *filename, int flags)
41 {
42         ComponentResult result;
43         dataref_private *private;
44         wide fsize;
45         long access = 0;
46        
47         if(flags & URL_RDWR) {
48                 access = kDataHCanRead | kDataHCanWrite;
49         } else if(flags & URL_WRONLY) {
50                 access = kDataHCanWrite;
51         } else {
52                 access = kDataHCanRead;
53         }
54        
55         private = h->priv_data;
56         result = OpenAComponent(GetDataHandler(private->dataRef, private->dataRefType, access), &private->dh);
57         require_noerr(result,bail);
58        
59         result = DataHSetDataRef(private->dh, private->dataRef);
60         require_noerr(result,bail);
61        
62         if(access & kDataHCanRead) {
63                 result = DataHOpenForRead(private->dh);
64                 require_noerr(result,bail);
65         }
66         if(access & kDataHCanWrite) {
67                 result = DataHOpenForWrite(private->dh);
68                 require_noerr(result,bail);
69         }
70        
71         private->pos = 0ll;
72         private->size = 0ll;
73        
74         DataHGetFileSize64(private->dh, &fsize);
75         private->size = (int64_t)fsize.lo;
76         private->size += (int64_t)fsize.hi << 32;
77        
78 bail:
79                 return result;
80 } /* dataref_open() */
81
82 static int dataref_read(URLContext *h, unsigned char *buf, int size)
83 {
84         int result;
85         int64_t read;
86         wide offset;
87         dataref_private *p = (dataref_private*)h->priv_data;
88        
89         read = p->size - p->pos;
90         read = (read < size) ? read : size;
91        
92         offset.hi = p->pos >> 32;
93         offset.lo = (UInt32)p->pos;
94        
95         result = DataHScheduleData64(p->dh, (Ptr)buf, &offset, (long)read, 0, NULL, NULL);
96         if(result != noErr) {
97                 read = -1;
98                 goto bail;
99         }
100        
101         p->pos += read;
102        
103 bail:
104                 return (int)read;
105 } /* dataref_read() */
106
107 static int dataref_write(URLContext *h, unsigned char *buf, int size)
108 {
109         int result;
110         int written = size;
111         wide offset;
112         dataref_private *p = (dataref_private*)h->priv_data;
113        
114         offset.hi = p->pos >> 32;
115         offset.lo = (UInt32)p->pos;
116        
117         result = DataHWrite64(p->dh, (Ptr)buf, &offset, size, NULL, 0);
118         if(result != noErr) {
119                 written = -1;
120                 goto bail;
121         }
122        
123         p->pos += written;
124        
125 bail:
126                 return written;
127 } /* dataref_write() */
128
129 static offset_t dataref_seek(URLContext *h, offset_t pos, int whence)
130 {
131         dataref_private *p = (dataref_private*)h->priv_data;
132        
133         switch(whence) {
134                 case SEEK_SET:
135                         p->pos = pos;
136                         break;
137                 case SEEK_CUR:
138                         p->pos += pos;
139                         break;
140                 case SEEK_END:
141                         p->pos = p->size + pos;
142                         break;
143                 default:
144                         break;
145         }
146        
147         return p->pos;
148 } /* dataref_seek() */
149
150 static int dataref_close(URLContext *h)
151 {
152         dataref_private *p = (dataref_private*)h->priv_data;
153        
154         CloseComponent(p->dh);
155         p->dh = 0;
156         p->pos = 0;
157         p->size = 0;
158        
159         av_free(p);
160         h->priv_data = NULL;
161        
162         return 0;
163 } /* dataref_close() */
164
165 URLProtocol dataref_protocol = {
166     "Data Ref",
167     dataref_open,
168     dataref_read,
169     dataref_write,
170     dataref_seek,
171     dataref_close,
172 };
173
174 /* This is the public function to open bytecontext withs datarefs */
175 OSStatus url_open_dataref(ByteIOContext *pb, Handle dataRef, OSType dataRefType)
176 {
177         URLContext *uc;
178         URLProtocol *up;
179         OSStatus err;
180         dataref_private *private;
181        
182         private = av_mallocz(sizeof(dataref_private));
183         private->dataRef = dataRef;
184         private->dataRefType = dataRefType;
185        
186         up = &dataref_protocol;
187        
188         uc = av_mallocz(sizeof(URLContext));
189         if(!uc) {
190                 err = -ENOMEM;
191                 return err;
192         }
193         uc->filename[0] = '\0';
194         uc->prot = up;
195         uc->flags = URL_RDONLY; // we're just using the read access...
196         uc->is_streamed = 0; // not streamed...
197         uc->max_packet_size = 0; // stream file
198         uc->priv_data = private;
199        
200         err = up->url_open(uc, uc->filename, URL_RDONLY);
201         if(err < 0) {
202                 av_free(uc);
203                 return err;
204         }
205         err = url_fdopen(pb, uc);
206         if(err < 0) {
207                 url_close(uc);
208                 return err;
209         }
210        
211         return noErr;
212 } /* url_open_dataref() */
Note: See TracBrowser for help on using the browser.