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"
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];
00047
00048 unsigned char *qscale_table;
00049 int qstride;
00050
00051 int interlaced_frame;
00052 int top_field_first;
00053 int repeat_pict;
00054 int forcekey;
00055 int dummy;
00056
00057 int pitches[3];
00058 int offsets[3];
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;
00242 uint bpb = 8 / 4;
00243
00244
00245
00246
00247 uint adj_w = (width + 15) & ~0xF;
00248 uint adj_h = (height + 15) & ~0xF;
00249 return (adj_w * adj_h * bpp + 4) / bpb;
00250 }
00251
00252 #endif
00253
00254 #endif
00255