allow ffmpeg video to resample curr_pos, add bluray format
[goodguy/history.git] / cinelerra-5.0 / quicktime / qtcache.c
1 #include "funcprotos.h"
2 #include "qtprivate.h"
3 #include <string.h>
4
5
6 quicktime_cache_t* quicktime_new_cache()
7 {
8         quicktime_cache_t *result = calloc(1, sizeof(quicktime_cache_t));
9         return result;
10 }
11
12 void quicktime_delete_cache(quicktime_cache_t *ptr)
13 {
14         if(ptr->frames) 
15         {
16                 int i;
17 //printf("quicktime_delete_cache 1\n");
18                 for(i = 0; i < ptr->allocation; i++)
19                 {
20                         quicktime_cacheframe_t *frame = &ptr->frames[i];
21                         if(frame->y) free(frame->y);
22                         if(frame->u) free(frame->u);
23                         if(frame->v) free(frame->v);
24                 }
25                 free(ptr->frames);
26                 free(ptr);
27         }
28 }
29
30 void quicktime_reset_cache(quicktime_cache_t *ptr)
31 {
32         ptr->total = 0;
33 }
34
35 void quicktime_put_frame(quicktime_cache_t *ptr,
36         int64_t frame_number,
37         unsigned char *y,
38         unsigned char *u,
39         unsigned char *v,
40         int y_size,
41         int u_size,
42         int v_size)
43 {
44         quicktime_cacheframe_t *frame = 0;
45         int i;
46
47 //printf("quicktime_put_frame %d total=%d allocation=%d\n", __LINE__, ptr->total, ptr->allocation);
48 // Get existing frame
49         for(i = 0; i < ptr->total; i++)
50         {
51                 if(ptr->frames[i].frame_number == frame_number)
52                 {
53                         frame = &ptr->frames[i];
54                         break;
55                 }
56         }
57
58
59         if(!frame)
60         {
61                 if(ptr->total >= ptr->allocation)
62                 {
63                         int new_allocation = ptr->allocation * 2;
64
65 // printf("quicktime_put_frame %d ptr->allocation=%d new_allocation=%d\n", 
66 // __LINE__, 
67 // ptr->allocation, 
68 // new_allocation);
69
70                         if(!new_allocation) new_allocation = 32;
71                         ptr->frames = realloc(ptr->frames, 
72                                 sizeof(quicktime_cacheframe_t) * new_allocation);
73                         bzero(ptr->frames + ptr->total,
74                                 sizeof(quicktime_cacheframe_t) * (new_allocation - ptr->allocation));
75                         ptr->allocation = new_allocation;
76                 }
77
78                 frame = &ptr->frames[ptr->total];
79 //printf("quicktime_put_frame 30 %d %p %p %p\n", ptr->total, frame->y, frame->u, frame->v);
80                 ptr->total++;
81
82 // Memcpy is a lot slower than just dropping the seeking frames.
83                 if(y) 
84                 {
85                         frame->y = realloc(frame->y, y_size);
86                         frame->y_size = y_size;
87                         memcpy(frame->y, y, y_size);
88                 }
89
90                 if(u)
91                 {
92                         frame->u = realloc(frame->u, u_size);
93                         frame->u_size = u_size;
94                         memcpy(frame->u, u, u_size);
95                 }
96
97                 if(v)
98                 {
99                         frame->v = realloc(frame->v, v_size);
100                         frame->v_size = v_size;
101                         memcpy(frame->v, v, v_size);
102                 }
103                 frame->frame_number = frame_number;
104         }
105         
106
107 //printf("quicktime_put_frame %d total=%d allocation=%d\n", __LINE__, ptr->total, ptr->allocation);
108 // Delete oldest frames
109         if(ptr->max)
110         {
111                 while(quicktime_cache_usage(ptr) > ptr->max && ptr->total > 0)
112                 {
113                         quicktime_cacheframe_t *frame = &ptr->frames[0];
114
115                         if(frame->y) free(frame->y);
116                         if(frame->u) free(frame->u);
117                         if(frame->v) free(frame->v);
118
119                         for(i = 0; i < ptr->total - 1; i++)
120                         {
121                                 quicktime_cacheframe_t *frame1 = &ptr->frames[i];
122                                 quicktime_cacheframe_t *frame2 = &ptr->frames[i + 1];
123                                 *frame1 = *frame2;
124                         }
125
126
127                         frame = &ptr->frames[ptr->total - 1];
128                         frame->y = 0;
129                         frame->u = 0;
130                         frame->v = 0;
131                         ptr->total--;
132                         ptr->allocation--;
133                 }
134         }
135
136
137 // printf("quicktime_put_frame %d total=%d allocation=%d\n", __LINE__, ptr->total, ptr->allocation);
138 // printf("quicktime_put_frame %d max=0x%x current=0x%x\n", 
139 // __LINE__,
140 // ptr->max, 
141 // quicktime_cache_usage(ptr));
142
143 }
144
145 int quicktime_get_frame(quicktime_cache_t *ptr,
146         int64_t frame_number,
147         unsigned char **y,
148         unsigned char **u,
149         unsigned char **v)
150 {
151         int i;
152
153         for(i = 0; i < ptr->total; i++)
154         {
155                 quicktime_cacheframe_t *frame = &ptr->frames[i];
156                 if(frame->frame_number == frame_number)
157                 {
158                         
159                         *y = frame->y;
160                         *u = frame->u;
161                         *v = frame->v;
162                         return 1;
163                         break;
164                 }
165         }
166
167         return 0;
168 }
169
170 int quicktime_has_frame(quicktime_cache_t *ptr,
171         int64_t frame_number)
172 {
173         int i;
174
175         for(i = 0; i < ptr->total; i++)
176         {
177                 quicktime_cacheframe_t *frame = &ptr->frames[i];
178                 if(frame->frame_number == frame_number)
179                 {
180                         return 1;
181                         break;
182                 }
183         }
184
185         return 0;
186 }
187
188 int64_t quicktime_cache_usage(quicktime_cache_t *ptr)
189 {
190         int64_t result = 0;
191         int i;
192 //printf("quicktime_cache_usage %p %d %lld\n", ptr,  ptr->total, result);
193         for(i = 0; i < ptr->total; i++)
194         {
195                 quicktime_cacheframe_t *frame = &ptr->frames[i];
196                 result += frame->y_size + frame->u_size + frame->v_size;
197         }
198         return result;
199 }
200
201 void quicktime_cache_max(quicktime_cache_t *ptr, int bytes)
202 {
203         ptr->max = bytes;
204 }
205
206
207
208