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 "libavutil/intreadwrite.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)
71 #define FRAMEHEADERSIZE 12
73 static int config(struct vf_instance_s
* vf
,
74 int width
, int height
, int d_width
, int d_height
,
75 unsigned int flags
, unsigned int outfmt
){
77 // We need a buffer wich can holda header and a whole YV12 picture
79 vf
->priv
->buf_size
= width
*height
*3/2+FRAMEHEADERSIZE
;
80 if(vf
->priv
->buf_size
< COMPDATASIZE
+ FRAMEHEADERSIZE
)
81 vf
->priv
->buf_size
= COMPDATASIZE
+ FRAMEHEADERSIZE
;
83 mux_v
->bih
->biWidth
=width
;
84 mux_v
->bih
->biHeight
=height
;
85 mux_v
->bih
->biSizeImage
=mux_v
->bih
->biWidth
*mux_v
->bih
->biHeight
*(mux_v
->bih
->biBitCount
/8);
86 mux_v
->aspect
= (float)d_width
/d_height
;
87 vf
->priv
->buffer
= realloc(vf
->priv
->buffer
,vf
->priv
->buf_size
);
89 vf
->priv
->zbuffer
= realloc(vf
->priv
->zbuffer
, FRAMEHEADERSIZE
+ LZO_OUT_LEN(vf
->priv
->buf_size
));
90 vf
->priv
->tbl_wrote
= 0;
95 static int control(struct vf_instance_s
* vf
, int request
, void* data
){
97 return CONTROL_UNKNOWN
;
100 static int query_format(struct vf_instance_s
* vf
, unsigned int fmt
){
101 if(fmt
==IMGFMT_I420
) return VFCAP_CSP_SUPPORTED
| VFCAP_CSP_SUPPORTED_BY_HW
;
105 static int put_image(struct vf_instance_s
* vf
, mp_image_t
*mpi
, double pts
){
106 uint8_t *header
= vf
->priv
->buffer
;
107 uint8_t* data
= vf
->priv
->buffer
+ FRAMEHEADERSIZE
;
108 uint8_t* zdata
= vf
->priv
->zbuffer
+ FRAMEHEADERSIZE
;
112 memset(header
, 0, FRAMEHEADERSIZE
); // Reset the header
114 memset(vf
->priv
->zbuffer
,0,FRAMEHEADERSIZE
);
116 // This has to be don here otherwise tv with sound doesn't work
117 if(!vf
->priv
->tbl_wrote
) {
118 RTjpeg_init_compress((uint32_t *)data
,mpi
->width
,mpi
->height
,vf
->priv
->q
);
119 RTjpeg_init_mcompress();
121 header
[0] = 'D'; // frametype: compressor data
122 header
[1] = 'R'; // comptype: compressor data for RTjpeg
123 AV_WL32(header
+ 8, COMPDATASIZE
); // packetlength
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(header
, 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 header
[1] = '0'; // comptype: uncompressed
147 } else { // Use lzo only if it's littler
148 header
= vf
->priv
->zbuffer
;
149 header
[1] = '3'; //comptype: lzo
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 header
[1] = '1'; // comptype: RTjpeg
172 header
= vf
->priv
->zbuffer
;
173 header
[1] = '2'; // comptype: RTjpeg + LZO
179 header
[0] = 'V'; // frametype: video frame
180 AV_WL32(header
+ 8, len
); // packetlength
181 mux_v
->buffer
= header
;
182 muxer_write_chunk(mux_v
, len
+ FRAMEHEADERSIZE
, 0x10, pts
, pts
);
186 static void uninit(struct vf_instance_s
* vf
) {
189 free(vf
->priv
->buffer
);
190 if(vf
->priv
->zbuffer
)
191 free(vf
->priv
->zbuffer
);
193 free(vf
->priv
->zmem
);
197 //===========================================================================//
199 static int vf_open(vf_instance_t
*vf
, char* args
){
201 vf
->default_caps
=VFCAP_CONSTANT
;
203 vf
->query_format
=query_format
;
204 vf
->put_image
=put_image
;
206 vf
->priv
=malloc(sizeof(struct vf_priv_s
));
207 memcpy(vf
->priv
, &nuv_priv_dflt
,sizeof(struct vf_priv_s
));
208 vf
->priv
->mux
=(muxer_stream_t
*)args
;
210 mux_v
->bih
=calloc(1, sizeof(BITMAPINFOHEADER
));
211 mux_v
->bih
->biSize
=sizeof(BITMAPINFOHEADER
);
212 mux_v
->bih
->biWidth
=0;
213 mux_v
->bih
->biHeight
=0;
214 mux_v
->bih
->biPlanes
=1;
215 mux_v
->bih
->biBitCount
=12;
216 mux_v
->bih
->biCompression
= mmioFOURCC('N','U','V','1');
219 if(lzo_init() != LZO_E_OK
) {
220 mp_msg(MSGT_VFILTER
,MSGL_WARN
,"LZO init failed: no lzo compression\n");
223 vf
->priv
->zmem
= malloc(sizeof(long)*LZO_AL(LZO1X_1_MEM_COMPRESS
));
229 vf_info_t ve_info_nuv
= {
233 "for internal use by mencoder",
237 //===========================================================================//