2 * This file is part of MPlayer.
4 * MPlayer is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
9 * MPlayer is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License along
15 * with MPlayer; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
25 #include "vd_internal.h"
27 static const vd_info_t info
= {
28 "Hauppauge Macroblock/NV12/NV21 Decoder",
30 "Alex <d18c7db@hotmail.com>, A'rpi, Alex Beregszaszi",
31 "Alex <d18c7db@hotmail.com>",
37 static void de_macro_y(unsigned char* dst
,unsigned char* src
,int dstride
,int w
,int h
){
40 for (y
=0; y
<h
; y
+=16) {
42 for (x
=0; x
<w
; x
+=16) {
44 for (i
=0; i
<16; i
++) {
45 memcpy(dst
+ x
+ (y
+i
)*dstride
, src
, 16);
52 static void de_macro_uv(unsigned char* dstu
,unsigned char* dstv
,unsigned char* src
,int dstride
,int w
,int h
){
54 // descramble U/V plane
55 for (y
=0; y
<h
; y
+=16) {
57 for (x
=0; x
<w
; x
+=8) {
59 for (i
=0; i
<16; i
++) {
60 int idx
=x
+ (y
+i
)*dstride
;
61 dstu
[idx
+0]=src
[0]; dstv
[idx
+0]=src
[1];
62 dstu
[idx
+1]=src
[2]; dstv
[idx
+1]=src
[3];
63 dstu
[idx
+2]=src
[4]; dstv
[idx
+2]=src
[5];
64 dstu
[idx
+3]=src
[6]; dstv
[idx
+3]=src
[7];
65 dstu
[idx
+4]=src
[8]; dstv
[idx
+4]=src
[9];
66 dstu
[idx
+5]=src
[10]; dstv
[idx
+5]=src
[11];
67 dstu
[idx
+6]=src
[12]; dstv
[idx
+6]=src
[13];
68 dstu
[idx
+7]=src
[14]; dstv
[idx
+7]=src
[15];
75 /*************************************************************************
76 * convert a nv12 buffer to yv12
78 static int nv12_to_yv12(unsigned char *data
, int len
, mp_image_t
* mpi
, int swapped
) {
79 unsigned int Y_size
= mpi
->width
* mpi
->height
;
80 unsigned int UV_size
= mpi
->chroma_width
* mpi
->chroma_height
;
82 unsigned char *dst_Y
= mpi
->planes
[0];
83 unsigned char *dst_U
= mpi
->planes
[1];
84 unsigned char *dst_V
= mpi
->planes
[2];
85 unsigned char *src
= data
+ Y_size
;
87 // sanity check raw stream
88 if ( (len
!= (Y_size
+ (UV_size
<<1))) ) {
89 mp_msg(MSGT_DECVIDEO
, MSGL_ERR
,
90 "hmblck: Image size inconsistent with data size.\n");
93 if (mpi
->num_planes
!= 3) {
94 mp_msg(MSGT_DECVIDEO
,MSGL_ERR
,
95 "hmblck: Incorrect number of image planes.\n");
99 // luma data is easy, just copy it
100 memcpy(dst_Y
, data
, Y_size
);
102 // chroma data is interlaced UVUV... so deinterlace it
103 for(idx
=0; idx
<UV_size
; idx
++ ) {
104 *(dst_U
+ idx
) = *(src
+ (idx
<<1) + (swapped
? 1 : 0));
105 *(dst_V
+ idx
) = *(src
+ (idx
<<1) + (swapped
? 0 : 1));
110 /*************************************************************************
111 * set/get/query special features/parameters
113 static int control(sh_video_t
*sh
,int cmd
, void *arg
,...){
114 return CONTROL_UNKNOWN
;
116 /*************************************************************************
119 static int init(sh_video_t
*sh
){
120 return mpcodecs_config_vo(sh
,sh
->disp_w
,sh
->disp_h
,sh
->format
);
122 /*************************************************************************
125 static void uninit(sh_video_t
*sh
){
127 /*************************************************************************
130 static mp_image_t
* decode(sh_video_t
*sh
,void* data
,int len
,int flags
){
133 if(len
<=0) return NULL
; // skipped frame
135 mpi
=mpcodecs_get_image(sh
, MP_IMGTYPE_TEMP
, MP_IMGFLAG_ACCEPT_STRIDE
,
136 sh
->disp_w
, sh
->disp_h
);
137 if(!mpi
) return NULL
;
139 if(sh
->format
== IMGFMT_HM12
) {
140 //if(!de_macro(sh, data, len, flags, mpi)) return NULL;
141 de_macro_y(mpi
->planes
[0],data
,mpi
->stride
[0],mpi
->w
,mpi
->h
);
142 de_macro_uv(mpi
->planes
[1],mpi
->planes
[2],
143 (unsigned char *)data
+mpi
->w
*mpi
->h
,mpi
->stride
[1],
146 if(!nv12_to_yv12(data
, len
, mpi
,(sh
->format
== IMGFMT_NV21
))) return NULL
;
151 /*************************************************************************/