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
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
|
/*
base class for converting raw data(stream) into some frametype.
Copyright (C) 2001 Martin Vogt
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU Library General Public License as published by
the Free Software Foundation.
For more information look at the file COPYRIGHT in this package
*/
#ifndef __FRAMER_H
#define __FRAMER_H
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <kdemacros.h>
#define FRAME_NEED 0
#define FRAME_WORK 1
#define FRAME_HAS 2
#include "rawDataBuffer.h"
/**
If we want to have a "push" interface, this means the decoder
does not read from an input interface, we must be sure
that we have a valid mpeg audio frame, before we feed
this whole frame to the decoder.
This class tells you how many bytes it can read and
gives you information wether we have a valid frame or not.
This class has three public states:
FRAME_NEED
/ \
/ \
/ \
FRAME_WORK <----------> FRAME_HAS
after the "FRAME_HAS" state we devliver _excatly_ one time
this state, and then automatically go to "FRAME_WORK" state.
You can reset() the class which empties the buffer and then
starts searching for a new sync code, or you can
do a next() which searches for the sync code, without
emptying the buffer (this is done automatically,
after the first call, when we was ins state "FRAME_HAS"
Note: i) You need a reset() if a "seek" occurs in your stream
ii) First call to the class must be "getState" which does the
Post-Constructor setup in derived classes!
The FRAME_NEED state is entered if the input buffer is empty
you then need to "push" data in this class.
The FRAME_NEED state is necessary to avoid an additonal memcpy
and a ringbuffer.(This safes "overhead"/"cpu cycles")
*/
class KDE_EXPORT Framer {
// this is our destination buffer for the output frame
// this buffer must be able to store the maximum size
// a frame of this type can have.
// Examples:
// avi-Chunk : 65KB
// mpeg audio: 4KB is always enough
// mpeg video: 224K (spec says this)
// this can be a remote buffer or a local one
unsigned char* buffer_data;
RawDataBuffer* buffer_info;
// state from FIND->READ->HAS
int process_state;
// state between NEED <-> PROCESS
int main_state;
RawDataBuffer* input_info;
int lAutoNext;
// stores if we have alloceated outdata or not
int lDeleteOutPtr;
// internal: unsync not done
int lConstruct;
public:
// allocate local output buffer
Framer(int outsize);
// outbuffer is remote.
Framer(int outsize,unsigned char* outptr);
virtual ~Framer();
//
// process states (transitions) [START]
//
// stores pointer to input and len
void store(unsigned char* start,int bytes);
int work();
void reset();
void next();
// returns pointer to outbuffer (frameheader+data)
unsigned char* outdata();
// returns pointer to inbuffer (raw data)
// Note: this ptr is not fixed! It may vary from time to time
// Cannot be stores in a variable!
unsigned char* indata();
//
// process states (transitions) [END]
//
//
// state helper functions [START]
//
int getState();
// returns number of bytes.
int canStore();
// returns length of frame == len(frameheader+data)
int len();
// returns number of bytes still in input(needed for a/v sync)
int restBytes();
//
// state helper functions [END]
//
// debugging
void printMainStates(const char* msg);
private:
void init(int outsize,unsigned char* outptr,int lDeleteOutptr);
void setState(int state);
//
// Overload functions for specialized framers [START]
//
// return true, if frame header found
virtual int find_frame(RawDataBuffer* input,RawDataBuffer* store);
// return true, if frame data read.
virtual int read_frame(RawDataBuffer* input,RawDataBuffer* store);
// makes buffer invalid, reset to begin of "find_frame"
virtual void unsync(RawDataBuffer* store,int lReset);
// debugging
virtual void printPrivateStates();
//
// Overload functions for specialized framers [END]
//
protected:
// this can be used, if the outptr come from a different framer
// (eg: OGG framer). You then need to call the construtor with
// some "dummy" size.
void setRemoteFrameBuffer(unsigned char* outptr,int size);
};
#endif
|