10 #include "codec-cfg.h"
17 #include "img_format.h"
21 #include "libmpdemux/nuppelvideo.h"
22 #include "native/minilzo.h"
23 #include "native/RTjpegN.h"
25 #define LZO_AL(size) (((size) + (sizeof(long) - 1)) / sizeof(long))
26 #define LZO_IN_LEN (1024*1024L)
27 #define LZO_OUT_LEN (LZO_IN_LEN + LZO_IN_LEN / 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 static int config(struct vf_instance_s
* vf
,
71 int width
, int height
, int d_width
, int d_height
,
72 unsigned int flags
, unsigned int outfmt
){
74 // We need a buffer wich can holda header and a whole YV12 picture
76 vf
->priv
->buf_size
= width
*height
*3/2+FRAMEHEADERSIZE
;
77 if(vf
->priv
->buf_size
< (int)(128*sizeof(long int) + FRAMEHEADERSIZE
))
78 vf
->priv
->buf_size
= 128*sizeof(long int) + FRAMEHEADERSIZE
;
80 mux_v
->bih
->biWidth
=width
;
81 mux_v
->bih
->biHeight
=height
;
82 mux_v
->bih
->biSizeImage
=mux_v
->bih
->biWidth
*mux_v
->bih
->biHeight
*(mux_v
->bih
->biBitCount
/8);
83 mux_v
->aspect
= (float)d_width
/d_height
;
84 vf
->priv
->buffer
= realloc(vf
->priv
->buffer
,vf
->priv
->buf_size
);
85 vf
->priv
->tbl_wrote
= 0;
90 static int control(struct vf_instance_s
* vf
, int request
, void* data
){
92 return CONTROL_UNKNOWN
;
95 static int query_format(struct vf_instance_s
* vf
, unsigned int fmt
){
96 if(fmt
==IMGFMT_I420
) return VFCAP_CSP_SUPPORTED
| VFCAP_CSP_SUPPORTED_BY_HW
;
100 static int put_image(struct vf_instance_s
* vf
, mp_image_t
*mpi
){
101 struct rtframeheader
* ench
= (struct rtframeheader
*)vf
->priv
->buffer
;
102 uint8_t* data
= vf
->priv
->buffer
+ FRAMEHEADERSIZE
;
103 uint8_t* zdata
= vf
->priv
->zbuffer
+ FRAMEHEADERSIZE
;
104 int len
= 0, zlen
= 0,r
;
106 memset(vf
->priv
->buffer
,0,FRAMEHEADERSIZE
); // Reset the header
108 memset(vf
->priv
->zbuffer
,0,FRAMEHEADERSIZE
);
110 // This has to be don here otherwise tv with sound doesn't work
111 if(!vf
->priv
->tbl_wrote
) {
112 RTjpeg_init_compress((long int*)data
,mpi
->width
,mpi
->height
,vf
->priv
->q
);
113 RTjpeg_init_mcompress();
115 ench
->frametype
= 'D'; // compressor data
116 ench
->comptype
= 'R'; // compressor data for RTjpeg
117 ench
->packetlength
= 128*sizeof(long int);
119 le2me_rtframeheader(ench
);
120 mux_v
->buffer
=vf
->priv
->buffer
;
121 muxer_write_chunk(mux_v
,FRAMEHEADERSIZE
+ 128*sizeof(long int), 0x10);
122 vf
->priv
->tbl_wrote
= 1;
123 memset(ench
,0,FRAMEHEADERSIZE
); // Reset the header
128 len
= mpi
->width
*mpi
->height
*3/2;
131 r
= lzo1x_1_compress(mpi
->planes
[0],mpi
->width
*mpi
->height
*3/2,
132 zdata
,&zlen
,vf
->priv
->zmem
);
134 mp_msg(MSGT_VFILTER
,MSGL_ERR
,"LZO compress error\n");
139 if(zlen
<= 0 || zlen
> len
) {
140 memcpy(data
,mpi
->planes
[0],len
);
141 ench
->comptype
= '0';
142 } else { // Use lzo only if it's littler
143 ench
= (struct rtframeheader
*)vf
->priv
->zbuffer
;
144 ench
->comptype
= '3';
148 } else { // RTjpeg compression
149 len
= RTjpeg_mcompressYUV420(data
,mpi
->planes
[0],vf
->priv
->l
,
152 mp_msg(MSGT_VFILTER
,MSGL_ERR
,"RTjpeg_mcompressYUV420 error (%d)\n",len
);
157 r
= lzo1x_1_compress(data
,len
,zdata
,&zlen
,vf
->priv
->zmem
);
159 mp_msg(MSGT_VFILTER
,MSGL_ERR
,"LZO compress error\n");
164 if(zlen
<= 0 || zlen
> len
)
165 ench
->comptype
= '1';
167 ench
= (struct rtframeheader
*)vf
->priv
->zbuffer
;
168 ench
->comptype
= '2';
174 ench
->frametype
= 'V'; // video frame
175 ench
->packetlength
= len
;
176 le2me_rtframeheader(ench
);
177 mux_v
->buffer
=(void*)ench
;
178 muxer_write_chunk(mux_v
, len
+ FRAMEHEADERSIZE
, 0x10);
182 static void uninit(struct vf_instance_s
* vf
) {
185 free(vf
->priv
->buffer
);
186 if(vf
->priv
->zbuffer
)
187 free(vf
->priv
->zbuffer
);
189 free(vf
->priv
->zmem
);
193 //===========================================================================//
195 static int vf_open(vf_instance_t
*vf
, char* args
){
197 vf
->default_caps
=VFCAP_CONSTANT
;
199 vf
->query_format
=query_format
;
200 vf
->put_image
=put_image
;
202 vf
->priv
=malloc(sizeof(struct vf_priv_s
));
203 memcpy(vf
->priv
, &nuv_priv_dflt
,sizeof(struct vf_priv_s
));
204 vf
->priv
->mux
=(muxer_stream_t
*)args
;
206 mux_v
->bih
=calloc(1, sizeof(BITMAPINFOHEADER
));
207 mux_v
->bih
->biSize
=sizeof(BITMAPINFOHEADER
);
208 mux_v
->bih
->biWidth
=0;
209 mux_v
->bih
->biHeight
=0;
210 mux_v
->bih
->biPlanes
=1;
211 mux_v
->bih
->biBitCount
=12;
212 mux_v
->bih
->biCompression
= mmioFOURCC('N','U','V','1');
215 if(lzo_init() != LZO_E_OK
) {
216 mp_msg(MSGT_VFILTER
,MSGL_WARN
,"LZO init failed: no lzo compression\n");
219 vf
->priv
->zbuffer
= (lzo_bytep
)malloc(FRAMEHEADERSIZE
+ LZO_OUT_LEN
);
220 vf
->priv
->zmem
= (long*)malloc(sizeof(long)*LZO_AL(LZO1X_1_MEM_COMPRESS
));
226 vf_info_t ve_info_nuv
= {
230 "for internal use by mencoder",
234 //===========================================================================//