MythTV  0.26-pre
frame.h
Go to the documentation of this file.
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 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends