1 /*
2 * frame_info.c
3 *
4 * Copyright (C) Thomas Oestreich - June 2001
5 *
6 * This file is part of transcode, a video stream processing tool
7 *
8 * transcode is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2, or (at your option)
11 * any later version.
12 *
13 * transcode is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with GNU Make; see the file COPYING. If not, write to
20 * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
21 *
22 */
23
24 #include "libtc/libtc.h"
25 #include "frame_info.h"
26
27 pthread_mutex_t frame_info_list_lock=PTHREAD_MUTEX_INITIALIZER;
28
29 frame_info_list_t *frame_info_list_head;
30 frame_info_list_t *frame_info_list_tail;
31
frame_info_register(int id)32 frame_info_list_t *frame_info_register(int id)
33
34 {
35
36 /* objectives:
37 ===========
38
39 register new frame
40
41 allocate space for frame buffer and establish backward reference
42
43 requirements:
44 =============
45
46 thread-safe
47
48 global mutex: frame_info_list_lock
49
50 */
51
52 frame_info_list_t *ptr;
53
54 pthread_mutex_lock(&frame_info_list_lock);
55
56 // retrive a valid pointer from the pool
57
58
59 if((ptr = tc_malloc(sizeof(frame_info_list_t))) == NULL) {
60 pthread_mutex_unlock(&frame_info_list_lock);
61 return(NULL);
62 }
63
64 ptr->status = FRAME_INFO_EMPTY;
65
66 ptr->next = NULL;
67 ptr->prev = NULL;
68
69 ptr->id = id;
70
71 if(frame_info_list_tail != NULL)
72 {
73 frame_info_list_tail->next = ptr;
74 ptr->prev = frame_info_list_tail;
75 }
76
77 frame_info_list_tail = ptr;
78
79 /* first frame registered must set frame_info_list_head */
80
81 if(frame_info_list_head == NULL) frame_info_list_head = ptr;
82
83 pthread_mutex_unlock(&frame_info_list_lock);
84
85 return(ptr);
86
87 }
88
89
90 /* ------------------------------------------------------------------ */
91
92
frame_info_remove(frame_info_list_t * ptr)93 void frame_info_remove(frame_info_list_t *ptr)
94
95 {
96
97 /* objectives:
98 ===========
99
100 remove frame from chained list
101
102 requirements:
103 =============
104
105 thread-safe
106
107 */
108
109
110 if(ptr == NULL) return; // do nothing if null pointer
111
112 pthread_mutex_lock(&frame_info_list_lock);
113
114 if(ptr->prev != NULL) (ptr->prev)->next = ptr->next;
115 if(ptr->next != NULL) (ptr->next)->prev = ptr->prev;
116
117 if(ptr == frame_info_list_tail) frame_info_list_tail = ptr->prev;
118 if(ptr == frame_info_list_head) frame_info_list_head = ptr->next;
119
120 // release valid pointer to pool
121 ptr->status = FRAME_INFO_EMPTY;
122
123 free(ptr->sync_info);
124
125 free(ptr);
126
127 pthread_mutex_unlock(&frame_info_list_lock);
128
129 }
130
131
132 /* ------------------------------------------------------------------ */
133
134
frame_info_retrieve()135 frame_info_list_t *frame_info_retrieve()
136
137 {
138
139 /* objectives:
140 ===========
141
142 get pointer to next frame for rendering
143
144 requirements:
145 =============
146
147 thread-safe
148
149 */
150
151 frame_info_list_t *ptr;
152
153 pthread_mutex_lock(&frame_info_list_lock);
154
155 ptr = frame_info_list_head;
156
157 /* move along the chain and check for status */
158
159 while(ptr != NULL)
160 {
161 if(ptr->status == FRAME_INFO_READY)
162 {
163 pthread_mutex_unlock(&frame_info_list_lock);
164 return(ptr);
165 }
166 ptr = ptr->next;
167 }
168
169 pthread_mutex_unlock(&frame_info_list_lock);
170
171 return(NULL);
172 }
173
174 /* ------------------------------------------------------------------ */
175
176
frame_info_retrieve_status(int old_status,int new_status)177 frame_info_list_t *frame_info_retrieve_status(int old_status, int new_status)
178
179 {
180
181 /* objectives:
182 ===========
183
184 get pointer to next frame for rendering
185
186 requirements:
187 =============
188
189 thread-safe
190
191 */
192
193 frame_info_list_t *ptr;
194
195 pthread_mutex_lock(&frame_info_list_lock);
196
197 ptr = frame_info_list_head;
198
199 /* move along the chain and check for status */
200
201 while(ptr != NULL)
202 {
203 if(ptr->status == old_status)
204 {
205
206 // found matching frame
207
208 ptr->status = new_status;
209
210 pthread_mutex_unlock(&frame_info_list_lock);
211
212 return(ptr);
213 }
214 ptr = ptr->next;
215 }
216
217 pthread_mutex_unlock(&frame_info_list_lock);
218
219 return(NULL);
220 }
221
222
223 /* ------------------------------------------------------------------ */
224
225
frame_info_set_status(frame_info_list_t * ptr,int status)226 void frame_info_set_status(frame_info_list_t *ptr, int status)
227
228 {
229
230 /* objectives:
231 ===========
232
233 get pointer to next frame for rendering
234
235 requirements:
236 =============
237
238 thread-safe
239
240 */
241
242 if(ptr == NULL) return;
243
244 pthread_mutex_lock(&frame_info_list_lock);
245
246 ptr->status = status;
247
248 pthread_mutex_unlock(&frame_info_list_lock);
249
250 return;
251 }
252
253