Changeset fc16feb13f52733cfe8c1b1219b519158a4c19c3
- Timestamp:
- 10/02/07 19:26:35
(11 months ago)
- Author:
- Rémi Denis-Courmont <rem@videolan.org>
- git-committer:
- Rémi Denis-Courmont <rem@videolan.org> 1191345995 +0000
- git-parent:
[e3e9c13799fc03656fe36f9646b77030aff2626c]
- git-author:
- Rémi Denis-Courmont <rem@videolan.org> 1191345995 +0000
- Message:
- Heavily simplify the MPJPEG mux (closes #1188); please test.
- Remove configurable boundary that had never been working anyway (did not match the original value from MUX_GET_MIME)
-
Files:
-
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
| r1d6c495 |
rfc16feb |
|
| 31 | 31 | #include <vlc_codecs.h> |
|---|
| 32 | 32 | |
|---|
| 33 | | #define SEPARATOR_TEXT N_( "Multipart separator string" ) |
|---|
| 34 | | #define SEPARATOR_LONGTEXT N_( "Multipart strings like MPJPEG use a " \ |
|---|
| 35 | | "specific string to separate its content " \ |
|---|
| 36 | | "pieces. You can select this string. " \ |
|---|
| 37 | | "Default is --myboundary" ) |
|---|
| 38 | | |
|---|
| 39 | | |
|---|
| 40 | | #define CONTENT_TYPE "Content-Type: image/jpeg" |
|---|
| 41 | 33 | /***************************************************************************** |
|---|
| 42 | 34 | * Module descriptor |
|---|
| … | … | |
| 51 | 43 | set_description( _("Multipart JPEG muxer") ); |
|---|
| 52 | 44 | set_capability( "sout mux", 5 ); |
|---|
| 53 | | add_string( SOUT_CFG_PREFIX "separator", "--myboundary", NULL, |
|---|
| 54 | | SEPARATOR_TEXT, SEPARATOR_LONGTEXT, VLC_TRUE ); |
|---|
| | 45 | add_obsolete_string( SOUT_CFG_PREFIX "separator" ); |
|---|
| 55 | 46 | set_category( CAT_SOUT ); |
|---|
| 56 | 47 | set_subcategory( SUBCAT_SOUT_MUX ); |
|---|
| … | … | |
| 62 | 53 | * Exported prototypes |
|---|
| 63 | 54 | *****************************************************************************/ |
|---|
| 64 | | static const char *ppsz_sout_options[] = { "separator", NULL }; |
|---|
| 65 | | |
|---|
| 66 | 55 | static int Control ( sout_mux_t *, int, va_list ); |
|---|
| 67 | 56 | static int AddStream( sout_mux_t *, sout_input_t * ); |
|---|
| … | … | |
| 69 | 58 | static int Mux ( sout_mux_t * ); |
|---|
| 70 | 59 | |
|---|
| 71 | | struct sout_mux_sys_t |
|---|
| 72 | | { |
|---|
| 73 | | block_t *p_separator; |
|---|
| 74 | | vlc_bool_t b_send_headers; |
|---|
| 75 | | }; |
|---|
| | 60 | /* This pseudo-random sequence is unlikely to ever happen */ |
|---|
| | 61 | #define BOUNDARY "7b3cc56e5f51db803f790dad720ed50a" |
|---|
| 76 | 62 | |
|---|
| 77 | 63 | /***************************************************************************** |
|---|
| … | … | |
| 81 | 67 | { |
|---|
| 82 | 68 | sout_mux_t *p_mux = (sout_mux_t*)p_this; |
|---|
| 83 | | sout_mux_sys_t *p_sys; |
|---|
| 84 | | char *psz_separator_block, *psz_separator; |
|---|
| 85 | 69 | |
|---|
| 86 | 70 | msg_Dbg( p_mux, "Multipart jpeg muxer opened" ); |
|---|
| 87 | | psz_separator = var_GetNonEmptyString( p_mux, SOUT_CFG_PREFIX"separator" ); |
|---|
| 88 | | if( psz_separator == NULL ) |
|---|
| 89 | | { |
|---|
| 90 | | msg_Err( p_this, "missing required multipart separator" ); |
|---|
| 91 | | return VLC_EGENERIC; |
|---|
| 92 | | } |
|---|
| 93 | | |
|---|
| 94 | | config_ChainParse( p_mux, SOUT_CFG_PREFIX, ppsz_sout_options, |
|---|
| 95 | | p_mux->p_cfg ); |
|---|
| 96 | | |
|---|
| 97 | | p_sys = p_mux->p_sys = malloc( sizeof(sout_mux_sys_t) ); |
|---|
| 98 | | if( p_sys == NULL ) |
|---|
| 99 | | return VLC_ENOMEM; |
|---|
| 100 | | p_sys->b_send_headers = VLC_TRUE; |
|---|
| 101 | | |
|---|
| 102 | | if( asprintf( &psz_separator_block, "\r\n%s\r\n%s\r\n", psz_separator, |
|---|
| 103 | | CONTENT_TYPE ) == -1 ) |
|---|
| 104 | | psz_separator_block = NULL; |
|---|
| 105 | | free( psz_separator_block ); |
|---|
| 106 | | |
|---|
| 107 | | if( psz_separator_block == NULL ) |
|---|
| 108 | | { |
|---|
| 109 | | free( p_sys ); |
|---|
| 110 | | return VLC_ENOMEM; |
|---|
| 111 | | } |
|---|
| 112 | | |
|---|
| 113 | | p_sys->p_separator = block_New( p_mux, strlen( psz_separator_block ) ); |
|---|
| 114 | | strcpy( (char *)p_sys->p_separator->p_buffer, psz_separator_block ); |
|---|
| 115 | 71 | |
|---|
| 116 | 72 | p_mux->pf_control = Control; |
|---|
| … | … | |
| 118 | 74 | p_mux->pf_delstream = DelStream; |
|---|
| 119 | 75 | p_mux->pf_mux = Mux; |
|---|
| | 76 | p_mux->p_sys = NULL; |
|---|
| 120 | 77 | |
|---|
| 121 | 78 | return VLC_SUCCESS; |
|---|
| … | … | |
| 128 | 85 | static void Close( vlc_object_t * p_this ) |
|---|
| 129 | 86 | { |
|---|
| 130 | | sout_mux_t *p_mux = (sout_mux_t*)p_this; |
|---|
| 131 | | sout_mux_sys_t *p_sys = p_mux->p_sys; |
|---|
| 132 | | |
|---|
| 133 | | msg_Dbg( p_mux, "Multipart jpeg muxer closed" ); |
|---|
| 134 | | block_Release( p_sys->p_separator ); |
|---|
| 135 | | free( p_sys ); |
|---|
| | 87 | /* TODO: send the ending boundary ("\r\n--"BOUNDARY"--\r\n"), |
|---|
| | 88 | * but is the access_output still useable?? */ |
|---|
| | 89 | msg_Dbg( p_this, "Multipart jpeg muxer closed" ); |
|---|
| 136 | 90 | } |
|---|
| 137 | 91 | |
|---|
| … | … | |
| 155 | 109 | case MUX_GET_MIME: |
|---|
| 156 | 110 | ppsz = (char**)va_arg( args, char ** ); |
|---|
| 157 | | *ppsz = strdup( "multipart/x-mixed-replace; boundary=This Random String" ); |
|---|
| | 111 | *ppsz = strdup( "multipart/x-mixed-replace; boundary="BOUNDARY ); |
|---|
| 158 | 112 | return VLC_SUCCESS; |
|---|
| 159 | 113 | |
|---|
| … | … | |
| 195 | 149 | { |
|---|
| 196 | 150 | block_fifo_t *p_fifo; |
|---|
| 197 | | sout_mux_sys_t *p_sys = p_mux->p_sys; |
|---|
| 198 | | int i_count; |
|---|
| 199 | | /* Content-Length:.......\r\n */ |
|---|
| 200 | | char psz_content_length[25]; |
|---|
| 201 | | |
|---|
| 202 | | if( p_sys->b_send_headers ) |
|---|
| 203 | | { |
|---|
| 204 | | block_t *p_header; |
|---|
| 205 | | char *psz_separator = var_CreateGetString( p_mux, |
|---|
| 206 | | SOUT_CFG_PREFIX "separator" ); |
|---|
| 207 | | char *psz_separator_block = (char *)malloc( strlen( psz_separator ) + |
|---|
| 208 | | 2 + strlen( CONTENT_TYPE ) ); |
|---|
| 209 | | |
|---|
| 210 | | sprintf( psz_separator_block, "%s\r\n%s\r\n", psz_separator, |
|---|
| 211 | | CONTENT_TYPE ); |
|---|
| 212 | | |
|---|
| 213 | | p_header = block_New( p_mux, strlen( psz_separator_block ) ); |
|---|
| 214 | | memcpy( p_header->p_buffer, psz_separator_block , |
|---|
| 215 | | strlen( psz_separator_block ) ); |
|---|
| 216 | | p_header->i_flags |= BLOCK_FLAG_HEADER; |
|---|
| 217 | | sout_AccessOutWrite( p_mux->p_access, p_header ); |
|---|
| 218 | | p_sys->b_send_headers = VLC_FALSE; |
|---|
| 219 | | if( psz_separator_block ) free( psz_separator_block ); |
|---|
| 220 | | } |
|---|
| 221 | 151 | |
|---|
| 222 | 152 | if( !p_mux->i_nb_inputs ) return VLC_SUCCESS; |
|---|
| 223 | 153 | |
|---|
| 224 | 154 | p_fifo = p_mux->pp_inputs[0]->p_fifo; |
|---|
| 225 | | i_count = block_FifoCount( p_fifo ); |
|---|
| 226 | | while( i_count > 0 ) |
|---|
| | 155 | |
|---|
| | 156 | while( block_FifoCount( p_fifo ) > 0 ) |
|---|
| 227 | 157 | { |
|---|
| 228 | | block_t *p_length = block_New( p_mux, 25 ); |
|---|
| | 158 | static const char psz_hfmt[] = "\r\n" |
|---|
| | 159 | "--"BOUNDARY"\r\n" |
|---|
| | 160 | "Content-Type: image/jpeg\r\n" |
|---|
| | 161 | "Content-Length: %u\r\n" |
|---|
| | 162 | "\r\n"; |
|---|
| 229 | 163 | block_t *p_data = block_FifoGet( p_fifo ); |
|---|
| 230 | | sout_AccessOutWrite( p_mux->p_access, |
|---|
| 231 | | block_Duplicate( p_sys->p_separator ) ); |
|---|
| 232 | | memset( psz_content_length, 0, 25 ); |
|---|
| 233 | | snprintf( psz_content_length, 25, "Content-Length: %i\r\n\r\n", |
|---|
| 234 | | p_data->i_buffer ); |
|---|
| 235 | | memcpy( p_length->p_buffer, psz_content_length, 25 ); |
|---|
| 236 | | sout_AccessOutWrite( p_mux->p_access, p_length ); |
|---|
| | 164 | block_t *p_header = block_New( p_mux, sizeof( psz_hfmt ) + 20 ); |
|---|
| | 165 | |
|---|
| | 166 | if( p_header == NULL ) /* uho! */ |
|---|
| | 167 | { |
|---|
| | 168 | block_Release( p_data ); |
|---|
| | 169 | continue; |
|---|
| | 170 | } |
|---|
| | 171 | |
|---|
| | 172 | p_header->i_buffer = |
|---|
| | 173 | snprintf( (char *)p_header->p_buffer, p_header->i_buffer, |
|---|
| | 174 | psz_hfmt, p_data->i_buffer ); |
|---|
| | 175 | p_header->i_flags |= BLOCK_FLAG_HEADER; |
|---|
| | 176 | sout_AccessOutWrite( p_mux->p_access, p_header ); |
|---|
| 237 | 177 | sout_AccessOutWrite( p_mux->p_access, p_data ); |
|---|
| 238 | | |
|---|
| 239 | | i_count--; |
|---|
| 240 | 178 | } |
|---|
| 241 | 179 | |
|---|