|
MythTV
0.26-pre
|
00001 #ifndef _FRAME_H 00002 #define _FRAME_H 00003 00004 #include <string.h> 00005 #include <stdint.h> 00006 #include "fourcc.h" 00007 #include "mythtvexp.h" // for MUNUSED 00008 00009 #ifdef __cplusplus 00010 extern "C" { 00011 #endif 00012 00013 typedef enum FrameType_ 00014 { 00015 FMT_NONE = -1, 00016 FMT_RGB24 = 0, 00017 FMT_YV12, 00018 FMT_IA44, 00019 FMT_AI44, 00020 FMT_ARGB32, 00021 FMT_RGBA32, 00022 FMT_YUV422P, 00023 FMT_BGRA, 00024 FMT_VDPAU, 00025 FMT_VAAPI, 00026 FMT_YUY2, 00027 FMT_DXVA2, 00028 } VideoFrameType; 00029 00030 typedef struct VideoFrame_ 00031 { 00032 VideoFrameType codec; 00033 unsigned char *buf; 00034 00035 int width; 00036 int height; 00037 float aspect; 00038 double frame_rate; 00039 int bpp; 00040 int size; 00041 00042 long long frameNumber; 00043 long long timecode; 00044 int64_t disp_timecode; 00045 00046 unsigned char *priv[4]; // random empty storage 00047 00048 unsigned char *qscale_table; 00049 int qstride; 00050 00051 int interlaced_frame; // 1 if interlaced. 00052 int top_field_first; // 1 if top field is first. 00053 int repeat_pict; 00054 int forcekey; // hardware encoded .nuv 00055 int dummy; 00056 00057 int pitches[3]; // Y, U, & V pitches 00058 int offsets[3]; // Y, U, & V offsets 00059 00060 int pix_fmt; 00061 } VideoFrame; 00062 00063 #ifdef __cplusplus 00064 } 00065 #endif 00066 00067 #ifdef __cplusplus 00068 static inline void init(VideoFrame *vf, VideoFrameType _codec, 00069 unsigned char *_buf, int _width, int _height, int _size, 00070 const int *p = 0, 00071 const int *o = 0, 00072 float _aspect = -1.0f, double _rate = -1.0f) MUNUSED; 00073 static inline void clear(VideoFrame *vf); 00074 static inline bool compatible(const VideoFrame *a, 00075 const VideoFrame *b) MUNUSED; 00076 static inline int bitsperpixel(VideoFrameType type); 00077 00078 static inline void init(VideoFrame *vf, VideoFrameType _codec, 00079 unsigned char *_buf, int _width, int _height, 00080 int _size, const int *p, const int *o, 00081 float _aspect, double _rate) 00082 { 00083 vf->bpp = bitsperpixel(_codec); 00084 vf->codec = _codec; 00085 vf->buf = _buf; 00086 vf->width = _width; 00087 vf->height = _height; 00088 vf->aspect = _aspect; 00089 vf->frame_rate = _rate; 00090 00091 vf->size = _size; 00092 vf->frameNumber = 0; 00093 vf->timecode = 0; 00094 00095 vf->qscale_table = 0; 00096 vf->qstride = 0; 00097 00098 vf->interlaced_frame = 1; 00099 vf->top_field_first = 1; 00100 vf->repeat_pict = 0; 00101 vf->forcekey = 0; 00102 vf->dummy = 0; 00103 vf->pix_fmt = 0; 00104 00105 memset(vf->priv, 0, 4 * sizeof(unsigned char *)); 00106 00107 if (p) 00108 { 00109 memcpy(vf->pitches, p, 3 * sizeof(int)); 00110 } 00111 else 00112 { 00113 if (FMT_YV12 == _codec || FMT_YUV422P == _codec) 00114 { 00115 vf->pitches[0] = _width; 00116 vf->pitches[1] = vf->pitches[2] = _width >> 1; 00117 } 00118 else 00119 { 00120 vf->pitches[0] = (_width * vf->bpp) >> 3; 00121 vf->pitches[1] = vf->pitches[2] = 0; 00122 } 00123 } 00124 00125 if (o) 00126 { 00127 memcpy(vf->offsets, o, 3 * sizeof(int)); 00128 } 00129 else 00130 { 00131 if (FMT_YV12 == _codec) 00132 { 00133 vf->offsets[0] = 0; 00134 vf->offsets[1] = _width * _height; 00135 vf->offsets[2] = vf->offsets[1] + (vf->offsets[1] >> 2); 00136 } 00137 else if (FMT_YUV422P == _codec) 00138 { 00139 vf->offsets[0] = 0; 00140 vf->offsets[1] = _width * _height; 00141 vf->offsets[2] = vf->offsets[1] + (vf->offsets[1] >> 1); 00142 } 00143 else 00144 { 00145 vf->offsets[0] = vf->offsets[1] = vf->offsets[2] = 0; 00146 } 00147 } 00148 } 00149 00150 static inline void clear(VideoFrame *vf) 00151 { 00152 if (!vf) 00153 return; 00154 00155 if (FMT_YV12 == vf->codec) 00156 { 00157 int uv_height = vf->height >> 1; 00158 memset(vf->buf + vf->offsets[0], 0, vf->pitches[0] * vf->height); 00159 memset(vf->buf + vf->offsets[1], 127, vf->pitches[1] * uv_height); 00160 memset(vf->buf + vf->offsets[2], 127, vf->pitches[2] * uv_height); 00161 } 00162 } 00163 00164 static inline bool compatible(const VideoFrame *a, const VideoFrame *b) 00165 { 00166 return a && b && 00167 (a->codec == b->codec) && 00168 (a->width == b->width) && 00169 (a->height == b->height) && 00170 (a->size == b->size) && 00171 (a->offsets[0] == b->offsets[0]) && 00172 (a->offsets[1] == b->offsets[1]) && 00173 (a->offsets[2] == b->offsets[2]) && 00174 (a->pitches[0] == b->pitches[0]) && 00175 (a->pitches[1] == b->pitches[1]) && 00176 (a->pitches[2] == b->pitches[2]); 00177 } 00178 00179 static inline void copy(VideoFrame *dst, const VideoFrame *src) 00180 { 00181 VideoFrameType codec = dst->codec; 00182 if (dst->codec != src->codec) 00183 return; 00184 00185 dst->interlaced_frame = src->interlaced_frame; 00186 dst->repeat_pict = src->repeat_pict; 00187 dst->top_field_first = src->top_field_first; 00188 00189 if (FMT_YV12 == codec) 00190 { 00191 int height0 = (dst->height < src->height) ? dst->height : src->height; 00192 int height1 = height0 >> 1; 00193 int height2 = height0 >> 1; 00194 int pitch0 = ((dst->pitches[0] < src->pitches[0]) ? 00195 dst->pitches[0] : src->pitches[0]); 00196 int pitch1 = ((dst->pitches[1] < src->pitches[1]) ? 00197 dst->pitches[1] : src->pitches[1]); 00198 int pitch2 = ((dst->pitches[2] < src->pitches[2]) ? 00199 dst->pitches[2] : src->pitches[2]); 00200 00201 memcpy(dst->buf + dst->offsets[0], 00202 src->buf + src->offsets[0], pitch0 * height0); 00203 memcpy(dst->buf + dst->offsets[1], 00204 src->buf + src->offsets[1], pitch1 * height1); 00205 memcpy(dst->buf + dst->offsets[2], 00206 src->buf + src->offsets[2], pitch2 * height2); 00207 } 00208 } 00209 00210 static inline int bitsperpixel(VideoFrameType type) 00211 { 00212 int res = 8; 00213 switch (type) 00214 { 00215 case FMT_BGRA: 00216 case FMT_RGBA32: 00217 case FMT_ARGB32: 00218 res = 32; 00219 break; 00220 case FMT_RGB24: 00221 res = 24; 00222 break; 00223 case FMT_YUV422P: 00224 case FMT_YUY2: 00225 res = 16; 00226 break; 00227 case FMT_YV12: 00228 res = 12; 00229 break; 00230 case FMT_IA44: 00231 case FMT_AI44: 00232 default: 00233 res = 8; 00234 } 00235 return res; 00236 } 00237 00238 static inline uint buffersize(VideoFrameType type, int width, int height) 00239 { 00240 int type_bpp = bitsperpixel(type); 00241 uint bpp = type_bpp / 4; /* bits per pixel div common factor */ 00242 uint bpb = 8 / 4; /* bits per byte div common factor */ 00243 00244 // If the buffer sizes are not a multple of 16, adjust. 00245 // old versions of MythTV allowed people to set invalid 00246 // dimensions for MPEG-4 capture, no need to segfault.. 00247 uint adj_w = (width + 15) & ~0xF; 00248 uint adj_h = (height + 15) & ~0xF; 00249 return (adj_w * adj_h * bpp + 4/* to round up */) / bpb; 00250 } 00251 00252 #endif /* __cplusplus */ 00253 00254 #endif 00255
1.7.6.1