1 /*****************************************************************************
2 * invmem_decoder.c: memory video driver for vlc
3 *****************************************************************************
4 * Copyright (C) 2008 the VideoLAN team
7 * Authors: Robert Paciorek <robert@opcode.eu.org> <http://opcode.eu.org/bercik>
9 * - vmem video output module (Gildas Bazin <gbazin@videolan.org>)
10 * - png video decodec module (Sam Hocevar <sam@zoy.org>)
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License as published by
14 * the Free Software Foundation; either version 2 of the License, or
15 * (at your option) any later version.
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
25 *****************************************************************************/
27 /*****************************************************************************
29 *****************************************************************************/
35 #include <vlc_common.h>
36 #include <vlc_plugin.h>
37 #include <vlc_codec.h>
39 #include <vlc_image.h>
40 #include <vlc_filter.h>
42 /*****************************************************************************
44 *****************************************************************************/
45 static int OpenDecoder ( vlc_object_t
* );
46 static void CloseDecoder ( vlc_object_t
* );
48 static picture_t
*DecodeBlock ( decoder_t
*, block_t
** );
50 /*****************************************************************************
52 *****************************************************************************/
53 #define T_WIDTH N_( "Width" )
54 #define LT_WIDTH N_( "Video memory buffer width." )
56 #define T_HEIGHT N_( "Height" )
57 #define LT_HEIGHT N_( "Video memory buffer height." )
59 #define T_LOCK N_( "Lock function" )
60 #define LT_LOCK N_( "Address of the locking callback function. This " \
61 "function must return a valid memory address for use " \
62 "by the video renderer." )
64 #define T_UNLOCK N_( "Unlock function" )
65 #define LT_UNLOCK N_( "Address of the unlocking callback function" )
67 #define T_DATA N_( "Callback data" )
68 #define LT_DATA N_( "Data for the locking and unlocking functions" )
70 #define T_CHROMA N_("Chroma")
71 #define LT_CHROMA N_("Output chroma for the memory image as a 4-character " \
72 "string, eg. \"RV32\".")
75 set_category( CAT_INPUT
)
76 set_subcategory( SUBCAT_INPUT_VCODEC
)
77 set_shortname( N_("Memory video decoder") )
78 set_description( N_("Memory video decoder") )
79 set_capability( "decoder", 50 )
80 set_callbacks( OpenDecoder
, CloseDecoder
)
81 add_shortcut( "invmem" )
83 add_integer( "invmem-width", 0, NULL
, T_WIDTH
, LT_WIDTH
, false )
84 add_integer( "invmem-height", 0, NULL
, T_HEIGHT
, LT_HEIGHT
, false )
85 add_string( "invmem-lock", "0", NULL
, T_LOCK
, LT_LOCK
, true )
86 add_string( "invmem-unlock", "0", NULL
, T_UNLOCK
, LT_UNLOCK
, true )
87 add_string( "invmem-data", "0", NULL
, T_DATA
, LT_DATA
, true )
88 add_string( "invmem-chroma", "RV24", NULL
, T_CHROMA
, LT_CHROMA
, true)
94 void * (*pf_lock
) (void *);
95 void (*pf_unlock
) (void *);
102 vlc_fourcc_t i_chroma
;
106 /*****************************************************************************
107 * OpenDecoder: probe the decoder and return score
108 *****************************************************************************/
109 static int OpenDecoder( vlc_object_t
*p_this
)
111 decoder_t
*p_dec
= (decoder_t
*)p_this
;
112 decoder_sys_t
*p_sys
;
116 if( p_dec
->fmt_in
.i_codec
!= VLC_FOURCC('f','a','k','e'))
121 /* Allocate the memory needed to store the decoder's structure */
122 if( ( p_dec
->p_sys
= p_sys
= malloc(sizeof(decoder_sys_t
)) ) == NULL
)
126 char* chromaStr
= var_CreateGetString( p_dec
, "invmem-chroma" );
127 p_sys
->i_width
= var_CreateGetInteger( p_this
, "invmem-width" );
128 p_sys
->i_height
= var_CreateGetInteger( p_this
, "invmem-height" );
129 if( p_sys
->i_width
== 0 || p_sys
->i_height
== 0 )
131 msg_Err( p_dec
, "--invmem-width and --invmem-height must be > 0" );
135 psz_tmp
= var_CreateGetString( p_dec
, "invmem-lock" );
136 p_sys
->pf_lock
= (void * (*) (void *))(intptr_t)atoll( psz_tmp
);
139 psz_tmp
= var_CreateGetString( p_dec
, "invmem-unlock" );
140 p_sys
->pf_unlock
= (void (*) (void *))(intptr_t)atoll( psz_tmp
);
143 psz_tmp
= var_CreateGetString( p_dec
, "invmem-data" );
144 p_sys
->p_data
= (void *)(intptr_t)atoll( psz_tmp
);
147 if( !p_sys
->pf_lock
|| !p_sys
->pf_unlock
)
149 msg_Err( p_dec
, "Invalid lock or unlock callbacks" );
153 if ( chromaStr
== NULL
)
155 msg_Err( p_dec
, "Invalid invmem-chroma string." );
158 const vlc_fourcc_t chroma
= vlc_fourcc_GetCodecFromString( VIDEO_ES
, chromaStr
);
162 msg_Err( p_dec
, "invmem-chroma should be 4 characters long." );
166 /* Set output properties */
169 case VLC_CODEC_RGB15
:
170 p_dec
->fmt_out
.video
.i_rmask
= 0x001f;
171 p_dec
->fmt_out
.video
.i_gmask
= 0x03e0;
172 p_dec
->fmt_out
.video
.i_bmask
= 0x7c00;
173 pitch
= p_sys
->i_width
* 2;
175 case VLC_CODEC_RGB16
:
176 p_dec
->fmt_out
.video
.i_rmask
= 0x001f;
177 p_dec
->fmt_out
.video
.i_gmask
= 0x07e0;
178 p_dec
->fmt_out
.video
.i_bmask
= 0xf800;
179 pitch
= p_sys
->i_width
* 2;
181 case VLC_CODEC_RGB24
:
182 p_dec
->fmt_out
.video
.i_rmask
= 0xff0000;
183 p_dec
->fmt_out
.video
.i_gmask
= 0x00ff00;
184 p_dec
->fmt_out
.video
.i_bmask
= 0x0000ff;
185 pitch
= p_sys
->i_width
* 3;
187 case VLC_CODEC_RGB32
:
188 p_dec
->fmt_out
.video
.i_rmask
= 0xff0000;
189 p_dec
->fmt_out
.video
.i_gmask
= 0x00ff00;
190 p_dec
->fmt_out
.video
.i_bmask
= 0x0000ff;
191 pitch
= p_sys
->i_width
* 4;
194 p_dec
->fmt_out
.video
.i_rmask
= 0;
195 p_dec
->fmt_out
.video
.i_gmask
= 0;
196 p_dec
->fmt_out
.video
.i_bmask
= 0;
198 msg_Warn( p_dec
, "Unknown chroma %s", chromaStr
);
204 p_dec
->fmt_out
.i_codec
= chroma
;
205 p_dec
->fmt_out
.video
.i_width
= p_dec
->p_sys
->i_width
;
206 p_dec
->fmt_out
.video
.i_height
= p_dec
->p_sys
->i_height
;
207 p_dec
->fmt_out
.video
.i_sar_num
= 1;
208 p_dec
->fmt_out
.video
.i_sar_den
= 1;
209 p_dec
->fmt_out
.i_cat
= VIDEO_ES
;
211 p_sys
->i_pitch
= pitch
;
214 p_dec
->pf_decode_video
= DecodeBlock
;
223 /****************************************************************************
224 * DecodeBlock: the whole thing
225 ****************************************************************************
226 * This function must be fed with a complete compressed frame.
227 ****************************************************************************/
228 static picture_t
*DecodeBlock( decoder_t
*p_dec
, block_t
**pp_block
)
230 decoder_sys_t
*p_sys
= p_dec
->p_sys
;
234 if( !pp_block
|| !*pp_block
) return NULL
;
238 // create new picture
239 p_pic
= decoder_NewPicture( p_dec
);
240 if ( !p_pic
) return NULL
;
241 p_pic
->b_force
= true;
242 p_pic
->p
->i_pitch
= p_dec
->p_sys
->i_pitch
;
243 p_pic
->date
= p_block
->i_pts
> VLC_TS_INVALID
? p_block
->i_pts
: p_block
->i_dts
;
245 // lock input and copy to picture
246 p_pic
->p
->p_pixels
= p_sys
->pf_lock( p_dec
->p_sys
->p_data
);
249 p_sys
->pf_unlock( p_dec
->p_sys
->p_data
);
251 block_Release( *pp_block
); *pp_block
= NULL
;
255 /*****************************************************************************
256 * CloseDecoder: invmem decoder destruction
257 *****************************************************************************/
258 static void CloseDecoder( vlc_object_t
*p_this
)
260 decoder_t
*p_dec
= (decoder_t
*)p_this
;
261 decoder_sys_t
*p_sys
= p_dec
->p_sys
;