igor ru.po
[goodguy/history.git] / cinelerra-5.1 / libzmpeg3 / video / cache.C
1 #include "../libzmpeg3.h"
2
3 zcache_t::
4 ~cache_t()
5 {
6   clear();
7 }
8
9 void zcache_t::
10 clear()
11 {
12   if( frames ) {
13     for( int i=0; i<allocation; ++i ) {
14       cacheframe_t *frame = &frames[i];
15       if( frame->y ) delete [] frame->y;
16       if( frame->u ) delete [] frame->u;
17       if( frame->v ) delete [] frame->v;
18     }
19     delete [] frames;
20     total = 0;
21     allocation = 0;
22     frames = 0;
23     seq = 0;
24   }
25 }
26
27 int zcache_t::
28 extend_cache()
29 {
30   if( total >= MAX_CACHE_FRAMES ) {
31     int i = 0, n = 0;
32     uint32_t vtim = frames[0].age;
33     while( ++i < total ) {
34       if( frames[i].age < vtim ) {
35         n = i;  vtim = frames[i].age;
36       }
37     }
38     frames[n].age = seq++;
39     return n;
40   }
41   if( total >= allocation ) {
42     int new_allocation = ZMAX(allocation*2,8);
43     cacheframe_t *new_frames = new cacheframe_t[new_allocation];
44     for( int i=0; i<total; ++i )
45       new_frames[i] = frames[i];
46     delete [] frames;
47     frames = new_frames;
48     allocation = new_allocation;
49 //zmsgs("%d %d %d\n", new_allocation, allocation, total);
50   }
51   frames[total].age = seq++;
52   return total++;
53 }
54
55 void zcache_t::
56 put_frame(int64_t zframe_number,
57   uint8_t *zy, uint8_t *zu, uint8_t *zv,
58   int zy_size, int zu_size, int zv_size)
59 {
60   cacheframe_t *frame = 0;
61   int i;
62 //zmsgs("save %d\n",zframe_number);
63
64   for( i=0; i<total; ++i ) { /* Get existing frame */
65     if( frames[i].frame_number == zframe_number ) {
66       frame = &frames[i];
67       break;
68     }
69   }
70
71   if( !frame ) {
72     int i = extend_cache();
73     frame = &frames[i];
74 //zmsgs("30 %d %p %p %p\n", ptr->total, frame->y, frame->u, frame->v);
75     if( zy ) {
76       if( zy_size > frame->y_alloc ) {
77         delete [] frame->y;
78         frame->y = new uint8_t[frame->y_alloc=zy_size];
79       }
80       memcpy(frame->y, zy, frame->y_size=zy_size);
81     }
82     if( zu ) {
83       if( zu_size > frame->u_alloc ) {
84         delete [] frame->u;
85         frame->u = new uint8_t[frame->u_alloc=zu_size];
86       }
87       memcpy(frame->u, zu, frame->u_size=zu_size);
88     }
89     if( zv ) {
90       if( zv_size > frame->v_alloc ) {
91         delete [] frame->v;
92         frame->v = new uint8_t[frame->v_alloc=zv_size];
93       }
94       memcpy(frame->v, zv, frame->v_size=zv_size);
95     }
96     frame->frame_number = zframe_number;
97   }
98 }
99
100 int zcache_t::
101 get_frame(int64_t zframe_number,
102   uint8_t **zy, uint8_t **zu, uint8_t **zv)
103 {
104   for( int i=0; i<total; ++i ) {
105     cacheframe_t *frame = &frames[i];
106     if( frame->frame_number == zframe_number ) {
107       frame->age = seq++;
108       *zy = frame->y;
109       *zu = frame->u;
110       *zv = frame->v;
111 //zmsgs("hit %d\n",zframe_number);
112       return 1;
113     }
114   }
115   clear();
116 //zmsgs("missed %d\n",zframe_number);
117   return 0;
118 }
119
120 int zcache_t::
121 has_frame(int64_t zframe_number)
122 {
123   for( int i=0; i<total; ++i )
124     if( frames[i].frame_number == zframe_number ) return 1;
125
126   return 0;
127 }
128
129 int64_t zcache_t::
130 memory_usage()
131 {
132   int64_t result = 0;
133   for( int i=0; i<allocation; ++i ) {
134     cacheframe_t *frame = &frames[i];
135     result += frame->y_alloc + frame->u_alloc + frame->v_alloc;
136   }
137   return result;
138 }
139