MythTV  0.27pre
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Groups Pages
frame.h
Go to the documentation of this file.
1 #ifndef _FRAME_H
2 #define _FRAME_H
3 
4 #include <string.h>
5 #include <stdint.h>
6 #include "fourcc.h"
7 #include "mythtvexp.h" // for MUNUSED
8 
9 #ifdef __cplusplus
10 extern "C" {
11 #endif
12 
13 typedef enum FrameType_
14 {
15  FMT_NONE = -1,
16  FMT_RGB24 = 0,
29 
30 typedef struct VideoFrame_
31 {
33  unsigned char *buf;
34 
35  int width;
36  int height;
37  float aspect;
38  double frame_rate;
39  int bpp;
40  int size;
41 
42  long long frameNumber;
43  long long timecode;
44  int64_t disp_timecode;
45 
46  unsigned char *priv[4]; // random empty storage
47 
48  unsigned char *qscale_table;
49  int qstride;
50 
51  int interlaced_frame; // 1 if interlaced.
52  int top_field_first; // 1 if top field is first.
54  int forcekey; // hardware encoded .nuv
55  int dummy;
56 
57  int pitches[3]; // Y, U, & V pitches
58  int offsets[3]; // Y, U, & V offsets
59 
60  int pix_fmt;
61 } VideoFrame;
62 
63 #ifdef __cplusplus
64 }
65 #endif
66 
67 #ifdef __cplusplus
68 static inline void init(VideoFrame *vf, VideoFrameType _codec,
69  unsigned char *_buf, int _width, int _height, int _size,
70  const int *p = 0,
71  const int *o = 0,
72  float _aspect = -1.0f, double _rate = -1.0f) MUNUSED;
73 static inline void clear(VideoFrame *vf);
74 static inline bool compatible(const VideoFrame *a,
75  const VideoFrame *b) MUNUSED;
76 static inline int bitsperpixel(VideoFrameType type);
77 
78 static inline void init(VideoFrame *vf, VideoFrameType _codec,
79  unsigned char *_buf, int _width, int _height,
80  int _size, const int *p, const int *o,
81  float _aspect, double _rate)
82 {
83  vf->bpp = bitsperpixel(_codec);
84  vf->codec = _codec;
85  vf->buf = _buf;
86  vf->width = _width;
87  vf->height = _height;
88  vf->aspect = _aspect;
89  vf->frame_rate = _rate;
90 
91  vf->size = _size;
92  vf->frameNumber = 0;
93  vf->timecode = 0;
94 
95  vf->qscale_table = 0;
96  vf->qstride = 0;
97 
98  vf->interlaced_frame = 1;
99  vf->top_field_first = 1;
100  vf->repeat_pict = 0;
101  vf->forcekey = 0;
102  vf->dummy = 0;
103  vf->pix_fmt = 0;
104 
105  memset(vf->priv, 0, 4 * sizeof(unsigned char *));
106 
107  if (p)
108  {
109  memcpy(vf->pitches, p, 3 * sizeof(int));
110  }
111  else
112  {
113  if (FMT_YV12 == _codec || FMT_YUV422P == _codec)
114  {
115  vf->pitches[0] = _width;
116  vf->pitches[1] = vf->pitches[2] = _width >> 1;
117  }
118  else
119  {
120  vf->pitches[0] = (_width * vf->bpp) >> 3;
121  vf->pitches[1] = vf->pitches[2] = 0;
122  }
123  }
124 
125  if (o)
126  {
127  memcpy(vf->offsets, o, 3 * sizeof(int));
128  }
129  else
130  {
131  if (FMT_YV12 == _codec)
132  {
133  vf->offsets[0] = 0;
134  vf->offsets[1] = _width * _height;
135  vf->offsets[2] = vf->offsets[1] + (vf->offsets[1] >> 2);
136  }
137  else if (FMT_YUV422P == _codec)
138  {
139  vf->offsets[0] = 0;
140  vf->offsets[1] = _width * _height;
141  vf->offsets[2] = vf->offsets[1] + (vf->offsets[1] >> 1);
142  }
143  else
144  {
145  vf->offsets[0] = vf->offsets[1] = vf->offsets[2] = 0;
146  }
147  }
148 }
149 
150 static inline void clear(VideoFrame *vf)
151 {
152  if (!vf)
153  return;
154 
155  if (FMT_YV12 == vf->codec)
156  {
157  int uv_height = vf->height >> 1;
158  memset(vf->buf + vf->offsets[0], 0, vf->pitches[0] * vf->height);
159  memset(vf->buf + vf->offsets[1], 127, vf->pitches[1] * uv_height);
160  memset(vf->buf + vf->offsets[2], 127, vf->pitches[2] * uv_height);
161  }
162 }
163 
164 static inline bool compatible(const VideoFrame *a, const VideoFrame *b)
165 {
166  return a && b &&
167  (a->codec == b->codec) &&
168  (a->width == b->width) &&
169  (a->height == b->height) &&
170  (a->size == b->size) &&
171  (a->offsets[0] == b->offsets[0]) &&
172  (a->offsets[1] == b->offsets[1]) &&
173  (a->offsets[2] == b->offsets[2]) &&
174  (a->pitches[0] == b->pitches[0]) &&
175  (a->pitches[1] == b->pitches[1]) &&
176  (a->pitches[2] == b->pitches[2]);
177 }
178 
179 static inline void copy(VideoFrame *dst, const VideoFrame *src)
180 {
181  VideoFrameType codec = dst->codec;
182  if (dst->codec != src->codec)
183  return;
184 
186  dst->repeat_pict = src->repeat_pict;
187  dst->top_field_first = src->top_field_first;
188 
189  if (FMT_YV12 == codec)
190  {
191  int height0 = (dst->height < src->height) ? dst->height : src->height;
192  int height1 = height0 >> 1;
193  int height2 = height0 >> 1;
194  int pitch0 = ((dst->pitches[0] < src->pitches[0]) ?
195  dst->pitches[0] : src->pitches[0]);
196  int pitch1 = ((dst->pitches[1] < src->pitches[1]) ?
197  dst->pitches[1] : src->pitches[1]);
198  int pitch2 = ((dst->pitches[2] < src->pitches[2]) ?
199  dst->pitches[2] : src->pitches[2]);
200 
201  memcpy(dst->buf + dst->offsets[0],
202  src->buf + src->offsets[0], pitch0 * height0);
203  memcpy(dst->buf + dst->offsets[1],
204  src->buf + src->offsets[1], pitch1 * height1);
205  memcpy(dst->buf + dst->offsets[2],
206  src->buf + src->offsets[2], pitch2 * height2);
207  }
208 }
209 
210 static inline int bitsperpixel(VideoFrameType type)
211 {
212  int res = 8;
213  switch (type)
214  {
215  case FMT_BGRA:
216  case FMT_RGBA32:
217  case FMT_ARGB32:
218  res = 32;
219  break;
220  case FMT_RGB24:
221  res = 24;
222  break;
223  case FMT_YUV422P:
224  case FMT_YUY2:
225  res = 16;
226  break;
227  case FMT_YV12:
228  res = 12;
229  break;
230  case FMT_IA44:
231  case FMT_AI44:
232  default:
233  res = 8;
234  }
235  return res;
236 }
237 
238 static inline uint buffersize(VideoFrameType type, int width, int height)
239 {
240  int type_bpp = bitsperpixel(type);
241  uint bpp = type_bpp / 4; /* bits per pixel div common factor */
242  uint bpb = 8 / 4; /* bits per byte div common factor */
243 
244  // If the buffer sizes are not a multple of 16, adjust.
245  // old versions of MythTV allowed people to set invalid
246  // dimensions for MPEG-4 capture, no need to segfault..
247  uint adj_w = (width + 15) & ~0xF;
248  uint adj_h = (height + 15) & ~0xF;
249  return (adj_w * adj_h * bpp + 4/* to round up */) / bpb;
250 }
251 
252 #endif /* __cplusplus */
253 
254 #endif
255