[vlc-commits] mux: avi: fix RGB muxing
Francois Cartegnie
git at videolan.org
Tue Aug 14 15:56:13 CEST 2018
vlc | branch: master | Francois Cartegnie <fcvlcdev at free.fr> | Tue Aug 14 14:28:01 2018 +0200| [83c1c178fd40c2384551bf903f39d8c446e3fb6d] | committer: Francois Cartegnie
mux: avi: fix RGB muxing
> http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=83c1c178fd40c2384551bf903f39d8c446e3fb6d
---
modules/mux/Makefile.am | 2 +-
modules/mux/avi.c | 115 ++++++++++++++++++++++++++----------------------
2 files changed, 63 insertions(+), 54 deletions(-)
diff --git a/modules/mux/Makefile.am b/modules/mux/Makefile.am
index b4318e2d9a..8b3c29df34 100644
--- a/modules/mux/Makefile.am
+++ b/modules/mux/Makefile.am
@@ -3,7 +3,7 @@ muxdir = $(pluginsdir)/mux
libmux_dummy_plugin_la_SOURCES = mux/dummy.c
libmux_asf_plugin_la_SOURCES = mux/asf.c demux/asf/libasf_guid.h
-libmux_avi_plugin_la_SOURCES = mux/avi.c
+libmux_avi_plugin_la_SOURCES = mux/avi.c demux/avi/bitmapinfoheader.h
libmux_mp4_plugin_la_SOURCES = mux/mp4/mp4.c \
mux/mp4/libmp4mux.c mux/mp4/libmp4mux.h \
demux/mp4/libmp4.h \
diff --git a/modules/mux/avi.c b/modules/mux/avi.c
index 5b910be774..9f6000e3ac 100644
--- a/modules/mux/avi.c
+++ b/modules/mux/avi.c
@@ -37,6 +37,7 @@
#include <vlc_block.h>
#include <vlc_codecs.h>
#include <vlc_boxes.h>
+#include "../demux/avi/bitmapinfoheader.h"
/*****************************************************************************
* Module descriptor
@@ -102,6 +103,7 @@ typedef struct avi_stream_s
int i_bitrate;
VLC_BITMAPINFOHEADER *p_bih;
+ size_t i_bih;
WAVEFORMATEX *p_wf;
} avi_stream_t;
@@ -323,6 +325,7 @@ static int AddStream( sout_mux_t *p_mux, sout_input_t *p_input )
p_stream->fcc[3] = 'b';
p_stream->p_bih = NULL;
+ p_stream->i_bih = 0;
WAVEFORMATEX *p_wf = malloc( sizeof( WAVEFORMATEX ) +
p_input->p_fmt->i_extra );
@@ -422,42 +425,13 @@ static int AddStream( sout_mux_t *p_mux, sout_input_t *p_input )
p_sys->i_stream_video = p_sys->i_streams;
}
p_stream->p_wf = NULL;
- VLC_BITMAPINFOHEADER *p_bih = malloc( sizeof( VLC_BITMAPINFOHEADER ) +
- p_input->p_fmt->i_extra );
- if( !p_bih )
+ p_stream->p_bih = CreateBitmapInfoHeader( &p_input->fmt, &p_stream->i_bih );
+ if( !p_stream->p_bih )
{
free( p_input->p_sys );
p_input->p_sys = NULL;
return VLC_ENOMEM;
}
-
- p_bih->biSize = sizeof( VLC_BITMAPINFOHEADER ) +
- p_input->p_fmt->i_extra;
- if( p_input->p_fmt->i_extra > 0 )
- {
- memcpy( &p_bih[1],
- p_input->p_fmt->p_extra,
- p_input->p_fmt->i_extra );
- }
- p_bih->biWidth = p_input->p_fmt->video.i_width;
- p_bih->biHeight= p_input->p_fmt->video.i_height;
- p_bih->biPlanes= 1;
- p_bih->biBitCount = 24;
- p_bih->biSizeImage = 0;
- p_bih->biXPelsPerMeter = 0;
- p_bih->biYPelsPerMeter = 0;
- p_bih->biClrUsed = 0;
- p_bih->biClrImportant = 0;
- switch( p_input->p_fmt->i_codec )
- {
- case VLC_CODEC_MP4V:
- p_bih->biCompression = VLC_FOURCC( 'X', 'V', 'I', 'D' );
- break;
- default:
- p_bih->biCompression = p_input->p_fmt->i_original_fourcc ?: p_input->p_fmt->i_codec;
- break;
- }
- p_stream->p_bih = p_bih;
break;
default:
free( p_input->p_sys );
@@ -483,6 +457,48 @@ static void DelStream( sout_mux_t *p_mux, sout_input_t *p_input )
free( p_input->p_sys );
}
+static int PrepareSamples( const avi_stream_t *p_stream,
+ const es_format_t *p_fmt,
+ block_t **pp_block )
+{
+ if( p_stream->i_frames == 0 && p_stream->i_cat == VIDEO_ES )
+ {
+ /* Add header present at the end of BITMAP info header
+ to first frame in case of XVID */
+ if( p_stream->p_bih->biCompression == VLC_FOURCC( 'X', 'V', 'I', 'D' ) )
+ {
+ size_t i_header_length =
+ p_stream->p_bih->biSize - sizeof(VLC_BITMAPINFOHEADER);
+ *pp_block = block_Realloc( *pp_block, i_header_length,
+ (*pp_block)->i_buffer );
+ if( !*pp_block )
+ return VLC_ENOMEM;
+ memcpy((*pp_block)->p_buffer,&p_stream->p_bih[1], i_header_length);
+ }
+ }
+
+ /* RV24 is only BGR in AVI, and we can't use BI_BITFIELD */
+ if( p_stream->i_cat == VIDEO_ES &&
+ p_stream->p_bih->biCompression == BI_RGB &&
+ p_stream->p_bih->biBitCount == 24 &&
+ (p_fmt->video.i_bmask != 0xFF0000 ||
+ p_fmt->video.i_rmask != 0x0000FF) )
+ {
+ uint8_t *p_data = (*pp_block)->p_buffer;
+ for( size_t i=0; i<(*pp_block)->i_buffer / 3; i++ )
+ {
+ uint8_t *p = &p_data[i*3];
+ /* reorder as BGR using shift value (done by FixRGB) */
+ uint32_t v = (p[0] << 16) | (p[1] << 8) | p[2];
+ p[0] = (v & p_fmt->video.i_bmask) >> p_fmt->video.i_lbshift;
+ p[1] = (v & p_fmt->video.i_gmask) >> p_fmt->video.i_lgshift;
+ p[2] = (v & p_fmt->video.i_rmask) >> p_fmt->video.i_lrshift;
+ }
+ }
+
+ return VLC_SUCCESS;
+}
+
static int Mux ( sout_mux_t *p_mux )
{
sout_mux_sys_t *p_sys = p_mux->p_sys;
@@ -526,22 +542,11 @@ static int Mux ( sout_mux_t *p_mux )
p_data->i_length = p_next->i_dts - p_data->i_dts;
}
-
- if( p_stream->i_frames == 0 &&p_stream->i_cat == VIDEO_ES )
+ if( PrepareSamples( p_stream, &p_mux->pp_inputs[i]->fmt,
+ &p_data ) != VLC_SUCCESS )
{
- /* Add header present at the end of BITMAP info header
- to first frame in case of XVID */
- if( p_stream->p_bih->biCompression
- == VLC_FOURCC( 'X', 'V', 'I', 'D' ) )
- {
- int i_header_length =
- p_stream->p_bih->biSize - sizeof(VLC_BITMAPINFOHEADER);
- p_data = block_Realloc( p_data,
- i_header_length, p_data->i_buffer );
- if( !p_data)
- return VLC_ENOMEM;
- memcpy(p_data->p_buffer,&p_stream->p_bih[1], i_header_length);
- }
+ i_count--;
+ continue;
}
p_stream->i_frames++;
@@ -700,7 +705,14 @@ static int avi_HeaderAdd_strh( bo_t *p_bo, avi_stream_t *p_stream )
case VIDEO_ES:
{
bo_add_fourcc( p_bo, "vids" );
+ if( p_stream->p_bih->biBitCount )
+ bo_add_fourcc( p_bo, "DIB " );
+ else
+#ifdef WORDS_BIGENDIAN
bo_add_32be( p_bo, p_stream->p_bih->biCompression );
+#else
+ bo_add_32le( p_bo, p_stream->p_bih->biCompression );
+#endif
bo_add_32le( p_bo, 0 ); /* flags */
bo_add_16le( p_bo, 0 ); /* priority */
bo_add_16le( p_bo, 0 ); /* langage */
@@ -780,21 +792,18 @@ static int avi_HeaderAdd_strf( bo_t *p_bo, avi_stream_t *p_stream )
bo_add_32le( p_bo, p_stream->p_bih->biHeight );
bo_add_16le( p_bo, p_stream->p_bih->biPlanes );
bo_add_16le( p_bo, p_stream->p_bih->biBitCount );
- if( VLC_FOURCC( 0, 0, 0, 1 ) == 0x00000001 )
- {
+#ifdef WORDS_BIGENDIAN
bo_add_32be( p_bo, p_stream->p_bih->biCompression );
- }
- else
- {
+#else
bo_add_32le( p_bo, p_stream->p_bih->biCompression );
- }
+#endif
bo_add_32le( p_bo, p_stream->p_bih->biSizeImage );
bo_add_32le( p_bo, p_stream->p_bih->biXPelsPerMeter );
bo_add_32le( p_bo, p_stream->p_bih->biYPelsPerMeter );
bo_add_32le( p_bo, p_stream->p_bih->biClrUsed );
bo_add_32le( p_bo, p_stream->p_bih->biClrImportant );
bo_add_mem( p_bo,
- p_stream->p_bih->biSize - sizeof( VLC_BITMAPINFOHEADER ),
+ p_stream->i_bih - sizeof( VLC_BITMAPINFOHEADER ),
(uint8_t*)&p_stream->p_bih[1] );
break;
}
More information about the vlc-commits
mailing list