-
Notifications
You must be signed in to change notification settings - Fork 6
/
Copy pathbufman.cpp
119 lines (103 loc) · 3.18 KB
/
bufman.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
#include "stdafx.h"
#include "bufman.h"
#include <assert.h>
// the h264 decoder library seems running in single thread
// if so, we can avoid any multi-thread protection in this class.
// I did the checking outside before calling into the buffer_manager functions.
// because it looks weired if I do the checking in the buffer_manager class
// however, the release_out_buffer can be called freely by user
// that makes conflicts with h264 decoder library, and the no-locking benifit
// is decreased to only one place in output_binded_buffer
buffer_manager::buffer_manager(){
InitializeCriticalSection(&cse);
buffer_length = 0;
#ifdef _DEBUG
nr_alloc = 0;
#endif
}
buffer_manager::~buffer_manager(){
while(!free_list.empty()){
buffer_header* cur = free_list.front();
free_list.pop_front();
free(cur);
#ifdef _DEBUG
--nr_alloc;
#endif
}
#ifdef _DEBUG
assert(nr_alloc == 0);
cs << "x264 free" << endl;
#endif
DeleteCriticalSection(&cse);
}
void buffer_manager::new_buffer_length(unsigned int length){
if(buffer_length < length){
buffer_length = length;
}
}
char* buffer_manager::bind_frame(){
buffer_header* header = NULL;
EnterCriticalSection(&cse);
while(!free_list.empty()){
buffer_header* cur = free_list.front();
free_list.pop_front();
if(cur->length < buffer_length){
free(cur);
continue;
}
header = cur;
break;
}
LeaveCriticalSection(&cse);
if(header == NULL){
header = (buffer_header *) calloc(buffer_length + sizeof(buffer_header), 1);
if(header == NULL){
return NULL;
}
#ifdef _DEBUG
++nr_alloc;
#endif
header->flag = flag_free;
header->length = buffer_length;
header->buffer = (char *) (header + 1);
}
assert(header->flag == flag_free);
header->flag = flag_binded;
return header->buffer;
}
void buffer_manager::unbind_frame(char* buf){
assert(buf);
buffer_header* header = (buffer_header *) (buf - sizeof(buffer_header));
assert(header->flag & flag_binded);
EnterCriticalSection(&cse);
if(0 == (header->flag & flag_output)){
header->flag = flag_free;
free_list.push_back(header);
}
header->flag &= (~flag_binded);
LeaveCriticalSection(&cse);
}
void buffer_manager::output_binded_buffer(char* buf){
assert(buf);
buffer_header* header = (buffer_header *) (buf - sizeof(buffer_header));
assert(header->flag == flag_binded);
#ifdef exactly_neednot
header->flag |= flag_output;
#else
EnterCriticalSection(&cse);
header->flag |= flag_output;
LeaveCriticalSection(&cse);
#endif
}
void buffer_manager::release_out_buffer(char* buf){
assert(buf);
buffer_header* header = (buffer_header *) (buf - sizeof(buffer_header));
assert(header->flag & flag_output);
EnterCriticalSection(&cse);
if(0 == (header->flag & flag_binded)){
header->flag = flag_free;
free_list.push_back(header);
}
header->flag &= (~flag_output);
LeaveCriticalSection(&cse);
}