10 #include "codec-cfg.h"
11 #include "stream/stream.h"
12 #include "libmpdemux/demuxer.h"
13 #include "libmpdemux/stheader.h"
15 #include "stream/stream.h"
16 #include "libmpdemux/muxer.h"
18 #include "img_format.h"
22 #include "libmpdemux/nuppelvideo.h"
23 #include <lzo/lzo1x.h>
24 #include "native/rtjpegn.h"
26 #define LZO_AL(size) (((size) + (sizeof(long) - 1)) / sizeof(long))
27 #define LZO_OUT_LEN(in) ((in) + (in) / 64 + 16 + 3)
29 //===========================================================================//
32 int raw
; // Do not use RTjpeg
34 unsigned int l
,c
,q
; // Mjpeg param
41 long __LZO_MMODEL
*zmem
;
43 #define mux_v (vf->priv->mux)
45 struct vf_priv_s nuv_priv_dflt
= {
56 m_option_t nuvopts_conf
[]={
57 {"raw", &nuv_priv_dflt
.raw
, CONF_TYPE_FLAG
, 0, 0, 1, NULL
},
58 {"rtjpeg", &nuv_priv_dflt
.raw
, CONF_TYPE_FLAG
, 0, 1, 0, NULL
},
59 {"lzo", &nuv_priv_dflt
.lzo
, CONF_TYPE_FLAG
, 0, 0, 1, NULL
},
60 {"nolzo", &nuv_priv_dflt
.lzo
, CONF_TYPE_FLAG
, 0, 1, 0, NULL
},
61 {"q", &nuv_priv_dflt
.q
, CONF_TYPE_INT
, M_OPT_RANGE
,3,255, NULL
},
62 {"l", &nuv_priv_dflt
.l
, CONF_TYPE_INT
, M_OPT_RANGE
,0,20, NULL
},
63 {"c", &nuv_priv_dflt
.c
, CONF_TYPE_INT
, M_OPT_RANGE
,0,20, NULL
},
64 {NULL
, NULL
, 0, 0, 0, 0, NULL
}
67 //===========================================================================//
70 #define COMPDATASIZE (128*4)
72 static int config(struct vf_instance_s
* vf
,
73 int width
, int height
, int d_width
, int d_height
,
74 unsigned int flags
, unsigned int outfmt
){
76 // We need a buffer wich can holda header and a whole YV12 picture
78 vf
->priv
->buf_size
= width
*height
*3/2+FRAMEHEADERSIZE
;
79 if(vf
->priv
->buf_size
< COMPDATASIZE
+ FRAMEHEADERSIZE
)
80 vf
->priv
->buf_size
= COMPDATASIZE
+ FRAMEHEADERSIZE
;
82 mux_v
->bih
->biWidth
=width
;
83 mux_v
->bih
->biHeight
=height
;
84 mux_v
->bih
->biSizeImage
=mux_v
->bih
->biWidth
*mux_v
->bih
->biHeight
*(mux_v
->bih
->biBitCount
/8);
85 mux_v
->aspect
= (float)d_width
/d_height
;
86 vf
->priv
->buffer
= realloc(vf
->priv
->buffer
,vf
->priv
->buf_size
);
88 vf
->priv
->zbuffer
= realloc(vf
->priv
->zbuffer
, FRAMEHEADERSIZE
+ LZO_OUT_LEN(vf
->priv
->buf_size
));
89 vf
->priv
->tbl_wrote
= 0;
94 static int control(struct vf_instance_s
* vf
, int request
, void* data
){
96 return CONTROL_UNKNOWN
;
99 static int query_format(struct vf_instance_s
* vf
, unsigned int fmt
){
100 if(fmt
==IMGFMT_I420
) return VFCAP_CSP_SUPPORTED
| VFCAP_CSP_SUPPORTED_BY_HW
;
104 static int put_image(struct vf_instance_s
* vf
, mp_image_t
*mpi
, double pts
){
105 struct rtframeheader
* ench
= (struct rtframeheader
*)vf
->priv
->buffer
;
106 uint8_t* data
= vf
->priv
->buffer
+ FRAMEHEADERSIZE
;
107 uint8_t* zdata
= vf
->priv
->zbuffer
+ FRAMEHEADERSIZE
;
111 memset(vf
->priv
->buffer
,0,FRAMEHEADERSIZE
); // Reset the header
113 memset(vf
->priv
->zbuffer
,0,FRAMEHEADERSIZE
);
115 // This has to be don here otherwise tv with sound doesn't work
116 if(!vf
->priv
->tbl_wrote
) {
117 RTjpeg_init_compress((uint32_t *)data
,mpi
->width
,mpi
->height
,vf
->priv
->q
);
118 RTjpeg_init_mcompress();
120 ench
->frametype
= 'D'; // compressor data
121 ench
->comptype
= 'R'; // compressor data for RTjpeg
122 ench
->packetlength
= COMPDATASIZE
;
124 le2me_rtframeheader(ench
);
125 mux_v
->buffer
=vf
->priv
->buffer
;
126 muxer_write_chunk(mux_v
,FRAMEHEADERSIZE
+ COMPDATASIZE
, 0x10, MP_NOPTS_VALUE
, MP_NOPTS_VALUE
);
127 vf
->priv
->tbl_wrote
= 1;
128 memset(ench
,0,FRAMEHEADERSIZE
); // Reset the header
133 len
= mpi
->width
*mpi
->height
*3/2;
136 r
= lzo1x_1_compress(mpi
->planes
[0],len
,
137 zdata
,&zlen
,vf
->priv
->zmem
);
139 mp_msg(MSGT_VFILTER
,MSGL_ERR
,"LZO compress error\n");
144 if(zlen
<= 0 || zlen
> len
) {
145 memcpy(data
,mpi
->planes
[0],len
);
146 ench
->comptype
= '0';
147 } else { // Use lzo only if it's littler
148 ench
= (struct rtframeheader
*)vf
->priv
->zbuffer
;
149 ench
->comptype
= '3';
153 } else { // RTjpeg compression
154 len
= RTjpeg_mcompressYUV420(data
,mpi
->planes
[0],vf
->priv
->l
,
157 mp_msg(MSGT_VFILTER
,MSGL_ERR
,"RTjpeg_mcompressYUV420 error (%d)\n",len
);
162 r
= lzo1x_1_compress(data
,len
,zdata
,&zlen
,vf
->priv
->zmem
);
164 mp_msg(MSGT_VFILTER
,MSGL_ERR
,"LZO compress error\n");
169 if(zlen
<= 0 || zlen
> len
)
170 ench
->comptype
= '1';
172 ench
= (struct rtframeheader
*)vf
->priv
->zbuffer
;
173 ench
->comptype
= '2';
179 ench
->frametype
= 'V'; // video frame
180 ench
->packetlength
= len
;
181 le2me_rtframeheader(ench
);
182 mux_v
->buffer
=(void*)ench
;
183 muxer_write_chunk(mux_v
, len
+ FRAMEHEADERSIZE
, 0x10, pts
, pts
);
187 static void uninit(struct vf_instance_s
* vf
) {
190 free(vf
->priv
->buffer
);
191 if(vf
->priv
->zbuffer
)
192 free(vf
->priv
->zbuffer
);
194 free(vf
->priv
->zmem
);
198 //===========================================================================//
200 static int vf_open(vf_instance_t
*vf
, char* args
){
202 vf
->default_caps
=VFCAP_CONSTANT
;
204 vf
->query_format
=query_format
;
205 vf
->put_image
=put_image
;
207 vf
->priv
=malloc(sizeof(struct vf_priv_s
));
208 memcpy(vf
->priv
, &nuv_priv_dflt
,sizeof(struct vf_priv_s
));
209 vf
->priv
->mux
=(muxer_stream_t
*)args
;
211 mux_v
->bih
=calloc(1, sizeof(BITMAPINFOHEADER
));
212 mux_v
->bih
->biSize
=sizeof(BITMAPINFOHEADER
);
213 mux_v
->bih
->biWidth
=0;
214 mux_v
->bih
->biHeight
=0;
215 mux_v
->bih
->biPlanes
=1;
216 mux_v
->bih
->biBitCount
=12;
217 mux_v
->bih
->biCompression
= mmioFOURCC('N','U','V','1');
220 if(lzo_init() != LZO_E_OK
) {
221 mp_msg(MSGT_VFILTER
,MSGL_WARN
,"LZO init failed: no lzo compression\n");
224 vf
->priv
->zmem
= malloc(sizeof(long)*LZO_AL(LZO1X_1_MEM_COMPRESS
));
230 vf_info_t ve_info_nuv
= {
234 "for internal use by mencoder",
238 //===========================================================================//