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 INVMEM_HELP N_( "This module make possible making video stream from raw-image " \
71 "generating (to memory) from rendering program uses libvlc. " \
72 "To use this module from libvlc set --codec to invmem, "\
73 "set all --invmem-* options in vlc_argv an use " \
74 "libvlc_media_new(libvlc, \"fake://\", &ex);. " \
75 "Besides is simillar to vmem video output module." )
77 set_category( CAT_INPUT
);
78 set_subcategory( SUBCAT_INPUT_VCODEC
);
79 set_shortname( N_("Memory video decoder") );
80 set_description( N_("Memory video decoder") );
81 set_help( INVMEM_HELP
);
82 set_capability( "decoder", 50 );
83 set_callbacks( OpenDecoder
, CloseDecoder
);
84 add_shortcut( "invmem" );
86 add_integer( "invmem-width", "0", NULL
, T_WIDTH
, LT_WIDTH
, false );
87 add_integer( "invmem-height", "0", NULL
, T_HEIGHT
, LT_HEIGHT
, false );
88 add_string( "invmem-lock", "0", NULL
, T_LOCK
, LT_LOCK
, true );
89 add_string( "invmem-unlock", "0", NULL
, T_UNLOCK
, LT_UNLOCK
, true );
90 add_string( "invmem-data", "0", NULL
, T_DATA
, LT_DATA
, true );
96 void * (*pf_lock
) (void *);
97 void (*pf_unlock
) (void *);
108 /*****************************************************************************
109 * OpenDecoder: probe the decoder and return score
110 *****************************************************************************/
111 static int OpenDecoder( vlc_object_t
*p_this
)
113 decoder_t
*p_dec
= (decoder_t
*)p_this
;
114 decoder_sys_t
*p_sys
;
117 if( p_dec
->fmt_in
.i_codec
!= VLC_FOURCC('f','a','k','e'))
122 /* Allocate the memory needed to store the decoder's structure */
123 if( ( p_dec
->p_sys
= p_sys
=
124 (decoder_sys_t
*)malloc(sizeof(decoder_sys_t
)) ) == NULL
)
128 p_sys
->i_width
= var_CreateGetInteger( p_this
, "invmem-width" );
129 p_sys
->i_height
= var_CreateGetInteger( p_this
, "invmem-height" );
130 if (p_sys
->i_width
== 0 || p_sys
->i_height
== 0) {
131 msg_Err( p_dec
, "--vmem-width and --vmem-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 /* Set output properties */
154 p_dec
->fmt_out
.i_cat
= VIDEO_ES
;
155 //p_dec->fmt_out.i_codec = VLC_FOURCC('R','G','B','A');
156 p_dec
->fmt_out
.i_codec
= VLC_FOURCC('R','V','2','4');
157 p_dec
->fmt_out
.video
.i_width
= p_dec
->p_sys
->i_width
;
158 p_dec
->fmt_out
.video
.i_height
= p_dec
->p_sys
->i_height
;
159 p_dec
->fmt_out
.video
.i_aspect
= VOUT_ASPECT_FACTOR
* p_dec
->p_sys
->i_width
/ p_dec
->p_sys
->i_height
;
160 p_dec
->fmt_out
.video
.i_rmask
= 0xff0000;
161 p_dec
->fmt_out
.video
.i_gmask
= 0x00ff00;
162 p_dec
->fmt_out
.video
.i_bmask
= 0x0000ff;
163 p_dec
->fmt_out
.i_cat
= VIDEO_ES
;
165 p_sys
->i_pitch
= p_sys
->i_width
*3 + p_sys
->i_width
%4;
167 // create new picture
168 p_sys
->p_pic
= p_dec
->pf_vout_buffer_new( p_dec
);
171 p_dec
->pf_decode_video
= DecodeBlock
;
176 /****************************************************************************
177 * DecodeBlock: the whole thing
178 ****************************************************************************
179 * This function must be fed with a complete compressed frame.
180 ****************************************************************************/
181 static picture_t
*DecodeBlock( decoder_t
*p_dec
, block_t
**pp_block
)
183 decoder_sys_t
*p_sys
= p_dec
->p_sys
;
185 if( !pp_block
|| !*pp_block
) return NULL
;
187 // create new picture
188 picture_Release( p_sys
->p_pic
);
189 p_sys
->p_pic
= p_dec
->pf_vout_buffer_new( p_dec
);
190 p_sys
->p_pic
->b_force
= true;
191 p_sys
->p_pic
->p
->i_pitch
= p_dec
->p_sys
->i_pitch
;
193 // lock input and copy to picture
194 p_sys
->p_pic
->p
->p_pixels
= p_sys
->pf_lock( p_dec
->p_sys
->p_data
);
197 p_sys
->pf_unlock( p_dec
->p_sys
->p_data
);
199 block_Release( *pp_block
); *pp_block
= NULL
;
203 /*****************************************************************************
204 * CloseDecoder: invmem decoder destruction
205 *****************************************************************************/
206 static void CloseDecoder( vlc_object_t
*p_this
)
208 decoder_t
*p_dec
= (decoder_t
*)p_this
;
209 decoder_sys_t
*p_sys
= p_dec
->p_sys
;