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.
28 #include "codec-cfg.h"
29 #include "stream/stream.h"
30 #include "libmpdemux/demuxer.h"
31 #include "libmpdemux/stheader.h"
33 #include "stream/stream.h"
34 #include "libmpdemux/muxer.h"
36 #include "img_format.h"
40 #include "ffmpeg_files/intreadwrite.h"
41 #include <lzo/lzo1x.h>
42 #include "native/rtjpegn.h"
44 #define LZO_AL(size) (((size) + (sizeof(long) - 1)) / sizeof(long))
45 #define LZO_OUT_LEN(in) ((in) + (in) / 64 + 16 + 3)
47 //===========================================================================//
50 int raw
; // Do not use RTjpeg
52 unsigned int l
,c
,q
; // Mjpeg param
59 long __LZO_MMODEL
*zmem
;
61 #define mux_v (vf->priv->mux)
63 struct vf_priv_s nuv_priv_dflt
= {
74 const m_option_t nuvopts_conf
[] = {
75 {"raw", &nuv_priv_dflt
.raw
, CONF_TYPE_FLAG
, 0, 0, 1, NULL
},
76 {"rtjpeg", &nuv_priv_dflt
.raw
, CONF_TYPE_FLAG
, 0, 1, 0, NULL
},
77 {"lzo", &nuv_priv_dflt
.lzo
, CONF_TYPE_FLAG
, 0, 0, 1, NULL
},
78 {"nolzo", &nuv_priv_dflt
.lzo
, CONF_TYPE_FLAG
, 0, 1, 0, NULL
},
79 {"q", &nuv_priv_dflt
.q
, CONF_TYPE_INT
, M_OPT_RANGE
,3,255, NULL
},
80 {"l", &nuv_priv_dflt
.l
, CONF_TYPE_INT
, M_OPT_RANGE
,0,20, NULL
},
81 {"c", &nuv_priv_dflt
.c
, CONF_TYPE_INT
, M_OPT_RANGE
,0,20, NULL
},
82 {NULL
, NULL
, 0, 0, 0, 0, NULL
}
85 //===========================================================================//
88 #define COMPDATASIZE (128*4)
89 #define FRAMEHEADERSIZE 12
91 static int config(struct vf_instance
*vf
,
92 int width
, int height
, int d_width
, int d_height
,
93 unsigned int flags
, unsigned int outfmt
){
95 // We need a buffer wich can holda header and a whole YV12 picture
97 vf
->priv
->buf_size
= width
*height
*3/2+FRAMEHEADERSIZE
;
98 if(vf
->priv
->buf_size
< COMPDATASIZE
+ FRAMEHEADERSIZE
)
99 vf
->priv
->buf_size
= COMPDATASIZE
+ FRAMEHEADERSIZE
;
101 mux_v
->bih
->biWidth
=width
;
102 mux_v
->bih
->biHeight
=height
;
103 mux_v
->bih
->biSizeImage
=mux_v
->bih
->biWidth
*mux_v
->bih
->biHeight
*(mux_v
->bih
->biBitCount
/8);
104 mux_v
->aspect
= (float)d_width
/d_height
;
105 vf
->priv
->buffer
= realloc(vf
->priv
->buffer
,vf
->priv
->buf_size
);
107 vf
->priv
->zbuffer
= realloc(vf
->priv
->zbuffer
, FRAMEHEADERSIZE
+ LZO_OUT_LEN(vf
->priv
->buf_size
));
108 vf
->priv
->tbl_wrote
= 0;
113 static int control(struct vf_instance
*vf
, int request
, void* data
){
115 return CONTROL_UNKNOWN
;
118 static int query_format(struct vf_instance
*vf
, unsigned int fmt
){
119 if(fmt
==IMGFMT_I420
) return VFCAP_CSP_SUPPORTED
| VFCAP_CSP_SUPPORTED_BY_HW
;
123 static int put_image(struct vf_instance
*vf
, mp_image_t
*mpi
, double pts
){
124 uint8_t *header
= vf
->priv
->buffer
;
125 uint8_t* data
= vf
->priv
->buffer
+ FRAMEHEADERSIZE
;
126 uint8_t* zdata
= vf
->priv
->zbuffer
+ FRAMEHEADERSIZE
;
130 memset(header
, 0, FRAMEHEADERSIZE
); // Reset the header
132 memset(vf
->priv
->zbuffer
,0,FRAMEHEADERSIZE
);
134 // This has to be don here otherwise tv with sound doesn't work
135 if(!vf
->priv
->tbl_wrote
) {
136 RTjpeg_init_compress((uint32_t *)data
,mpi
->width
,mpi
->height
,vf
->priv
->q
);
137 RTjpeg_init_mcompress();
139 header
[0] = 'D'; // frametype: compressor data
140 header
[1] = 'R'; // comptype: compressor data for RTjpeg
141 AV_WL32(header
+ 8, COMPDATASIZE
); // packetlength
143 mux_v
->buffer
=vf
->priv
->buffer
;
144 muxer_write_chunk(mux_v
,FRAMEHEADERSIZE
+ COMPDATASIZE
, 0x10, MP_NOPTS_VALUE
, MP_NOPTS_VALUE
);
145 vf
->priv
->tbl_wrote
= 1;
146 memset(header
, 0, FRAMEHEADERSIZE
); // Reset the header
151 len
= mpi
->width
*mpi
->height
*3/2;
154 r
= lzo1x_1_compress(mpi
->planes
[0],len
,
155 zdata
,&zlen
,vf
->priv
->zmem
);
157 mp_msg(MSGT_VFILTER
,MSGL_ERR
,"LZO compress error\n");
162 if(zlen
<= 0 || zlen
> len
) {
163 memcpy(data
,mpi
->planes
[0],len
);
164 header
[1] = '0'; // comptype: uncompressed
165 } else { // Use lzo only if it's littler
166 header
= vf
->priv
->zbuffer
;
167 header
[1] = '3'; //comptype: lzo
171 } else { // RTjpeg compression
172 len
= RTjpeg_mcompressYUV420(data
,mpi
->planes
[0],vf
->priv
->l
,
175 mp_msg(MSGT_VFILTER
,MSGL_ERR
,"RTjpeg_mcompressYUV420 error (%d)\n",len
);
180 r
= lzo1x_1_compress(data
,len
,zdata
,&zlen
,vf
->priv
->zmem
);
182 mp_msg(MSGT_VFILTER
,MSGL_ERR
,"LZO compress error\n");
187 if(zlen
<= 0 || zlen
> len
)
188 header
[1] = '1'; // comptype: RTjpeg
190 header
= vf
->priv
->zbuffer
;
191 header
[1] = '2'; // comptype: RTjpeg + LZO
197 header
[0] = 'V'; // frametype: video frame
198 AV_WL32(header
+ 8, len
); // packetlength
199 mux_v
->buffer
= header
;
200 muxer_write_chunk(mux_v
, len
+ FRAMEHEADERSIZE
, 0x10, pts
, pts
);
204 static void uninit(struct vf_instance
*vf
) {
207 free(vf
->priv
->buffer
);
208 if(vf
->priv
->zbuffer
)
209 free(vf
->priv
->zbuffer
);
211 free(vf
->priv
->zmem
);
215 //===========================================================================//
217 static int vf_open(vf_instance_t
*vf
, char* args
){
219 vf
->default_caps
=VFCAP_CONSTANT
;
221 vf
->query_format
=query_format
;
222 vf
->put_image
=put_image
;
224 vf
->priv
=malloc(sizeof(struct vf_priv_s
));
225 memcpy(vf
->priv
, &nuv_priv_dflt
,sizeof(struct vf_priv_s
));
226 vf
->priv
->mux
=(muxer_stream_t
*)args
;
228 mux_v
->bih
=calloc(1, sizeof(BITMAPINFOHEADER
));
229 mux_v
->bih
->biSize
=sizeof(BITMAPINFOHEADER
);
230 mux_v
->bih
->biWidth
=0;
231 mux_v
->bih
->biHeight
=0;
232 mux_v
->bih
->biPlanes
=1;
233 mux_v
->bih
->biBitCount
=12;
234 mux_v
->bih
->biCompression
= mmioFOURCC('N','U','V','1');
237 if(lzo_init() != LZO_E_OK
) {
238 mp_msg(MSGT_VFILTER
,MSGL_WARN
,"LZO init failed: no lzo compression\n");
241 vf
->priv
->zmem
= malloc(sizeof(long)*LZO_AL(LZO1X_1_MEM_COMPRESS
));
247 vf_info_t ve_info_nuv
= {
251 "for internal use by mencoder",
255 //===========================================================================//