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 #define TEMP_BUF_SIZE (720*576)
29 static const vd_info_t info
= {
30 "Hauppauge Macroblock/NV12/NV21 Decoder",
32 "Alex <d18c7db@hotmail.com>, A'rpi, Alex Beregszaszi",
33 "Alex <d18c7db@hotmail.com>",
39 static void de_macro_y(unsigned char* dst
,unsigned char* src
,int dstride
,int w
,int h
){
42 for (y
=0; y
<h
; y
+=16) {
44 for (x
=0; x
<w
; x
+=16) {
46 for (i
=0; i
<16; i
++) {
47 memcpy(dst
+ x
+ (y
+i
)*dstride
, src
, 16);
54 static void de_macro_uv(unsigned char* dstu
,unsigned char* dstv
,unsigned char* src
,int dstride
,int w
,int h
){
56 // descramble U/V plane
57 for (y
=0; y
<h
; y
+=16) {
59 for (x
=0; x
<w
; x
+=8) {
61 for (i
=0; i
<16; i
++) {
62 int idx
=x
+ (y
+i
)*dstride
;
63 dstu
[idx
+0]=src
[0]; dstv
[idx
+0]=src
[1];
64 dstu
[idx
+1]=src
[2]; dstv
[idx
+1]=src
[3];
65 dstu
[idx
+2]=src
[4]; dstv
[idx
+2]=src
[5];
66 dstu
[idx
+3]=src
[6]; dstv
[idx
+3]=src
[7];
67 dstu
[idx
+4]=src
[8]; dstv
[idx
+4]=src
[9];
68 dstu
[idx
+5]=src
[10]; dstv
[idx
+5]=src
[11];
69 dstu
[idx
+6]=src
[12]; dstv
[idx
+6]=src
[13];
70 dstu
[idx
+7]=src
[14]; dstv
[idx
+7]=src
[15];
77 /*************************************************************************
78 * convert a nv12 buffer to yv12
80 static int nv12_to_yv12(unsigned char *data
, int len
, mp_image_t
* mpi
, int swapped
) {
81 unsigned int Y_size
= mpi
->width
* mpi
->height
;
82 unsigned int UV_size
= mpi
->chroma_width
* mpi
->chroma_height
;
84 unsigned char *dst_Y
= mpi
->planes
[0];
85 unsigned char *dst_U
= mpi
->planes
[1];
86 unsigned char *dst_V
= mpi
->planes
[2];
87 unsigned char *src
= data
+ Y_size
;
89 // sanity check raw stream
90 if ( (len
!= (Y_size
+ (UV_size
<<1))) ) {
91 mp_msg(MSGT_DECVIDEO
, MSGL_ERR
,
92 "hmblck: Image size inconsistent with data size.\n");
95 if ( (mpi
->width
> 720) || (mpi
->height
> 576) ) {
96 mp_msg(MSGT_DECVIDEO
,MSGL_ERR
,
97 "hmblck: Image size is too big.\n");
100 if (mpi
->num_planes
!= 3) {
101 mp_msg(MSGT_DECVIDEO
,MSGL_ERR
,
102 "hmblck: Incorrect number of image planes.\n");
106 // luma data is easy, just copy it
107 memcpy(dst_Y
, data
, Y_size
);
109 // chroma data is interlaced UVUV... so deinterlace it
110 for(idx
=0; idx
<UV_size
; idx
++ ) {
111 *(dst_U
+ idx
) = *(src
+ (idx
<<1) + (swapped
? 1 : 0));
112 *(dst_V
+ idx
) = *(src
+ (idx
<<1) + (swapped
? 0 : 1));
117 /*************************************************************************
118 * set/get/query special features/parameters
120 static int control(sh_video_t
*sh
,int cmd
, void *arg
,...){
121 return CONTROL_UNKNOWN
;
123 /*************************************************************************
126 static int init(sh_video_t
*sh
){
127 return mpcodecs_config_vo(sh
,sh
->disp_w
,sh
->disp_h
,sh
->format
);
129 /*************************************************************************
132 static void uninit(sh_video_t
*sh
){
134 /*************************************************************************
137 static mp_image_t
* decode(sh_video_t
*sh
,void* data
,int len
,int flags
){
140 if(len
<=0) return NULL
; // skipped frame
142 mpi
=mpcodecs_get_image(sh
, MP_IMGTYPE_TEMP
, MP_IMGFLAG_ACCEPT_STRIDE
,
143 sh
->disp_w
, sh
->disp_h
);
144 if(!mpi
) return NULL
;
146 if(sh
->format
== IMGFMT_HM12
) {
147 //if(!de_macro(sh, data, len, flags, mpi)) return NULL;
148 de_macro_y(mpi
->planes
[0],data
,mpi
->stride
[0],mpi
->w
,mpi
->h
);
149 de_macro_uv(mpi
->planes
[1],mpi
->planes
[2],
150 (unsigned char *)data
+mpi
->w
*mpi
->h
,mpi
->stride
[1],
153 if(!nv12_to_yv12(data
, len
, mpi
,(sh
->format
== IMGFMT_NV21
))) return NULL
;
158 /*************************************************************************/