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_IN_LEN (1024*1024L)
28 #define LZO_OUT_LEN (LZO_IN_LEN + LZO_IN_LEN / 64 + 16 + 3)
30 //===========================================================================//
33 int raw
; // Do not use RTjpeg
35 unsigned int l
,c
,q
; // Mjpeg param
42 long __LZO_MMODEL
*zmem
;
44 #define mux_v (vf->priv->mux)
46 struct vf_priv_s nuv_priv_dflt
= {
57 m_option_t nuvopts_conf
[]={
58 {"raw", &nuv_priv_dflt
.raw
, CONF_TYPE_FLAG
, 0, 0, 1, NULL
},
59 {"rtjpeg", &nuv_priv_dflt
.raw
, CONF_TYPE_FLAG
, 0, 1, 0, NULL
},
60 {"lzo", &nuv_priv_dflt
.lzo
, CONF_TYPE_FLAG
, 0, 0, 1, NULL
},
61 {"nolzo", &nuv_priv_dflt
.lzo
, CONF_TYPE_FLAG
, 0, 1, 0, NULL
},
62 {"q", &nuv_priv_dflt
.q
, CONF_TYPE_INT
, M_OPT_RANGE
,3,255, NULL
},
63 {"l", &nuv_priv_dflt
.l
, CONF_TYPE_INT
, M_OPT_RANGE
,0,20, NULL
},
64 {"c", &nuv_priv_dflt
.c
, CONF_TYPE_INT
, M_OPT_RANGE
,0,20, NULL
},
65 {NULL
, NULL
, 0, 0, 0, 0, NULL
}
68 //===========================================================================//
71 static int config(struct vf_instance_s
* vf
,
72 int width
, int height
, int d_width
, int d_height
,
73 unsigned int flags
, unsigned int outfmt
){
75 // We need a buffer wich can holda header and a whole YV12 picture
77 vf
->priv
->buf_size
= width
*height
*3/2+FRAMEHEADERSIZE
;
78 if(vf
->priv
->buf_size
< (int)(128*sizeof(long int) + FRAMEHEADERSIZE
))
79 vf
->priv
->buf_size
= 128*sizeof(long int) + FRAMEHEADERSIZE
;
81 mux_v
->bih
->biWidth
=width
;
82 mux_v
->bih
->biHeight
=height
;
83 mux_v
->bih
->biSizeImage
=mux_v
->bih
->biWidth
*mux_v
->bih
->biHeight
*(mux_v
->bih
->biBitCount
/8);
84 mux_v
->aspect
= (float)d_width
/d_height
;
85 vf
->priv
->buffer
= realloc(vf
->priv
->buffer
,vf
->priv
->buf_size
);
86 vf
->priv
->tbl_wrote
= 0;
91 static int control(struct vf_instance_s
* vf
, int request
, void* data
){
93 return CONTROL_UNKNOWN
;
96 static int query_format(struct vf_instance_s
* vf
, unsigned int fmt
){
97 if(fmt
==IMGFMT_I420
) return VFCAP_CSP_SUPPORTED
| VFCAP_CSP_SUPPORTED_BY_HW
;
101 static int put_image(struct vf_instance_s
* vf
, mp_image_t
*mpi
, double pts
){
102 struct rtframeheader
* ench
= (struct rtframeheader
*)vf
->priv
->buffer
;
103 uint8_t* data
= vf
->priv
->buffer
+ FRAMEHEADERSIZE
;
104 uint8_t* zdata
= vf
->priv
->zbuffer
+ FRAMEHEADERSIZE
;
105 int len
= 0, zlen
= 0,r
;
107 memset(vf
->priv
->buffer
,0,FRAMEHEADERSIZE
); // Reset the header
109 memset(vf
->priv
->zbuffer
,0,FRAMEHEADERSIZE
);
111 // This has to be don here otherwise tv with sound doesn't work
112 if(!vf
->priv
->tbl_wrote
) {
113 RTjpeg_init_compress((long int*)data
,mpi
->width
,mpi
->height
,vf
->priv
->q
);
114 RTjpeg_init_mcompress();
116 ench
->frametype
= 'D'; // compressor data
117 ench
->comptype
= 'R'; // compressor data for RTjpeg
118 ench
->packetlength
= 128*sizeof(long int);
120 le2me_rtframeheader(ench
);
121 mux_v
->buffer
=vf
->priv
->buffer
;
122 muxer_write_chunk(mux_v
,FRAMEHEADERSIZE
+ 128*sizeof(long int), 0x10, MP_NOPTS_VALUE
, MP_NOPTS_VALUE
);
123 vf
->priv
->tbl_wrote
= 1;
124 memset(ench
,0,FRAMEHEADERSIZE
); // Reset the header
129 len
= mpi
->width
*mpi
->height
*3/2;
132 r
= lzo1x_1_compress(mpi
->planes
[0],mpi
->width
*mpi
->height
*3/2,
133 zdata
,&zlen
,vf
->priv
->zmem
);
135 mp_msg(MSGT_VFILTER
,MSGL_ERR
,"LZO compress error\n");
140 if(zlen
<= 0 || zlen
> len
) {
141 memcpy(data
,mpi
->planes
[0],len
);
142 ench
->comptype
= '0';
143 } else { // Use lzo only if it's littler
144 ench
= (struct rtframeheader
*)vf
->priv
->zbuffer
;
145 ench
->comptype
= '3';
149 } else { // RTjpeg compression
150 len
= RTjpeg_mcompressYUV420(data
,mpi
->planes
[0],vf
->priv
->l
,
153 mp_msg(MSGT_VFILTER
,MSGL_ERR
,"RTjpeg_mcompressYUV420 error (%d)\n",len
);
158 r
= lzo1x_1_compress(data
,len
,zdata
,&zlen
,vf
->priv
->zmem
);
160 mp_msg(MSGT_VFILTER
,MSGL_ERR
,"LZO compress error\n");
165 if(zlen
<= 0 || zlen
> len
)
166 ench
->comptype
= '1';
168 ench
= (struct rtframeheader
*)vf
->priv
->zbuffer
;
169 ench
->comptype
= '2';
175 ench
->frametype
= 'V'; // video frame
176 ench
->packetlength
= len
;
177 le2me_rtframeheader(ench
);
178 mux_v
->buffer
=(void*)ench
;
179 muxer_write_chunk(mux_v
, len
+ FRAMEHEADERSIZE
, 0x10, pts
, pts
);
183 static void uninit(struct vf_instance_s
* vf
) {
186 free(vf
->priv
->buffer
);
187 if(vf
->priv
->zbuffer
)
188 free(vf
->priv
->zbuffer
);
190 free(vf
->priv
->zmem
);
194 //===========================================================================//
196 static int vf_open(vf_instance_t
*vf
, char* args
){
198 vf
->default_caps
=VFCAP_CONSTANT
;
200 vf
->query_format
=query_format
;
201 vf
->put_image
=put_image
;
203 vf
->priv
=malloc(sizeof(struct vf_priv_s
));
204 memcpy(vf
->priv
, &nuv_priv_dflt
,sizeof(struct vf_priv_s
));
205 vf
->priv
->mux
=(muxer_stream_t
*)args
;
207 mux_v
->bih
=calloc(1, sizeof(BITMAPINFOHEADER
));
208 mux_v
->bih
->biSize
=sizeof(BITMAPINFOHEADER
);
209 mux_v
->bih
->biWidth
=0;
210 mux_v
->bih
->biHeight
=0;
211 mux_v
->bih
->biPlanes
=1;
212 mux_v
->bih
->biBitCount
=12;
213 mux_v
->bih
->biCompression
= mmioFOURCC('N','U','V','1');
216 if(lzo_init() != LZO_E_OK
) {
217 mp_msg(MSGT_VFILTER
,MSGL_WARN
,"LZO init failed: no lzo compression\n");
220 vf
->priv
->zbuffer
= (lzo_bytep
)malloc(FRAMEHEADERSIZE
+ LZO_OUT_LEN
);
221 vf
->priv
->zmem
= malloc(sizeof(long)*LZO_AL(LZO1X_1_MEM_COMPRESS
));
227 vf_info_t ve_info_nuv
= {
231 "for internal use by mencoder",
235 //===========================================================================//