From: Tristan Matthews Date: Sat, 31 Jan 2015 16:46:33 +0000 (+0000) Subject: Add encoder for YCbCr 4:2:0 over RTP (RFC 4175) X-Git-Url: https://git.sesse.net/?a=commitdiff_plain;h=095bb638696ddb435232bc6a4401585d6b4eac3c;p=vlc Add encoder for YCbCr 4:2:0 over RTP (RFC 4175) --- diff --git a/include/vlc_fourcc.h b/include/vlc_fourcc.h index 5f4f8f9119..fd677979c2 100644 --- a/include/vlc_fourcc.h +++ b/include/vlc_fourcc.h @@ -275,6 +275,8 @@ #define VLC_CODEC_CYUV VLC_FOURCC('c','y','u','v') /* 10-bit 4:2:2 Component YCbCr */ #define VLC_CODEC_V210 VLC_FOURCC('v','2','1','0') +/* I420 packed for RTP (RFC 4175) */ +#define VLC_CODEC_R420 VLC_FOURCC('r','4','2','0') /* RGB */ diff --git a/modules/codec/Makefile.am b/modules/codec/Makefile.am index ebdbf78136..0de32a02aa 100644 --- a/modules/codec/Makefile.am +++ b/modules/codec/Makefile.am @@ -99,6 +99,12 @@ codec_LTLIBRARIES += $(LTLIBlibmpeg2) librawvideo_plugin_la_SOURCES = codec/rawvideo.c codec_LTLIBRARIES += librawvideo_plugin.la +librtpvideo_plugin_la_SOURCES = codec/rtpvideo.c +if ENABLE_SOUT +codec_LTLIBRARIES += librtpvideo_plugin.la +endif + + libschroedinger_plugin_la_SOURCES = codec/schroedinger.c libschroedinger_plugin_la_CFLAGS = $(AM_CFLAGS) $(CFLAGS_schroedinger) libschroedinger_plugin_la_LDFLAGS = $(AM_LDFLAGS) -rpath '$(codecdir)' diff --git a/modules/codec/rtpvideo.c b/modules/codec/rtpvideo.c new file mode 100644 index 0000000000..e3fdd7ba9b --- /dev/null +++ b/modules/codec/rtpvideo.c @@ -0,0 +1,108 @@ +/***************************************************************************** + * rtpvideo.c: video encoder for raw video for RTP (see RFC 4175) + ***************************************************************************** + * Copyright (C) 2015 VLC authors and VideoLAN + * $Id$ + * + * Authors: Tristan Matthews + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 2.1 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA. + *****************************************************************************/ + +/***************************************************************************** + * Preamble + *****************************************************************************/ +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include +#include +#include + +/**************************************************************************** + * Local prototypes + ****************************************************************************/ +static int OpenEncoder( vlc_object_t * ); +static block_t *Encode( encoder_t *p_enc, picture_t *p_pict ); + +/***************************************************************************** + * Module descriptor + *****************************************************************************/ +vlc_module_begin () + set_description( N_("Raw video encoder for RTP") ) + set_capability( "encoder", 50 ) + set_category( CAT_INPUT ) + set_subcategory( SUBCAT_INPUT_VCODEC ) + set_callbacks( OpenEncoder, NULL ) + add_shortcut( "rtpvideo" ) +vlc_module_end () + +static int OpenEncoder( vlc_object_t *p_this ) +{ + encoder_t *p_enc = (encoder_t *)p_this; + if( p_enc->fmt_out.i_codec != VLC_CODEC_R420 && !p_enc->b_force ) + return VLC_EGENERIC; + + p_enc->pf_encode_video = Encode; + p_enc->fmt_in.i_codec = VLC_CODEC_I420; + p_enc->fmt_out.i_codec = VLC_CODEC_R420; + + return VLC_SUCCESS; +} + +static block_t *Encode( encoder_t *p_enc, picture_t *p_pict ) +{ + VLC_UNUSED( p_enc ); + if( !p_pict ) return NULL; + + const int i_length = p_pict->p[0].i_visible_lines * p_pict->p[0].i_visible_pitch + + p_pict->p[1].i_visible_lines * p_pict->p[1].i_visible_pitch + + p_pict->p[2].i_visible_lines * p_pict->p[2].i_visible_pitch; + + block_t *p_block = block_Alloc( i_length ); + if( !p_block ) return NULL; + + p_block->i_dts = p_block->i_pts = p_pict->date; + uint8_t *p_outdata = p_block->p_buffer; + const int i_xdec = 2; + const int i_ydec = 2; + + const uint8_t *p_yd1 = p_pict->p[0].p_pixels; + const uint8_t *p_u = p_pict->p[1].p_pixels; + const uint8_t *p_v = p_pict->p[2].p_pixels; + + /* Y00-Y01-Y10-Y11-U00-V00...luma from adjacent lines */ + for( int i_lin = 0; i_lin < p_pict->p[0].i_visible_lines; i_lin += i_ydec ) + { + const uint8_t *p_yd2 = p_yd1 + p_pict->p[0].i_pitch; + for ( int i_pix = 0; i_pix < p_pict->p[0].i_visible_pitch; i_pix += i_xdec ) + { + *p_outdata++ = *p_yd1++; + *p_outdata++ = *p_yd1++; + *p_outdata++ = *p_yd2++; + *p_outdata++ = *p_yd2++; + *p_outdata++ = *p_u++; + *p_outdata++ = *p_v++; + } + /* Skip a line + padding */ + p_yd1 += p_pict->p[0].i_pitch + + (p_pict->p[0].i_pitch - p_pict->p[0].i_visible_pitch); + p_u += p_pict->p[1].i_pitch - p_pict->p[1].i_visible_pitch; + p_v += p_pict->p[2].i_pitch - p_pict->p[2].i_visible_pitch; + } + + return p_block; +}