Commit a0f65bae authored by François Cartegnie's avatar François Cartegnie 🤞

packetizer: add hxxx_nal.h for avc/hevc rbsp conversions

parent 9b748033
......@@ -166,7 +166,8 @@ demux_LTLIBRARIES += libes_plugin.la
libh264_plugin_la_SOURCES = demux/mpeg/h264.c
demux_LTLIBRARIES += libh264_plugin.la
libhevc_plugin_la_SOURCES = demux/mpeg/hevc.c demux/mpeg/mpeg_parser_helpers.h
libhevc_plugin_la_SOURCES = demux/mpeg/hevc.c demux/mpeg/mpeg_parser_helpers.h \
packetizer/hxxx_nal.h
demux_LTLIBRARIES += libhevc_plugin.la
libmkv_plugin_la_SOURCES = \
......
......@@ -36,6 +36,7 @@
#include <vlc_bits.h>
#include "mpeg_parser_helpers.h"
#include "../packetizer/hxxx_nal.h"
/*****************************************************************************
* Module descriptor
......@@ -223,32 +224,19 @@ static int Control( demux_t *p_demux, int i_query, va_list args )
0, 1, i_query, args );
}
static uint8_t * CreateDecodedNAL( int *pi_ret,
const uint8_t *src, int i_src )
{
uint8_t *dst = malloc( i_src );
if( !dst )
return NULL;
*pi_ret = nal_to_rbsp( src, dst, i_src );
return dst;
}
static int32_t getFPS( demux_t *p_demux, block_t * p_block )
{
demux_sys_t *p_sys = p_demux->p_sys;
bs_t bs;
uint8_t * p_decoded_nal;
int i_decoded_nal;
size_t i_decoded_nal;
if( p_block->i_buffer < 5 )
return -1;
p_decoded_nal = CreateDecodedNAL(&i_decoded_nal,
p_block->p_buffer+4, p_block->i_buffer-4);
p_decoded_nal = hxxx_ep3b_to_rbsp(p_block->p_buffer+4, p_block->i_buffer-4,
&i_decoded_nal);
if( !p_decoded_nal )
return -1;
......
......@@ -51,21 +51,4 @@ static inline void hevc_skip_profile_tiers_level( bs_t * bs, int32_t max_sub_lay
}
}
/* Discards emulation prevention three bytes */
static inline size_t nal_to_rbsp(const uint8_t * p_src, uint8_t * p_dst, size_t i_size)
{
size_t j = 0;
for (size_t i = 0; i < i_size; i++) {
if (i < i_size - 3 &&
p_src[i] == 0 && p_src[i+1] == 0 && p_src[i+2] == 3) {
p_dst[j++] = 0;
p_dst[j++] = 0;
i += 2;
continue;
}
p_dst[j++] = p_src[i];
}
return j;
}
#endif /*MPEG_PARSER_HELPERS_H*/
......@@ -6,7 +6,7 @@ libmux_asf_plugin_la_SOURCES = mux/asf.c demux/asf/libasf_guid.h
libmux_avi_plugin_la_SOURCES = mux/avi.c
libmux_mp4_plugin_la_SOURCES = mux/mp4/mp4.c \
mux/mp4/libmp4mux.c mux/mp4/libmp4mux.h \
demux/mpeg/mpeg_parser_helpers.h demux/mp4/libmp4.h \
packetizer/hxxx_nal.h demux/mp4/libmp4.h \
packetizer/h264_nal.c packetizer/h264_nal.h
libmux_mpjpeg_plugin_la_SOURCES = mux/mpjpeg.c
libmux_ps_plugin_la_SOURCES = \
......
......@@ -22,8 +22,8 @@
*****************************************************************************/
#include "libmp4mux.h"
#include "../demux/mp4/libmp4.h" /* flags */
#include "../demux/mpeg/mpeg_parser_helpers.h" /* nal rbsp */
#include "../packetizer/h264_nal.h" /* h264_get_spspps */
#include "../packetizer/hxxx_nal.h"
#ifdef HAVE_CONFIG_H
# include "config.h"
......@@ -496,10 +496,13 @@ static bo_t *GetD263Tag(void)
static void hevcParseVPS(uint8_t * p_buffer, size_t i_buffer, uint8_t *general,
uint8_t * numTemporalLayer, bool * temporalIdNested)
{
const size_t i_decoded_nal_size = 512;
uint8_t p_dec_nal[i_decoded_nal_size];
size_t i_size = (i_buffer < i_decoded_nal_size)?i_buffer:i_decoded_nal_size;
nal_to_rbsp(p_buffer, p_dec_nal, i_size);
size_t i_decoded_nal_size;
uint8_t *p_dec_nal = hxxx_ep3b_to_rbsp(p_buffer, i_buffer, &i_decoded_nal_size);
if(!p_dec_nal || i_decoded_nal_size < 19)
{
free(p_dec_nal);
return;
}
/* first two bytes are the NAL header, 3rd and 4th are:
vps_video_parameter_set_id(4)
......@@ -514,17 +517,22 @@ static void hevcParseVPS(uint8_t * p_buffer, size_t i_buffer, uint8_t *general,
/* 5th & 6th are reserved 0xffff */
/* copy the first 12 bytes of profile tier */
memcpy(general, &p_dec_nal[6], 12);
free(p_dec_nal);
}
static void hevcParseSPS(uint8_t * p_buffer, size_t i_buffer, uint8_t * chroma_idc,
uint8_t *bit_depth_luma_minus8, uint8_t *bit_depth_chroma_minus8)
{
const size_t i_decoded_nal_size = 512;
uint8_t p_dec_nal[i_decoded_nal_size];
size_t i_size = (i_buffer < i_decoded_nal_size)?i_buffer-2:i_decoded_nal_size;
nal_to_rbsp(p_buffer+2, p_dec_nal, i_size);
if(i_buffer < 2)
return;
size_t i_decoded_nal_size;
uint8_t *p_dec_nal = hxxx_ep3b_to_rbsp(p_buffer + 2, i_buffer - 2, &i_decoded_nal_size);
if(!p_dec_nal)
return;
bs_t bs;
bs_init(&bs, p_dec_nal, i_size);
bs_init(&bs, p_dec_nal, i_decoded_nal_size);
/* skip vps id */
bs_skip(&bs, 4);
......@@ -556,6 +564,8 @@ static void hevcParseSPS(uint8_t * p_buffer, size_t i_buffer, uint8_t * chroma_i
}
*bit_depth_luma_minus8 = bs_read_ue(&bs);
*bit_depth_chroma_minus8 = bs_read_ue(&bs);
free(p_dec_nal);
}
static bo_t *GetHvcCTag(es_format_t *p_fmt)
......
......@@ -6,13 +6,13 @@ libpacketizer_mpeg4video_plugin_la_SOURCES = packetizer/mpeg4video.c
libpacketizer_mpeg4audio_plugin_la_SOURCES = packetizer/mpeg4audio.c
libpacketizer_h264_plugin_la_SOURCES = \
packetizer/h264_nal.c packetizer/h264_nal.h \
packetizer/h264.c
packetizer/h264.c packetizer/hxxx_nal.h
libpacketizer_vc1_plugin_la_SOURCES = packetizer/vc1.c
libpacketizer_mlp_plugin_la_SOURCES = packetizer/mlp.c
libpacketizer_dirac_plugin_la_SOURCES = packetizer/dirac.c
libpacketizer_flac_plugin_la_SOURCES = packetizer/flac.c
libpacketizer_hevc_plugin_la_SOURCES = packetizer/hevc.c \
packetizer/hevc_nal.h
packetizer/hevc_nal.h packetizer/hxxx_nal.h
libpacketizer_avparser_plugin_la_SOURCES = packetizer/avparser.c \
packetizer/avparser.h \
......
......@@ -42,6 +42,7 @@
#include <vlc_bits.h>
#include "../codec/cc.h"
#include "h264_nal.h"
#include "hxxx_nal.h"
#include "packetizer_helper.h"
/*****************************************************************************
......@@ -161,7 +162,7 @@ static block_t *CreateAnnexbNAL( decoder_t *, const uint8_t *p, int );
static block_t *OutputPicture( decoder_t *p_dec );
static void PutSPS( decoder_t *p_dec, block_t *p_frag );
static void PutPPS( decoder_t *p_dec, block_t *p_frag );
static void ParseSlice( decoder_t *p_dec, bool *pb_new_picture, slice_t *p_slice,
static bool ParseSlice( decoder_t *p_dec, bool *pb_new_picture, slice_t *p_slice,
int i_nal_ref_idc, int i_nal_type, const block_t *p_frag );
static void ParseSei( decoder_t *, block_t * );
......@@ -601,15 +602,16 @@ static block_t *ParseNALBlock( decoder_t *p_dec, bool *pb_ts_used, block_t *p_fr
slice_t slice;
bool b_new_picture;
ParseSlice( p_dec, &b_new_picture, &slice, i_nal_ref_idc, i_nal_type, p_frag );
/* */
if( b_new_picture && p_sys->b_slice )
p_pic = OutputPicture( p_dec );
if(ParseSlice( p_dec, &b_new_picture, &slice, i_nal_ref_idc, i_nal_type, p_frag ))
{
/* */
if( b_new_picture && p_sys->b_slice )
p_pic = OutputPicture( p_dec );
/* */
p_sys->slice = slice;
p_sys->b_slice = true;
/* */
p_sys->slice = slice;
p_sys->b_slice = true;
}
}
else if( i_nal_type == H264_NAL_SPS )
{
......@@ -891,7 +893,7 @@ static void PutPPS( decoder_t *p_dec, block_t *p_frag )
p_sys->pp_pps[pps.i_id] = p_frag;
}
static void ParseSlice( decoder_t *p_dec, bool *pb_new_picture, slice_t *p_slice,
static bool ParseSlice( decoder_t *p_dec, bool *pb_new_picture, slice_t *p_slice,
int i_nal_ref_idc, int i_nal_type, const block_t *p_frag )
{
decoder_sys_t *p_sys = p_dec->p_sys;
......@@ -901,9 +903,14 @@ static void ParseSlice( decoder_t *p_dec, bool *pb_new_picture, slice_t *p_slice
slice_t slice;
bs_t s;
if(p_frag->i_buffer < 6)
return false;
/* do not convert the whole frame */
CreateRbspFromNAL( &pb_dec, &i_dec, &p_frag->p_buffer[5],
__MIN( p_frag->i_buffer - 5, 60 ) );
pb_dec = hxxx_ep3b_to_rbsp(&p_frag->p_buffer[5], __MIN( p_frag->i_buffer - 5, 60 ), &i_dec);
if(!pb_dec)
return false;
bs_init( &s, pb_dec, i_dec );
/* first_mb_in_slice */
......@@ -999,6 +1006,8 @@ static void ParseSlice( decoder_t *p_dec, bool *pb_new_picture, slice_t *p_slice
/* */
*pb_new_picture = b_pic;
*p_slice = slice;
return true;
}
static void ParseSei( decoder_t *p_dec, block_t *p_frag )
......@@ -1007,8 +1016,11 @@ static void ParseSei( decoder_t *p_dec, block_t *p_frag )
uint8_t *pb_dec;
size_t i_dec = 0;
if( p_frag->i_buffer < 6 )
return;
/* */
CreateRbspFromNAL( &pb_dec, &i_dec, &p_frag->p_buffer[5], p_frag->i_buffer - 5 );
pb_dec = hxxx_ep3b_to_rbsp( &p_frag->p_buffer[5], p_frag->i_buffer - 5, &i_dec );
if( !pb_dec )
return;
......
......@@ -19,6 +19,7 @@
*****************************************************************************/
#include "h264_nal.h"
#include "hxxx_nal.h"
#include <vlc_boxes.h>
#include <limits.h>
......@@ -425,8 +426,7 @@ int h264_parse_sps( const uint8_t *p_sps_buf, int i_sps_size,
return -1;
memset( p_sps, 0, sizeof(struct h264_nal_sps) );
CreateRbspFromNAL( &pb_dec, &i_dec, &p_sps_buf[5],
i_sps_size - 5 );
pb_dec = hxxx_ep3b_to_rbsp( &p_sps_buf[5], i_sps_size - 5, &i_dec );
if( !pb_dec )
return -1;
......
......@@ -107,17 +107,6 @@ struct h264_nal_pps
int i_pic_order_present_flag;
};
static inline void CreateRbspFromNAL( uint8_t **pp_ret, size_t *pi_ret,
const uint8_t *src, int i_src )
{
uint8_t *dst = malloc( i_src );
*pp_ret = dst;
if( dst )
*pi_ret = nal_to_rbsp(src, dst, i_src);
}
/*
AnnexB : [\x00] \x00 \x00 \x01 Prefixed NAL
AVC Sample format : NalLengthSize encoded size prefixed NAL
......
/*****************************************************************************
* hxxx_nal.h: Common helpers for AVC/HEVC NALU
*****************************************************************************
* Copyright (C) 2014-2015 VLC authors and VideoLAN
*
* 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.
*****************************************************************************/
#ifndef HXXX_NAL_H
#define HXXX_NAL_H
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include <vlc_common.h>
/* Discards emulation prevention three bytes */
static inline uint8_t * hxxx_ep3b_to_rbsp(const uint8_t *p_src, size_t i_src, size_t *pi_ret)
{
uint8_t *p_dst;
if(!p_src || !(p_dst = malloc(i_src)))
return NULL;
size_t j = 0;
for (size_t i = 0; i < i_src; i++) {
if (i < i_src - 3 &&
p_src[i] == 0 && p_src[i+1] == 0 && p_src[i+2] == 3) {
p_dst[j++] = 0;
p_dst[j++] = 0;
i += 2;
continue;
}
p_dst[j++] = p_src[i];
}
*pi_ret = j;
return p_dst;
}
#endif // HXXX_NAL_H
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment