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