source: trunk/ff_dataref.c @ 221

Revision 221, 5.6 KB checked in by durin42, 8 years ago (diff)

As discussed and confirmed on the list, we are now switching completely to the
GNU Lesser General Public License. As such, changing the banner on the top
of all the files, and updating our license file. Removed all remaining
references to libpostproc, and everything still builds!

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
27struct _dataref_private {
28        Handle dataRef;
29        OSType dataRefType;
30        DataHandler dh;
31        int64_t pos;
32        int64_t size;
33        unsigned char supportsWideOffsets;
34};
35typedef 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 */
41static 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       
88bail:
89                return result;
90} /* dataref_open() */
91
92static 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        } else {
109                result = DataHScheduleData(p->dh, (Ptr)buf, (long)p->pos, (long)read, 0, NULL, NULL);
110        }
111       
112        if(result != noErr) {
113                read = -1;
114                goto bail;
115        }
116       
117        p->pos += read;
118       
119bail:
120                return (int)read;
121} /* dataref_read() */
122
123static int dataref_write(URLContext *h, unsigned char *buf, int size)
124{
125        int result;
126        int written = size;
127        dataref_private *p = (dataref_private*)h->priv_data;
128       
129        if(p->supportsWideOffsets) {
130                wide offset;
131                offset.hi = p->pos >> 32;
132                offset.lo = (UInt32)p->pos;
133               
134                result = DataHWrite64(p->dh, (Ptr)buf, &offset, size, NULL, 0);
135        } else {
136                result = DataHWrite(p->dh, (Ptr)buf, (long)p->pos, size, NULL, 0);
137        }
138       
139        if(result != noErr) {
140                written = -1;
141                goto bail;
142        }
143       
144        p->pos += written;
145       
146bail:
147                return written;
148} /* dataref_write() */
149
150static offset_t dataref_seek(URLContext *h, offset_t pos, int whence)
151{
152        dataref_private *p = (dataref_private*)h->priv_data;
153       
154        switch(whence) {
155                case SEEK_SET:
156                        p->pos = pos;
157                        break;
158                case SEEK_CUR:
159                        p->pos += pos;
160                        break;
161                case SEEK_END:
162                        p->pos = p->size + pos;
163                        break;
164                default:
165                        break;
166        }
167       
168        return p->pos;
169} /* dataref_seek() */
170
171static int dataref_close(URLContext *h)
172{
173        dataref_private *p = (dataref_private*)h->priv_data;
174       
175        CloseComponent(p->dh);
176        p->dh = 0;
177        p->pos = 0;
178        p->size = 0;
179       
180        av_free(p);
181        h->priv_data = NULL;
182       
183        return 0;
184} /* dataref_close() */
185
186URLProtocol dataref_protocol = {
187    "Data Ref",
188    dataref_open,
189    dataref_read,
190    dataref_write,
191    dataref_seek,
192    dataref_close,
193};
194
195/* This is the public function to open bytecontext withs datarefs */
196OSStatus url_open_dataref(ByteIOContext *pb, Handle dataRef, OSType dataRefType, DataHandler *dataHandler, Boolean *wideSupport, int64_t *dataSize)
197{
198        URLContext *uc;
199        URLProtocol *up;
200        OSStatus err;
201        dataref_private *private;
202       
203        private = av_mallocz(sizeof(dataref_private));
204        private->dataRef = dataRef;
205        private->dataRefType = dataRefType;
206       
207        up = &dataref_protocol;
208       
209        uc = av_mallocz(sizeof(URLContext));
210        if(!uc) {
211                err = -ENOMEM;
212                return err;
213        }
214        uc->filename[0] = '\0';
215        uc->prot = up;
216        uc->flags = URL_RDONLY; // we're just using the read access...
217        uc->is_streamed = 0; // not streamed...
218        uc->max_packet_size = 0; // stream file
219        uc->priv_data = private;
220       
221        err = up->url_open(uc, uc->filename, URL_RDONLY);
222               
223        if(err < 0) {
224                av_free(uc);
225                return err;
226        }
227        err = url_fdopen(pb, uc);
228        if(err < 0) {
229                url_close(uc);
230                return err;
231        }
232       
233        if(dataHandler)
234                *dataHandler = private->dh;
235       
236        if(wideSupport)
237                *wideSupport = private->supportsWideOffsets;
238       
239        if(dataSize)
240                *dataSize = private->size;     
241       
242        return noErr;
243} /* url_open_dataref() */
Note: See TracBrowser for help on using the repository browser.