7 #include "vd_internal.h"
9 #define TEMP_BUF_SIZE (720*576)
11 static vd_info_t info
= {
12 "Hauppauge Macroblock/NV12/NV21 Decoder",
14 "Alex <d18c7db@hotmail.com>, A'rpi, Alex Beregszaszi",
15 "Alex <d18c7db@hotmail.com>",
21 static void de_macro_y(unsigned char* dst
,unsigned char* src
,int dstride
,int w
,int h
){
24 for (y
=0; y
<h
; y
+=16) {
26 for (x
=0; x
<w
; x
+=16) {
28 for (i
=0; i
<16; i
++) {
29 memcpy(dst
+ x
+ (y
+i
)*dstride
, src
, 16);
36 static void de_macro_uv(unsigned char* dstu
,unsigned char* dstv
,unsigned char* src
,int dstride
,int w
,int h
){
38 // descramble U/V plane
39 for (y
=0; y
<h
; y
+=16) {
41 for (x
=0; x
<w
; x
+=8) {
43 for (i
=0; i
<16; i
++) {
44 int idx
=x
+ (y
+i
)*dstride
;
45 dstu
[idx
+0]=src
[0]; dstv
[idx
+0]=src
[1];
46 dstu
[idx
+1]=src
[2]; dstv
[idx
+1]=src
[3];
47 dstu
[idx
+2]=src
[4]; dstv
[idx
+2]=src
[5];
48 dstu
[idx
+3]=src
[6]; dstv
[idx
+3]=src
[7];
49 dstu
[idx
+4]=src
[8]; dstv
[idx
+4]=src
[9];
50 dstu
[idx
+5]=src
[10]; dstv
[idx
+5]=src
[11];
51 dstu
[idx
+6]=src
[12]; dstv
[idx
+6]=src
[13];
52 dstu
[idx
+7]=src
[14]; dstv
[idx
+7]=src
[15];
59 /*************************************************************************
60 * convert a nv12 buffer to yv12
62 static int nv12_to_yv12(unsigned char *data
, int len
, mp_image_t
* mpi
, int swapped
) {
63 unsigned int Y_size
= mpi
->width
* mpi
->height
;
64 unsigned int UV_size
= mpi
->chroma_width
* mpi
->chroma_height
;
66 unsigned char *dst_Y
= mpi
->planes
[0];
67 unsigned char *dst_U
= mpi
->planes
[1];
68 unsigned char *dst_V
= mpi
->planes
[2];
69 unsigned char *src
= data
+ Y_size
;
71 // sanity check raw stream
72 if ( (len
!= (Y_size
+ (UV_size
<<1))) ) {
73 mp_msg(MSGT_DECVIDEO
, MSGL_ERR
,
74 "hmblck: Image size inconsistent with data size.\n");
77 if ( (mpi
->width
> 720) || (mpi
->height
> 576) ) {
78 mp_msg(MSGT_DECVIDEO
,MSGL_ERR
,
79 "hmblck: Image size is too big.\n");
82 if (mpi
->num_planes
!= 3) {
83 mp_msg(MSGT_DECVIDEO
,MSGL_ERR
,
84 "hmblck: Incorrect number of image planes.\n");
88 // luma data is easy, just copy it
89 memcpy(dst_Y
, data
, Y_size
);
91 // chroma data is interlaced UVUV... so deinterlace it
92 for(idx
=0; idx
<UV_size
; idx
++ ) {
93 *(dst_U
+ idx
) = *(src
+ (idx
<<1) + (swapped
? 1 : 0));
94 *(dst_V
+ idx
) = *(src
+ (idx
<<1) + (swapped
? 0 : 1));
99 /*************************************************************************
100 * set/get/query special features/parameters
102 static int control(sh_video_t
*sh
,int cmd
, void *arg
,...){
103 return CONTROL_UNKNOWN
;
105 /*************************************************************************
108 static int init(sh_video_t
*sh
){
109 return mpcodecs_config_vo(sh
,sh
->disp_w
,sh
->disp_h
,sh
->format
);
111 /*************************************************************************
114 static void uninit(sh_video_t
*sh
){
116 /*************************************************************************
119 static mp_image_t
* decode(sh_video_t
*sh
,void* data
,int len
,int flags
){
122 if(len
<=0) return NULL
; // skipped frame
124 mpi
=mpcodecs_get_image(sh
, MP_IMGTYPE_TEMP
, MP_IMGFLAG_ACCEPT_STRIDE
,
125 sh
->disp_w
, sh
->disp_h
);
126 if(!mpi
) return NULL
;
128 if(sh
->format
== IMGFMT_HM12
) {
129 //if(!de_macro(sh, data, len, flags, mpi)) return NULL;
130 de_macro_y(mpi
->planes
[0],data
,mpi
->stride
[0],mpi
->w
,mpi
->h
);
131 de_macro_uv(mpi
->planes
[1],mpi
->planes
[2],
132 (unsigned char *)data
+mpi
->w
*mpi
->h
,mpi
->stride
[1],
135 if(!nv12_to_yv12(data
, len
, mpi
,(sh
->format
== IMGFMT_NV21
))) return NULL
;
140 /*************************************************************************/