Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
  • videolan/vlc
  • chouquette/vlc
  • bakiewicz.marek122/vlc
  • devnexen/vlc
  • rohanrajpal/vlc
  • blurrrb/vlc
  • gsoc/gsoc2019/darkapex/vlc
  • b1ue/vlc
  • fkuehne/vlc
  • magsoft/vlc
  • chub/vlc
  • cramiro9/vlc
  • robUx4/vlc
  • rom1v/vlc
  • akshayaky/vlc
  • tmk907/vlc
  • akymaster/vlc
  • govind.sharma/vlc
  • psilokos/vlc
  • xjbeta/vlc
  • jahan/vlc
  • 1480c1/vlc
  • amanchande/vlc
  • aaqib/vlc
  • rist/vlc
  • apol/vlc
  • mindfreeze/vlc
  • alexandre-janniaux/vlc
  • sandsmark/vlc
  • jagannatharjun/vlc
  • gsoc/gsoc2020/matiaslgonzalez/vlc
  • gsoc/gsoc2020/jagannatharjun/vlc
  • mstorsjo/vlc
  • gsoc/gsoc2020/vedenta/vlc
  • gsoc/gsoc2020/arnav-ishaan/vlc
  • gsoc/gsoc2020/andreduong/vlc
  • fuzun/vlc
  • gsoc/gsoc2020/vatsin/vlc
  • gsoc/gsoc2020/sagid/vlc
  • yaron/vlc
  • Phoenix/vlc
  • Garf/vlc
  • ePiratWorkarounds/vlc
  • tguillem/vlc
  • jnqnfe/vlc
  • mdc/vlc
  • Vedaa/vlc
  • rasa/vlc
  • quink/vlc
  • yealo/vlc
  • aleksey_ak/vlc
  • ePirat/vlc
  • ilya.yanok/vlc
  • asenat/vlc
  • m/vlc
  • bunjee/vlc
  • BLumia/vlc
  • sagudev/vlc
  • hamedmonji30/vlc
  • nullgemm/vlc
  • DivyamAhuja/vlc
  • thesamesam/vlc
  • dag7/vlc
  • snehil101/vlc
  • haasn/vlc
  • jbk/vlc
  • ValZapod/vlc
  • mfkl/vlc
  • WangChuan/vlc
  • core1024/vlc
  • GhostVaibhav/vlc
  • dfuhrmann/vlc
  • davide.prade/vlc
  • tmatth/vlc
  • Courmisch/vlc
  • zouya/vlc
  • hpi/vlc
  • EwoutH/vlc
  • aleung27/vlc
  • hengwu0/vlc
  • saladin/vlc
  • ashuio/vlc
  • richselwood/vlc
  • verma16Ayush/vlc
  • chemicalflash/vlc
  • PoignardAzur/vlc
  • huangjieNT/vlc
  • Blake-Haydon/vlc
  • AnuthaDev/vlc
  • gsoc/gsoc2021/mpd/vlc
  • nicolas_lequec/vlc
  • sambassaly/vlc
  • thresh/vlc
  • bonniegong/vlc
  • myaashish/vlc
  • stavros.vagionitis/vlc
  • ileoo/vlc
  • louis-santucci/vlc
  • cchristiansen/vlc
  • sabyasachi07/vlc
  • AbduAmeen/vlc
  • ashishb0410/vlc
  • urbanhusky/vlc
  • davidepietrasanta/vlc
  • riksleutelstad/vlc
  • jeremyVignelles/vlc
  • komh/vlc
  • iamjithinjohn/vlc
  • JohannesKauffmann/vlc2
  • kunglao/vlc
  • natzberg/vlc
  • jill/vlc
  • cwendling/vlc
  • adufou/vlc
  • ErwanAirone/vlc
  • HasinduDilshan10/vlc
  • vagrantc/vlc
  • rafiv/macos-bigsur-icon
  • Aymeriic/vlc
  • saranshg20/vlc
  • metzlove24/vlc
  • linkfanel/vlc
  • Ds886/vlc
  • metehan-arslan/vlc
  • Skantes/vlc
  • kgsandundananjaya96/vlc
  • mitchcapper/vlc
  • advaitgupta/vlc
  • StefanBruens/vlc
  • ratajs/vlc
  • T.M.F.B.3761/vlc
  • m222059/vlc
  • casemerrick/vlc
  • joshuaword2alt/vlc
  • sjwaddy/vlc
  • dima/vlc
  • Ybalrid/vlc
  • umxprime/vlc
  • eschmidt/vlc
  • vannieuwenhuysenmichelle/vlc
  • badcf00d/vlc
  • wesinator/vlc
  • louis/vlc
  • xqq/vlc
  • EmperorYP7/vlc
  • NicoLiam/vlc
  • loveleen/vlc
  • rofferom/vlc
  • rbultje/vlc
  • TheUnamed/vlc
  • pratiksharma341/vlc
  • Saurab17/vlc
  • purist.coder/vlc
  • Shuicheng/vlc
  • mdrrubel292/vlc
  • silverbleu00/vlc
  • metif12/vlc
  • asher-m/vlc
  • jeffk/vlc
  • Brandonbr1/vlc
  • beautyyuyanli/vlc
  • rego21/vlc
  • muyangren907/vlc
  • collectionbylawrencejason/vlc
  • evelez/vlc
  • GSMgeeth/vlc
  • Oneric/vlc
  • TJ5/vlc
  • XuanTung95/vlc
  • darrenjenny21/vlc
  • Trenly/vlc
  • RockyTDR/vlc
  • mjakubowski/vlc
  • caprica/vlc
  • ForteFrankie/vlc
  • seannamiller19/vlc
  • junlon2006/vlc
  • kiwiren6666/vlc
  • iuseiphonexs/vlc
  • fenngtun/vlc
  • Rajdutt999/vlc
  • typx/vlc
  • leon.vitanos/vlc
  • robertogarci0938/vlc
  • gsoc/gsoc2022/luc65r/vlc-mpd
  • skeller/vlc
  • MCJack123/vlc
  • luc65r/vlc-mpd
  • popov895/vlc
  • claucambra/vlc
  • brad/vlc
  • matthewmurua88/vlc
  • Tomas8874/vlc
  • philenotfound/vlc
  • makita-do3/vlc
  • LZXCorp/vlc
  • mar0x/vlc
  • senojetkennedy0102/vlc
  • shaneb243/vlc
  • ahmadbader/vlc
  • rajduttcse26/vlc-audio-filters
  • Juniorzito8415/vlc
  • achernyakov/vlc
  • lucasjetgroup/vlc
  • pupdoggy666/vlc
  • gmde9363/vlc
  • alexnwayne/vlc
  • bahareebrahimi781/vlc
  • hamad633666/vlc
  • umghof3112/vlc
  • joe0199771874/vlc
  • Octocats66666666/vlc
  • jjm_223/vlc
  • btech10110.19/vlc
  • sunnykfc028/vlc-audio-filters
  • loic/vlc
  • nguyenminhducmx1/vlc
  • JanekKrueger/vlc
  • bstubbington2/vlc
  • rcombs/vlc
  • Ordissimo/vlc
  • king7532/vlc
  • noobsauce101/vlc
  • schong0525/vlc
  • myQwil/vlc
  • apisbg91/vlc
  • geeboy0101017/vlc
  • kim.faughey/vlc
  • nurupo/vlc
  • yyusea/vlc
  • 0711235879.khco/vlc
  • ialo/vlc
  • iloveyeye2/vlc
  • gdtdftdqtd/vlc
  • leandroconsiglio/vlc
  • AndyHTML2012/vlc
  • ncz/vlc
  • lucenticus/vlc
  • knr1931/vlc
  • kjoonlee/vlc
  • chandrakant100/vlc-qt
  • johge42/vlc
  • polter/vlc
  • hexchain/vlc
  • Tushwrld/vlc
  • mztea928/vlc
  • jbelloncastro/vlc
  • alvinhochun/vlc
  • ghostpiratecrow/vlc
  • ujjwaltwitx/vlc
  • alexsonarin06/vlc
  • adrianbon76/vlc
  • altsod/vlc
  • damien.lucas44/vlc
  • dmytrivtaisa/vlc
  • utk202/vlc
  • aaxhrj/vlc
  • thomas.hermes/vlc
  • structurenewworldorder/vlc
  • slomo/vlc
  • wantlamy/vlc
  • musc.o3cminc/vlc
  • thebarshablog/vlc
  • kerrick/vlc
  • kratos142518/vlc
  • leogps/vlc
  • vacantron/vlc
  • luna_koly/vlc
  • Ratio2/vlc
  • anuoshemohammad/vlc
  • apsun/vlc
  • aaa1115910/vlc
  • alimotmoyo/vlc
  • Ambossmann/vlc
  • Sam-LearnsToCode/vlc
  • Chilledheart/vlc
  • Labnann/vlc
  • ktcoooot1/vlc
  • mohit-marathe/vlc
  • johnddx/vlc
  • manstabuk/vlc
  • Omar-ahmed314/vlc
  • vineethkm/vlc
  • 9Enemi86/vlc
  • radoslav.m.panteleev/vlc
  • ashishami2002/vlc
  • Corbax/vlc
  • firnasahmed/vlc
  • pelayarmalam4/vlc
  • c0ff330k/vlc
  • shikhindahikar/vlc
  • l342723951/vlc
  • christianschwandner/vlc
  • douniwan5788/vlc
  • 7damian7/vlc
  • ferdnyc/vlc
  • f.ales1/vlc
  • pandagby/vlc
  • BaaBaa/vlc
  • jewe37/vlc
  • w00drow/vlc
  • russelltg/vlc
  • ironicallygod/vlc
  • soumyaDghosh/vlc
  • linzihao1999/vlc
  • deyayush6/vlc
  • mibi88/vlc
  • newabdallah10/vlc
  • jhorbincolombia/vlc
  • rimvihaqueshupto/vlc
  • andrewkhon98/vlc
  • fab78/vlc
  • lapaz17/vlc
  • amanna13/vlc
  • mdakram28/vlc
  • 07jw1980/vlc
  • sohamgupta/vlc
  • Eson-Jia1/vlc
  • Sumou/vlc
  • vikram-kangotra/vlc
  • chalice191/vlc
  • olivercalder/vlc
  • aaasg4001/vlc
  • zipdox/vlc
  • kwizart/vlc
  • Dragon-S/vlc
  • jdemeule/vlc
  • gabriel_lt/vlc
  • locutusofborg/vlc
  • sammirata/vlc-librist
  • another/vlc
  • Benjamin_Loison/vlc
  • ahmedmoselhi/vlc
  • petergaal/vlc
  • huynhsontung/vlc
  • dariusmihut/vlc
  • tvermaashutosh/vlc
  • buti/vlc
  • Niram7777/vlc
  • rohan-here/vlc
  • balaji-sivasakthi/vlc
  • rlindner81/vlc
  • Kakadus/vlc
  • djain/vlc
  • ABBurmeister/vlc
  • craighuggins/vlc
  • orbea/vlc
  • maxos/vlc
  • aakarshmj/vlc
  • kblaschke/vlc
  • ankitm/vlc
  • advait-0/vlc
  • mohak2003/vlc
  • yselkowitz/vlc
  • AZM999/vlc-azm
  • andrey.turkin/vlc
  • Disha-Baghel/vlc
  • nowrep/vlc
  • Apeng/vlc
  • Choucroute_melba/vlc
  • autra/vlc
  • eclipseo/vlc
  • fhuber/vlc
  • olafhering/vlc
  • sdasda7777/vlc
  • 1div0/vlc
  • skosnits/vlc-extended-playlist-support
  • dnicolson/vlc
  • Timshel/vlc
  • octopols/vlc
  • MangalK/vlc
  • nima64/vlc
  • misawai/vlc
  • Alexander-Wilms/vlc
  • Maxime2/vlc-fork-for-visualizer
  • ww/vlc
  • jeske/vlc
  • sgross-emlix/vlc
  • morenonatural/vlc
  • freakingLovesVLC/vlc
  • borisgolovnev/vlc
  • mpromonet/vlc
  • diogo.simao-marques/vlc
  • masstock/vlc
  • pratikpatel8982/vlc
  • hugok79/vlc
  • longervision/vlc
  • abhiudaysurya/vlc
  • rishabhgarg/vlc
  • tumic/vlc
  • cart/vlc
  • shubham442/vlc
  • Aditya692005/vlc
  • sammirata/vlc4
  • syrykh/vlc
  • Vvorcun/macos-new-icon
  • AyaanshC/vlc
  • nasso/vlc
  • Quark/vlc
  • sebastinas/vlc
  • rhstone/vlc
  • talregev/vlc
  • Managor/vlc
403 results
Show changes
Commits on Source (15)
Showing with 602 additions and 370 deletions
......@@ -449,6 +449,7 @@ libdxva2_plugin_la_SOURCES = \
codec/avcodec/va_surface.c codec/avcodec/va_surface.h \
packetizer/h264_nal.c packetizer/h264_nal.h \
packetizer/hevc_nal.c packetizer/hevc_nal.h \
packetizer/h26x_nal_common.h \
codec/avcodec/dxva_blocklist.c
libdxva2_plugin_la_LIBADD = libd3d9_common.la $(LIBCOM) -luuid
if !HAVE_WINSTORE
......@@ -470,6 +471,7 @@ libd3d11va_plugin_la_SOURCES = \
codec/avcodec/va_surface.c codec/avcodec/va_surface.h \
packetizer/h264_nal.c packetizer/h264_nal.h \
packetizer/hevc_nal.c packetizer/hevc_nal.h \
packetizer/h26x_nal_common.h \
codec/avcodec/dxva_blocklist.c
libd3d11va_plugin_la_LIBADD = libd3d11_common.la $(LIBCOM) -luuid
if HAVE_WINSTORE
......@@ -497,6 +499,7 @@ libomxil_plugin_la_SOURCES = \
codec/omxil/utils.c codec/omxil/omxil_utils.h \
packetizer/h264_nal.c packetizer/h264_nal.h \
packetizer/hevc_nal.c packetizer/hevc_nal.h \
packetizer/h26x_nal_common.h \
codec/omxil/qcom.c codec/omxil/qcom.h \
codec/omxil/omxil.c codec/omxil/omxil.h codec/omxil/omxil_core.c codec/omxil/omxil_core.h
libomxil_plugin_la_CPPFLAGS = $(AM_CPPFLAGS) -I$(srcdir)/codec/omxil $(CFLAGS_omxil)
......@@ -689,6 +692,7 @@ libvlc_hxxxhelper_la_SOURCES = \
packetizer/hxxx_sei.h packetizer/hxxx_sei.c \
packetizer/h264_slice.c packetizer/h264_slice.h \
packetizer/h264_nal.c packetizer/h264_nal.h \
packetizer/h26x_nal_common.h \
packetizer/hevc_nal.c packetizer/hevc_nal.h
libvlc_hxxxhelper_la_CPPFLAGS = -Dneedsomethinghere
libvlc_hxxxhelper_la_LDFLAGS = -static
......
......@@ -1772,7 +1772,7 @@ static void lavc_ReleaseFrame(void *opaque, uint8_t *data)
picture_Release(picture);
}
static int lavc_va_GetFrame(struct AVCodecContext *ctx, AVFrame *frame)
static int lavc_va_GetFrame(struct AVCodecContext *ctx, AVFrame *frame, int flags)
{
decoder_t *dec = ctx->opaque;
decoder_sys_t *p_sys = dec->p_sys;
......@@ -1794,7 +1794,7 @@ static int lavc_va_GetFrame(struct AVCodecContext *ctx, AVFrame *frame)
return -1;
}
AVBufferRef *buf = av_buffer_create(NULL, 0, lavc_ReleaseFrame, pic, 0);
AVBufferRef *buf = av_buffer_create(NULL, 0, lavc_ReleaseFrame, pic, flags);
if (unlikely(buf == NULL))
{
lavc_ReleaseFrame(pic, NULL);
......@@ -1822,7 +1822,7 @@ static int lavc_va_GetFrame(struct AVCodecContext *ctx, AVFrame *frame)
return 0;
}
static int lavc_dr_GetFrame(struct AVCodecContext *ctx, AVFrame *frame)
static int lavc_dr_GetFrame(struct AVCodecContext *ctx, AVFrame *frame, int flags)
{
decoder_t *dec = ctx->opaque;
decoder_sys_t *sys = dec->p_sys;
......@@ -1876,7 +1876,7 @@ static int lavc_dr_GetFrame(struct AVCodecContext *ctx, AVFrame *frame)
frame->data[i] = data;
frame->linesize[i] = pic->p[i].i_pitch;
frame->buf[i] = av_buffer_create(data, size, lavc_ReleaseFrame,
pic, 0);
pic, flags);
if (unlikely(frame->buf[i] == NULL))
{
while (i > 0)
......@@ -1937,14 +1937,14 @@ static int lavc_GetFrame(struct AVCodecContext *ctx, AVFrame *frame, int flags)
if (sys->p_va != NULL)
{
int ret = lavc_va_GetFrame(ctx, frame);
int ret = lavc_va_GetFrame(ctx, frame, flags);
vlc_mutex_unlock(&sys->lock);
return ret;
}
/* Some codecs set pix_fmt only after the 1st frame has been decoded,
* so we need to check for direct rendering again. */
int ret = lavc_dr_GetFrame(ctx, frame);
int ret = lavc_dr_GetFrame(ctx, frame, flags);
vlc_mutex_unlock(&sys->lock);
if (ret)
ret = avcodec_default_get_buffer2(ctx, frame, flags);
......
......@@ -201,34 +201,38 @@ h264_helper_parse_nal(struct hxxx_helper *hh, const uint8_t *p_nal, size_t i_nal
return VLC_EGENERIC;
const enum h264_nal_unit_type_e i_nal_type = p_nal[0] & 0x1F;
uint8_t i_id;
if (i_nal_type == H264_NAL_SPS)
{
h264_get_xps_id(p_nal, i_nal, &i_id);
LOAD_xPS(hh->h264.sps_list, hh->h264.i_sps_count,
p_xps->i_id, H264_SPS_ID_MAX,
i_id, H264_SPS_ID_MAX,
h264_sequence_parameter_set_t,
h264_decode_sps,
h264_release_sps);
hh->h264.i_current_sps = ((h264_sequence_parameter_set_t*)p_xps)->i_id;
msg_Dbg(hh->p_obj, "new SPS parsed: %u", hh->h264.i_current_sps);
hh->h264.i_current_sps = i_id;
msg_Dbg(hh->p_obj, "new SPS parsed: %u", i_id);
}
else if (i_nal_type == H264_NAL_PPS)
{
h264_get_xps_id(p_nal, i_nal, &i_id);
LOAD_xPS(hh->h264.pps_list, hh->h264.i_pps_count,
p_xps->i_id, H264_PPS_ID_MAX,
i_id, H264_PPS_ID_MAX,
h264_picture_parameter_set_t,
h264_decode_pps,
h264_release_pps);
msg_Dbg(hh->p_obj, "new PPS parsed: %u", ((h264_picture_parameter_set_t*)p_xps)->i_id);
msg_Dbg(hh->p_obj, "new PPS parsed: %u", i_id);
}
else if(i_nal_type == H264_NAL_SPS_EXT)
{
h264_get_xps_id(p_nal, i_nal, &i_id);
LOAD_xPS(hh->h264.spsext_list, hh->h264.i_spsext_count,
p_xps->i_sps_id, H264_SPSEXT_ID_MAX,
i_id, H264_SPSEXT_ID_MAX,
h264_sequence_parameter_set_extension_t,
h264_decode_sps_extension,
h264_release_sps_extension);
msg_Dbg(hh->p_obj, "new SPSEXT parsed: %u", ((h264_sequence_parameter_set_extension_t*)p_xps)->i_sps_id);
msg_Dbg(hh->p_obj, "new SPSEXT parsed: %u", i_id);
}
else if (i_nal_type <= H264_NAL_SLICE_IDR
&& i_nal_type != H264_NAL_UNKNOWN)
......@@ -254,14 +258,14 @@ h264_helper_parse_nal(struct hxxx_helper *hh, const uint8_t *p_nal, size_t i_nal
return VLC_EGENERIC;
struct hxxx_helper_nal *hsps =
&hh->h264.sps_list[hpps->h264_pps->i_sps_id];
&hh->h264.sps_list[h264_get_pps_sps_id(hpps->h264_pps)];
if (hsps->b == NULL)
return VLC_EGENERIC;
assert(hpps->h264_pps->i_sps_id == hsps->h264_sps->i_id);
if (hsps->h264_sps->i_id != hh->h264.i_current_sps)
assert(h264_get_pps_sps_id(hpps->h264_pps) == h264_get_sps_id(hsps->h264_sps));
if (h264_get_sps_id(hsps->h264_sps) != hh->h264.i_current_sps)
{
hh->h264.i_current_sps = hsps->h264_sps->i_id;
hh->h264.i_current_sps = h264_get_sps_id(hsps->h264_sps);
hh->i_config_version++;
}
}
......@@ -832,20 +836,20 @@ hxxx_helper_get_current_picture_size(const struct hxxx_helper *hh,
int
hxxx_helper_get_current_sar(const struct hxxx_helper *hh, int *p_num, int *p_den)
{
unsigned num, den;
if(hh->i_codec == VLC_CODEC_H264)
{
const struct hxxx_helper_nal *hsps = h264_helper_get_current_sps(hh);
if (hsps)
if (hsps && hsps->h264_sps && h264_get_aspect_ratio(hsps->h264_sps, &num, &den))
{
*p_num = hsps->h264_sps->vui.i_sar_num;
*p_den = hsps->h264_sps->vui.i_sar_den;
*p_num = num;
*p_den = den;
return VLC_SUCCESS;
}
}
else if(hh->i_codec == VLC_CODEC_HEVC)
{
const struct hxxx_helper_nal *hsps = &hh->hevc.sps_list[hh->hevc.i_current_sps];
unsigned num, den;
if(hsps && hsps->hevc_sps && hevc_get_aspect_ratio(hsps->hevc_sps, &num, &den))
{
*p_num = num;
......@@ -874,12 +878,9 @@ hxxx_helper_get_current_profile_level(const struct hxxx_helper *hh,
if(hh->i_codec == VLC_CODEC_H264)
{
const struct hxxx_helper_nal *hsps = h264_helper_get_current_sps(hh);
if (hsps)
{
*p_profile = hsps->h264_sps->i_profile;
*p_level = hsps->h264_sps->i_level;
if (hsps && hsps->h264_sps &&
h264_get_sps_profile_tier_level(hsps->h264_sps, p_profile, p_level))
return VLC_SUCCESS;
}
}
else if(hh->i_codec == VLC_CODEC_HEVC)
{
......@@ -896,11 +897,9 @@ int h264_helper_get_constraint_flag(const struct hxxx_helper *hh,
assert(hh->i_codec == VLC_CODEC_H264);
const struct hxxx_helper_nal *hsps = h264_helper_get_current_sps(hh);
if (hsps)
{
*pi_constraints = hsps->h264_sps->i_constraint_set_flags;
if (hsps && hsps->h264_sps &&
h264_get_constraints_set(hsps->h264_sps, pi_constraints))
return VLC_SUCCESS;
}
return VLC_EGENERIC;
}
......
......@@ -201,7 +201,7 @@ static void GetxPSH264(uint8_t i_pps_id, void *priv,
if (*pp_pps == NULL)
*pp_sps = NULL;
else
*pp_sps = h264ctx->hh.h264.sps_list[(*pp_pps)->i_sps_id].h264_sps;
*pp_sps = h264ctx->hh.h264.sps_list[h264_get_pps_sps_id(*pp_pps)].h264_sps;
}
struct sei_callback_h264_s
......@@ -215,16 +215,13 @@ static bool ParseH264SEI(const hxxx_sei_data_t *p_sei_data, void *priv)
if (p_sei_data->i_type == HXXX_SEI_PIC_TIMING)
{
struct sei_callback_h264_s *s = priv;
if (s->p_sps && s->p_sps->vui.b_valid)
if (s->p_sps)
{
if (s->p_sps->vui.b_hrd_parameters_present_flag)
{
bs_read(p_sei_data->p_bs, s->p_sps->vui.i_cpb_removal_delay_length_minus1 + 1);
bs_read(p_sei_data->p_bs, s->p_sps->vui.i_dpb_output_delay_length_minus1 + 1);
}
if (s->p_sps->vui.b_pic_struct_present_flag)
s->i_pic_struct = bs_read( p_sei_data->p_bs, 4);
uint8_t i_dpb_output_delay;
h264_decode_sei_pic_timing( p_sei_data->p_bs, s->p_sps,
&s->i_pic_struct,
&i_dpb_output_delay );
VLC_UNUSED(i_dpb_output_delay);
}
return false;
}
......@@ -257,24 +254,25 @@ static bool FillReorderInfoH264(decoder_t *p_dec, const block_t *p_block,
if (i_nal_type <= H264_NAL_SLICE_IDR && i_nal_type != H264_NAL_UNKNOWN)
{
h264_slice_t slice;
if (!h264_decode_slice(p_nal, i_nal, GetxPSH264, h264ctx, &slice))
h264_slice_t *slice = h264_decode_slice(p_nal, i_nal, GetxPSH264, h264ctx);
if (!slice)
return false;
const h264_sequence_parameter_set_t *p_sps;
const h264_picture_parameter_set_t *p_pps;
GetxPSH264(slice.i_pic_parameter_set_id, h264ctx, &p_sps, &p_pps);
GetxPSH264(h264_get_slice_pps_id(slice), h264ctx, &p_sps, &p_pps);
if (p_sps)
{
int bFOC;
h264_compute_poc(p_sps, &slice, &h264ctx->poc,
h264_compute_poc(p_sps, slice, &h264ctx->poc,
&p_info->i_poc, &p_info->i_foc, &bFOC);
p_info->b_keyframe = slice.type == H264_SLICE_TYPE_I;
p_info->b_flush = (slice.type == H264_SLICE_TYPE_I) || slice.has_mmco5;
p_info->b_field = slice.i_field_pic_flag;
p_info->b_progressive = !p_sps->mb_adaptive_frame_field_flag &&
!slice.i_field_pic_flag;
enum h264_slice_type_e slicetype = h264_get_slice_type(slice);
p_info->b_keyframe = slicetype == H264_SLICE_TYPE_I;
p_info->b_flush = p_info->b_keyframe || h264_has_mmco5(slice);
p_info->b_field = h264_is_field_pic(slice);
p_info->b_progressive = !h264_using_adaptive_frames(p_sps) &&
!p_info->b_field;
struct sei_callback_h264_s sei;
sei.p_sps = p_sps;
......@@ -284,7 +282,7 @@ static bool FillReorderInfoH264(decoder_t *p_dec, const block_t *p_block,
HxxxParseSEI(sei_array[i].p_nal, sei_array[i].i_nal, 1,
ParseH264SEI, &sei);
p_info->i_num_ts = h264_get_num_ts(p_sps, &slice, sei.i_pic_struct,
p_info->i_num_ts = h264_get_num_ts(p_sps, slice, sei.i_pic_struct,
p_info->i_foc, bFOC);
unsigned dummy;
h264_get_dpb_values(p_sps, &p_info->i_max_pics_buffering, &dummy);
......@@ -293,12 +291,14 @@ static bool FillReorderInfoH264(decoder_t *p_dec, const block_t *p_block,
p_info->b_top_field_first = (sei.i_pic_struct % 2 == 1);
/* Set frame rate for timings in case of missing rate */
if (p_sps->vui.i_time_scale && p_sps->vui.i_num_units_in_tick)
unsigned fr[2];
if(h264_get_frame_rate(p_sps, fr, &fr[1]))
{
p_info->field_rate_num = p_sps->vui.i_time_scale;
p_info->field_rate_den = p_sps->vui.i_num_units_in_tick;
p_info->field_rate_num = fr[0];
p_info->field_rate_den = fr[1];
}
}
h264_slice_release(slice);
return true; /* No need to parse further NAL */
}
......
......@@ -7,8 +7,10 @@ libpacketizer_av1_plugin_la_SOURCES = packetizer/av1.c \
libpacketizer_copy_plugin_la_SOURCES = packetizer/copy.c
libpacketizer_mpegvideo_plugin_la_SOURCES = packetizer/mpegvideo.c \
packetizer/mpegvideo.h \
packetizer/h26x_nal_common.h \
packetizer/iso_color_tables.h
libpacketizer_mpeg4video_plugin_la_SOURCES = packetizer/mpeg4video.c \
packetizer/h26x_nal_common.h \
packetizer/iso_color_tables.h
libpacketizer_mjpeg_plugin_la_SOURCES = packetizer/mjpeg.c
libpacketizer_mpeg4audio_plugin_la_SOURCES = packetizer/mpeg4audio.c \
......@@ -32,6 +34,7 @@ libpacketizer_flac_plugin_la_SOURCES = packetizer/flac.c \
packetizer/flac.h
libpacketizer_hevc_plugin_la_SOURCES = packetizer/hevc.c \
packetizer/hevc_nal.h packetizer/hevc_nal.c \
packetizer/h26x_nal_common.h \
packetizer/hxxx_sei.c packetizer/hxxx_sei.h \
packetizer/hxxx_nal.h \
packetizer/hxxx_common.c packetizer/hxxx_common.h \
......
......@@ -73,7 +73,6 @@ typedef struct
packetizer_t packetizer;
/* */
bool b_slice;
struct
{
block_t *p_head;
......@@ -109,8 +108,8 @@ typedef struct
uint8_t i_dpb_output_delay;
unsigned i_recovery_frame_cnt;
/* Useful values of the Slice Header */
h264_slice_t slice;
/* Current Slice Header */
h264_slice_t *p_slice;
/* */
int i_next_block_flags;
......@@ -154,11 +153,10 @@ static block_t *ParseNALBlock( decoder_t *, bool *pb_ts_used, block_t * );
static block_t *OutputPicture( decoder_t *p_dec );
static void ReleaseXPS( decoder_sys_t *p_sys );
static bool PutXPS( decoder_t *p_dec, uint8_t i_nal_type, block_t *p_frag );
static bool ParseSliceHeader( decoder_t *p_dec, const block_t *p_frag, h264_slice_t *p_slice );
static h264_slice_t * ParseSliceHeader( decoder_t *p_dec, const block_t *p_frag );
static bool ParseSeiCallback( const hxxx_sei_data_t *, void * );
static const uint8_t p_h264_startcode[3] = { 0x00, 0x00, 0x01 };
/*****************************************************************************
* Helpers
......@@ -202,8 +200,12 @@ static void ActivateSets( decoder_t *p_dec, const h264_sequence_parameter_set_t
if( p_sps )
{
p_dec->fmt_out.i_profile = p_sps->i_profile;
p_dec->fmt_out.i_level = p_sps->i_level;
uint8_t pl[2];
if( h264_get_sps_profile_tier_level( p_sps, pl, &pl[1] ) )
{
p_dec->fmt_out.i_profile = pl[0];
p_dec->fmt_out.i_level = pl[1];
}
(void) h264_get_picture_size( p_sps,
&p_dec->fmt_out.video.i_x_offset,
......@@ -213,31 +215,24 @@ static void ActivateSets( decoder_t *p_dec, const h264_sequence_parameter_set_t
&p_dec->fmt_out.video.i_visible_width,
&p_dec->fmt_out.video.i_visible_height );
if( p_sps->vui.i_sar_num != 0 && p_sps->vui.i_sar_den != 0 )
{
p_dec->fmt_out.video.i_sar_num = p_sps->vui.i_sar_num;
p_dec->fmt_out.video.i_sar_den = p_sps->vui.i_sar_den;
}
h264_get_aspect_ratio( p_sps,
&p_dec->fmt_out.video.i_sar_num,
&p_dec->fmt_out.video.i_sar_den );
if( !p_dec->fmt_out.video.i_frame_rate ||
!p_dec->fmt_out.video.i_frame_rate_base )
{
/* on first run == if fmt_in does not provide frame rate info */
/* If we have frame rate info in the stream */
if(p_sps->vui.b_valid &&
p_sps->vui.i_num_units_in_tick > 0 &&
p_sps->vui.i_time_scale > 1 )
{
date_Change( &p_sys->dts, p_sps->vui.i_time_scale,
p_sps->vui.i_num_units_in_tick );
}
unsigned nd[2];
if( h264_get_frame_rate( p_sps, nd, &nd[1] ) )
date_Change( &p_sys->dts, nd[0], nd[1] );
/* else use the default num/den */
p_dec->fmt_out.video.i_frame_rate = p_sys->dts.i_divider_num >> 1; /* num_clock_ts == 2 */
p_dec->fmt_out.video.i_frame_rate_base = p_sys->dts.i_divider_den;
}
if( p_dec->fmt_in->video.primaries == COLOR_PRIMARIES_UNDEF &&
p_sps->vui.b_valid )
if( p_dec->fmt_in->video.primaries == COLOR_PRIMARIES_UNDEF )
{
h264_get_colorimetry( p_sps, &p_dec->fmt_out.video.primaries,
&p_dec->fmt_out.video.transfer,
......@@ -264,34 +259,6 @@ static void ActivateSets( decoder_t *p_dec, const h264_sequence_parameter_set_t
}
}
static bool IsFirstVCLNALUnit( const h264_slice_t *p_prev, const h264_slice_t *p_cur )
{
/* Detection of the first VCL NAL unit of a primary coded picture
* (cf. 7.4.1.2.4) */
if( p_cur->i_frame_num != p_prev->i_frame_num ||
p_cur->i_pic_parameter_set_id != p_prev->i_pic_parameter_set_id ||
p_cur->i_field_pic_flag != p_prev->i_field_pic_flag ||
!p_cur->i_nal_ref_idc != !p_prev->i_nal_ref_idc )
return true;
if( (p_cur->i_bottom_field_flag != -1) &&
(p_prev->i_bottom_field_flag != -1) &&
(p_cur->i_bottom_field_flag != p_prev->i_bottom_field_flag) )
return true;
if( p_cur->i_pic_order_cnt_type == 0 &&
( p_cur->i_pic_order_cnt_lsb != p_prev->i_pic_order_cnt_lsb ||
p_cur->i_delta_pic_order_cnt_bottom != p_prev->i_delta_pic_order_cnt_bottom ) )
return true;
else if( p_cur->i_pic_order_cnt_type == 1 &&
( p_cur->i_delta_pic_order_cnt0 != p_prev->i_delta_pic_order_cnt0 ||
p_cur->i_delta_pic_order_cnt1 != p_prev->i_delta_pic_order_cnt1 ) )
return true;
if( ( p_cur->i_nal_type == H264_NAL_SLICE_IDR || p_prev->i_nal_type == H264_NAL_SLICE_IDR ) &&
( p_cur->i_nal_type != p_prev->i_nal_type || p_cur->i_idr_pic_id != p_prev->i_idr_pic_id ) )
return true;
return false;
}
static void DropStoredNAL( decoder_sys_t *p_sys )
{
block_ChainRelease( p_sys->frame.p_head );
......@@ -334,12 +301,12 @@ static int Open( vlc_object_t *p_this )
}
packetizer_Init( &p_sys->packetizer,
p_h264_startcode, sizeof(p_h264_startcode), startcode_FindAnnexB,
p_h264_startcode, 1, 5,
annexb_startcode3, 3, startcode_FindAnnexB,
annexb_startcode3, 1, 5,
PacketizeReset, PacketizeParse, PacketizeValidate, PacketizeDrain,
p_dec );
p_sys->b_slice = false;
p_sys->p_slice = NULL;
p_sys->frame.p_head = NULL;
p_sys->frame.pp_append = &p_sys->frame.p_head;
p_sys->leading.p_head = NULL;
......@@ -363,8 +330,6 @@ static int Open( vlc_object_t *p_this )
p_sys->spsext[i].p_block = NULL;
p_sys->i_recovery_frame_cnt = UINT_MAX;
h264_slice_init( &p_sys->slice );
p_sys->i_next_block_flags = 0;
p_sys->b_recovered = false;
p_sys->i_recoveryfnum = UINT_MAX;
......@@ -475,6 +440,9 @@ static void Close( vlc_object_t *p_this )
DropStoredNAL( p_sys );
ReleaseXPS( p_sys );
if( p_sys->p_slice )
h264_slice_release( p_sys->p_slice );
packetizer_Clean( &p_sys->packetizer );
cc_storage_delete( p_sys->p_ccs );
......@@ -530,10 +498,11 @@ static void ResetOutputVariables( decoder_sys_t *p_sys )
{
p_sys->i_frame_dts = VLC_TICK_INVALID;
p_sys->i_frame_pts = VLC_TICK_INVALID;
p_sys->slice.type = H264_SLICE_TYPE_UNKNOWN;
if( p_sys->p_slice )
h264_slice_release( p_sys->p_slice );
p_sys->p_slice = NULL;
p_sys->b_new_sps = false;
p_sys->b_new_pps = false;
p_sys->b_slice = false;
/* From SEI */
p_sys->i_dpb_output_delay = 0;
p_sys->i_pic_struct = UINT8_MAX;
......@@ -545,7 +514,7 @@ static void PacketizeReset( void *p_private, bool b_flush )
decoder_t *p_dec = p_private;
decoder_sys_t *p_sys = p_dec->p_sys;
if( b_flush || !p_sys->b_slice )
if( b_flush || !p_sys->p_slice )
{
DropStoredNAL( p_sys );
ResetOutputVariables( p_sys );
......@@ -582,7 +551,7 @@ static block_t * PacketizeDrain( void *p_private )
decoder_t *p_dec = p_private;
decoder_sys_t *p_sys = p_dec->p_sys;
if( !p_sys->b_slice )
if( !p_sys->p_slice )
return NULL;
block_t *p_out = OutputPicture( p_dec );
......@@ -610,7 +579,7 @@ static block_t *ParseNALBlock( decoder_t *p_dec, bool *pb_ts_used, block_t *p_fr
bool b_au_end = p_frag->i_flags & BLOCK_FLAG_AU_END;
p_frag->i_flags &= ~BLOCK_FLAG_AU_END;
if( p_sys->b_slice && (!p_sys->p_active_pps || !p_sys->p_active_sps) )
if( p_sys->p_slice && (!p_sys->p_active_pps || !p_sys->p_active_sps) )
{
msg_Warn( p_dec, "waiting for SPS/PPS" );
......@@ -629,7 +598,7 @@ static block_t *ParseNALBlock( decoder_t *p_dec, bool *pb_ts_used, block_t *p_fr
case H264_NAL_SLICE_DPC:
case H264_NAL_SLICE_IDR:
{
h264_slice_t newslice;
h264_slice_t *p_newslice;
if( i_nal_type == H264_NAL_SLICE_IDR )
{
......@@ -638,13 +607,12 @@ static block_t *ParseNALBlock( decoder_t *p_dec, bool *pb_ts_used, block_t *p_fr
p_sys->i_recoveryfnum = UINT_MAX;
}
if( ParseSliceHeader( p_dec, p_frag, &newslice ) )
if( (p_newslice = ParseSliceHeader( p_dec, p_frag )) )
{
/* Only IDR carries the id, to be propagated */
if( newslice.i_idr_pic_id == -1 )
newslice.i_idr_pic_id = p_sys->slice.i_idr_pic_id;
h264_slice_copy_idr_id( p_sys->p_slice, p_newslice );
bool b_new_picture = IsFirstVCLNALUnit( &p_sys->slice, &newslice );
bool b_new_picture = h264_IsFirstVCLNALUnit( p_sys->p_slice, p_newslice );
if( b_new_picture )
{
/* Parse SEI for that frame now we should have matched SPS/PPS */
......@@ -656,19 +624,19 @@ static block_t *ParseNALBlock( decoder_t *p_dec, bool *pb_ts_used, block_t *p_fr
1 /* nal header */, ParseSeiCallback, p_dec );
}
if( p_sys->b_slice )
if( p_sys->p_slice )
p_pic = OutputPicture( p_dec );
}
/* */
p_sys->slice = newslice;
h264_slice_release( p_sys->p_slice );
p_sys->p_slice = p_newslice;
}
else
{
p_sys->p_active_pps = NULL;
/* Fragment will be discarded later on */
}
p_sys->b_slice = true;
block_ChainLastAppend( &p_sys->frame.pp_append, p_frag );
} break;
......@@ -676,7 +644,7 @@ static block_t *ParseNALBlock( decoder_t *p_dec, bool *pb_ts_used, block_t *p_fr
/*** Prefix NALs ***/
case H264_NAL_AU_DELIMITER:
if( p_sys->b_slice )
if( p_sys->p_slice )
p_pic = OutputPicture( p_dec );
/* clear junk if no pic, we're always the first nal */
......@@ -689,7 +657,7 @@ static block_t *ParseNALBlock( decoder_t *p_dec, bool *pb_ts_used, block_t *p_fr
case H264_NAL_SPS:
case H264_NAL_PPS:
if( p_sys->b_slice )
if( p_sys->p_slice )
p_pic = OutputPicture( p_dec );
/* Stored for insert on keyframes */
......@@ -700,7 +668,7 @@ static block_t *ParseNALBlock( decoder_t *p_dec, bool *pb_ts_used, block_t *p_fr
break;
case H264_NAL_SEI:
if( p_sys->b_slice )
if( p_sys->p_slice )
p_pic = OutputPicture( p_dec );
p_frag->i_flags |= BLOCK_FLAG_PRIVATE_SEI;
......@@ -709,7 +677,7 @@ static block_t *ParseNALBlock( decoder_t *p_dec, bool *pb_ts_used, block_t *p_fr
case H264_NAL_SPS_EXT:
PutXPS( p_dec, i_nal_type, p_frag );
if( p_sys->b_slice )
if( p_sys->p_slice )
p_pic = OutputPicture( p_dec );
break;
......@@ -718,7 +686,7 @@ static block_t *ParseNALBlock( decoder_t *p_dec, bool *pb_ts_used, block_t *p_fr
case H264_NAL_DEPTH_PS:
case H264_NAL_RESERVED_17:
case H264_NAL_RESERVED_18:
if( p_sys->b_slice )
if( p_sys->p_slice )
p_pic = OutputPicture( p_dec );
block_ChainLastAppend( &p_sys->leading.pp_append, p_frag );
......@@ -733,7 +701,7 @@ static block_t *ParseNALBlock( decoder_t *p_dec, bool *pb_ts_used, block_t *p_fr
/* important for still pictures/menus */
p_sys->i_next_block_flags |= BLOCK_FLAG_END_OF_SEQUENCE;
if( p_sys->b_slice )
if( p_sys->p_slice )
p_pic = OutputPicture( p_dec );
break;
......@@ -760,7 +728,7 @@ static block_t *ParseNALBlock( decoder_t *p_dec, bool *pb_ts_used, block_t *p_fr
date_Set( &p_sys->dts, i_frag_dts );
}
if( p_sys->b_slice && b_au_end && !p_pic )
if( p_sys->p_slice && b_au_end && !p_pic )
{
p_pic = OutputPicture( p_dec );
}
......@@ -774,17 +742,6 @@ static block_t *ParseNALBlock( decoder_t *p_dec, bool *pb_ts_used, block_t *p_fr
return p_pic;
}
static bool CanSwapPTSwithDTS( const h264_slice_t *p_slice,
const h264_sequence_parameter_set_t *p_sps )
{
if( p_slice->i_nal_ref_idc == 0 && p_slice->type == H264_SLICE_TYPE_B )
return true;
else if( p_sps->vui.b_valid )
return p_sps->vui.i_max_num_reorder_frames == 0;
else
return p_sps->i_profile == PROFILE_H264_CAVLC_INTRA;
}
static block_t *OutputPicture( decoder_t *p_dec )
{
decoder_sys_t *p_sys = p_dec->p_sys;
......@@ -812,21 +769,23 @@ static block_t *OutputPicture( decoder_t *p_dec )
}
if( !p_sys->b_recovered && p_sys->i_recoveryfnum == UINT_MAX &&
p_sys->i_recovery_frame_cnt == UINT_MAX && p_sys->slice.type == H264_SLICE_TYPE_I )
p_sys->i_recovery_frame_cnt == UINT_MAX && h264_get_slice_type(p_sys->p_slice) == H264_SLICE_TYPE_I )
{
/* No way to recover using SEI, just sync on I Slice */
p_sys->b_recovered = true;
}
bool b_need_sps_pps = p_sys->slice.type == H264_SLICE_TYPE_I &&
bool b_need_sps_pps = h264_get_slice_type(p_sys->p_slice) == H264_SLICE_TYPE_I &&
p_sys->p_active_pps && p_sys->p_active_sps;
const unsigned i_frame_num = h264_get_frame_num(p_sys->p_slice);
/* Handle SEI recovery */
if ( !p_sys->b_recovered && p_sys->i_recovery_frame_cnt != UINT_MAX &&
p_sys->i_recoveryfnum == UINT_MAX )
{
p_sys->i_recoveryfnum = p_sys->slice.i_frame_num + p_sys->i_recovery_frame_cnt;
p_sys->i_recoverystartfnum = p_sys->slice.i_frame_num;
p_sys->i_recoveryfnum = i_frame_num + p_sys->i_recovery_frame_cnt;
p_sys->i_recoverystartfnum = i_frame_num;
b_need_sps_pps = true; /* SPS/PPS must be inserted for SEI recovery */
msg_Dbg( p_dec, "Recovering using SEI, prerolling %u reference pics", p_sys->i_recovery_frame_cnt );
}
......@@ -834,13 +793,13 @@ static block_t *OutputPicture( decoder_t *p_dec )
if( p_sys->i_recoveryfnum != UINT_MAX )
{
assert(p_sys->b_recovered == false);
const unsigned maxFrameNum = 1 << (p_sps->i_log2_max_frame_num + 4);
const unsigned maxFrameNum = h264_get_max_frame_num( p_sps );
if( ( p_sys->i_recoveryfnum > maxFrameNum &&
p_sys->slice.i_frame_num < p_sys->i_recoverystartfnum &&
p_sys->slice.i_frame_num >= p_sys->i_recoveryfnum % maxFrameNum ) ||
i_frame_num < p_sys->i_recoverystartfnum &&
i_frame_num >= p_sys->i_recoveryfnum % maxFrameNum ) ||
( p_sys->i_recoveryfnum <= maxFrameNum &&
p_sys->slice.i_frame_num >= p_sys->i_recoveryfnum ) )
i_frame_num >= p_sys->i_recoveryfnum ) )
{
p_sys->i_recoveryfnum = UINT_MAX;
p_sys->b_recovered = true;
......@@ -892,11 +851,11 @@ static block_t *OutputPicture( decoder_t *p_dec )
/* for PTS Fixup, interlaced fields (multiple AU/block) */
int tFOC = 0, bFOC = 0, PictureOrderCount = 0;
h264_compute_poc( p_sps, &p_sys->slice, &p_sys->pocctx, &PictureOrderCount, &tFOC, &bFOC );
h264_compute_poc( p_sps, p_sys->p_slice, &p_sys->pocctx, &PictureOrderCount, &tFOC, &bFOC );
unsigned i_num_clock_ts = h264_get_num_ts( p_sps, &p_sys->slice, p_sys->i_pic_struct, tFOC, bFOC );
unsigned i_num_clock_ts = h264_get_num_ts( p_sps, p_sys->p_slice, p_sys->i_pic_struct, tFOC, bFOC );
if( p_sps->frame_mbs_only_flag == 0 && p_sps->vui.b_pic_struct_present_flag )
if( !h264_is_frames_only( p_sps ) && p_sys->i_pic_struct != UINT8_MAX )
{
switch( p_sys->i_pic_struct )
{
......@@ -904,8 +863,8 @@ static block_t *OutputPicture( decoder_t *p_dec )
case 1:
case 2:
p_pic->i_flags |= BLOCK_FLAG_SINGLE_FIELD;
p_pic->i_flags |= (!p_sys->slice.i_bottom_field_flag) ? BLOCK_FLAG_TOP_FIELD_FIRST
: BLOCK_FLAG_BOTTOM_FIELD_FIRST;
p_pic->i_flags |= h264_slice_top_field(p_sys->p_slice) ? BLOCK_FLAG_TOP_FIELD_FIRST
: BLOCK_FLAG_BOTTOM_FIELD_FIRST;
break;
/* Each of the following slices contains multiple fields */
case 3:
......@@ -933,7 +892,7 @@ static block_t *OutputPicture( decoder_t *p_dec )
if( p_pic->i_dts == VLC_TICK_INVALID )
p_pic->i_dts = date_Get( &p_sys->dts );
if( p_sys->slice.type == H264_SLICE_TYPE_I )
if( h264_get_slice_type( p_sys->p_slice ) == H264_SLICE_TYPE_I )
p_sys->prevdatedpoc.pts = VLC_TICK_INVALID;
if( p_pic->i_pts == VLC_TICK_INVALID )
......@@ -956,11 +915,11 @@ static block_t *OutputPicture( decoder_t *p_dec )
p_pic->i_pts = p_pic->i_dts;
}
/* In case there's no PTS at all */
else if( CanSwapPTSwithDTS( &p_sys->slice, p_sps ) )
else if( h264_CanSwapPTSWithDTS( p_sys->p_slice, p_sps ) )
{
p_pic->i_pts = p_pic->i_dts;
}
else if( p_sys->slice.type == H264_SLICE_TYPE_I &&
else if( h264_get_slice_type( p_sys->p_slice ) == H264_SLICE_TYPE_I &&
date_Get( &p_sys->dts ) != VLC_TICK_INVALID )
{
/* Hell no PTS on IDR. We're totally blind */
......@@ -970,7 +929,7 @@ static block_t *OutputPicture( decoder_t *p_dec )
}
}
else if( p_pic->i_dts == VLC_TICK_INVALID &&
CanSwapPTSwithDTS( &p_sys->slice, p_sps ) )
h264_CanSwapPTSWithDTS( p_sys->p_slice, p_sps ) )
{
p_pic->i_dts = p_pic->i_pts;
if( date_Get( &p_sys->dts ) == VLC_TICK_INVALID )
......@@ -991,10 +950,11 @@ static block_t *OutputPicture( decoder_t *p_dec )
}
#if 0
msg_Err(p_dec, "F/BOC %d/%d POC %d %d rec %d flags %x ref%d fn %d fp %d %d pts %ld len %ld",
msg_Err(p_dec, "F/BOC %d/%d POC %d %d rec %d flags %x ref%d fn %d fp %d %ld pts %ld len %ld",
tFOC, bFOC, PictureOrderCount,
p_sys->slice.type, p_sys->b_recovered, p_pic->i_flags,
p_sys->slice.i_nal_ref_idc, p_sys->slice.i_frame_num, p_sys->slice.i_field_pic_flag,
h264_get_slice_type(p_sys->p_slice), p_sys->b_recovered, p_pic->i_flags,
h264_get_nal_ref_idc(p_sys->p_slice), h264_get_frame_num(p_sys->p_slice),
h264_is_field_pic(p_sys->p_slice),
p_pic->i_pts - p_pic->i_dts, p_pic->i_pts % VLC_TICK_FROM_SEC(100), p_pic->i_length);
#endif
......@@ -1013,7 +973,7 @@ static block_t *OutputPicture( decoder_t *p_dec )
p_sys->i_next_block_flags = 0;
}
switch( p_sys->slice.type )
switch( h264_get_slice_type( p_sys->p_slice ) )
{
case H264_SLICE_TYPE_P:
p_pic->i_flags |= BLOCK_FLAG_TYPE_P;
......@@ -1182,10 +1142,10 @@ static void GetSPSPPS( uint8_t i_pps_id, void *priv,
if( *pp_pps == NULL )
*pp_sps = NULL;
else
*pp_sps = p_sys->sps[(*pp_pps)->i_sps_id].p_sps;
*pp_sps = p_sys->sps[h264_get_pps_sps_id(*pp_pps)].p_sps;
}
static bool ParseSliceHeader( decoder_t *p_dec, const block_t *p_frag, h264_slice_t *p_slice )
static h264_slice_t * ParseSliceHeader( decoder_t *p_dec, const block_t *p_frag )
{
decoder_sys_t *p_sys = p_dec->p_sys;
......@@ -1193,20 +1153,24 @@ static bool ParseSliceHeader( decoder_t *p_dec, const block_t *p_frag, h264_slic
size_t i_stripped = p_frag->i_buffer;
if( !hxxx_strip_AnnexB_startcode( &p_stripped, &i_stripped ) || i_stripped < 2 )
return false;
return NULL;
if( !h264_decode_slice( p_stripped, i_stripped, GetSPSPPS, p_sys, p_slice ) )
return false;
h264_slice_t *p_slice = h264_decode_slice( p_stripped, i_stripped, GetSPSPPS, p_sys );
if( !p_slice )
return NULL;
const h264_sequence_parameter_set_t *p_sps;
const h264_picture_parameter_set_t *p_pps;
GetSPSPPS( p_slice->i_pic_parameter_set_id, p_sys, &p_sps, &p_pps );
GetSPSPPS( h264_get_slice_pps_id( p_slice ), p_sys, &p_sps, &p_pps );
if( unlikely( !p_sps || !p_pps) )
return false;
{
h264_slice_release( p_slice );
return NULL;
}
ActivateSets( p_dec, p_sps, p_pps );
return true;
return p_slice;
}
static bool ParseSeiCallback( const hxxx_sei_data_t *p_sei_data, void *cbdata )
......@@ -1226,19 +1190,9 @@ static bool ParseSeiCallback( const hxxx_sei_data_t *p_sei_data, void *cbdata )
break;
}
if( p_sps->vui.b_valid )
{
if( p_sps->vui.b_hrd_parameters_present_flag )
{
bs_read( p_sei_data->p_bs, p_sps->vui.i_cpb_removal_delay_length_minus1 + 1 );
p_sys->i_dpb_output_delay =
bs_read( p_sei_data->p_bs, p_sps->vui.i_dpb_output_delay_length_minus1 + 1 );
}
if( p_sps->vui.b_pic_struct_present_flag )
p_sys->i_pic_struct = bs_read( p_sei_data->p_bs, 4 );
/* + unparsed remains */
}
h264_decode_sei_pic_timing( p_sei_data->p_bs, p_sps,
&p_sys->i_pic_struct,
&p_sys->i_dpb_output_delay );
} break;
/* Look for user_data_registered_itu_t_t35 */
......
......@@ -400,10 +400,9 @@ static bool h264_parse_sequence_parameter_set_rbsp( bs_t *p_bs,
}
/* vui */
i_tmp = bs_read( p_bs, 1 );
if( i_tmp )
p_sps->vui_parameters_present_flag = bs_read( p_bs, 1 );
if( p_sps->vui_parameters_present_flag )
{
p_sps->vui.b_valid = true;
/* read the aspect ratio part if any */
i_tmp = bs_read( p_bs, 1 );
if( i_tmp )
......@@ -775,6 +774,16 @@ bool h264_get_xps_id( const uint8_t *p_buf, size_t i_buf, uint8_t *pi_id )
return !bs_error( &bs ) && *pi_id <= i_max;
}
uint8_t h264_get_sps_id( const h264_sequence_parameter_set_t *p_sps )
{
return p_sps->i_id;
}
uint8_t h264_get_pps_sps_id( const h264_picture_parameter_set_t *p_pps )
{
return p_pps->i_sps_id;
}
static const h264_level_limits_t * h264_get_level_limits( const h264_sequence_parameter_set_t *p_sps )
{
uint16_t i_level_number = p_sps->i_level;
......@@ -845,6 +854,37 @@ bool h264_get_dpb_values( const h264_sequence_parameter_set_t *p_sps,
return true;
}
unsigned h264_get_max_frame_num( const h264_sequence_parameter_set_t *p_sps )
{
return 1 << (p_sps->i_log2_max_frame_num + 4);
}
bool h264_is_frames_only( const h264_sequence_parameter_set_t *p_sps )
{
return p_sps->frame_mbs_only_flag;
}
bool h264_using_adaptive_frames( const h264_sequence_parameter_set_t *p_sps )
{
return p_sps->mb_adaptive_frame_field_flag;
}
bool h264_get_sps_profile_tier_level( const h264_sequence_parameter_set_t *p_sps,
uint8_t *pi_profile, uint8_t *pi_level)
{
*pi_profile = p_sps->i_profile;
*pi_level = p_sps->i_level;
return true;
}
bool h264_get_constraints_set( const h264_sequence_parameter_set_t *p_sps,
uint8_t *pi_constraints )
{
*pi_constraints = p_sps->i_constraint_set_flags;
return true;
}
bool h264_get_picture_size( const h264_sequence_parameter_set_t *p_sps,
unsigned *p_ox, unsigned *p_oy,
unsigned *p_w, unsigned *p_h,
......@@ -881,6 +921,27 @@ bool h264_get_picture_size( const h264_sequence_parameter_set_t *p_sps,
return true;
}
bool h264_get_frame_rate( const h264_sequence_parameter_set_t *p_sps,
unsigned *pi_num, unsigned *pi_den )
{
if(!p_sps->vui_parameters_present_flag || !p_sps->vui.i_num_units_in_tick ||
p_sps->vui.i_time_scale <= 1)
return false;
*pi_num = p_sps->vui.i_time_scale;
*pi_den = p_sps->vui.i_num_units_in_tick;
return true;
}
bool h264_get_aspect_ratio( const h264_sequence_parameter_set_t *p_sps,
unsigned *pi_num, unsigned *pi_den )
{
if(!p_sps->vui.i_sar_num || !p_sps->vui.i_sar_den)
return false;
*pi_num = p_sps->vui.i_sar_num;
*pi_den = p_sps->vui.i_sar_den;
return true;
}
bool h264_get_chroma_luma( const h264_sequence_parameter_set_t *p_sps, uint8_t *pi_chroma_format,
uint8_t *pi_depth_luma, uint8_t *pi_depth_chroma )
{
......@@ -895,7 +956,7 @@ bool h264_get_colorimetry( const h264_sequence_parameter_set_t *p_sps,
video_color_space_t *p_colorspace,
video_color_range_t *p_full_range )
{
if( !p_sps->vui.b_valid )
if( !p_sps->vui_parameters_present_flag )
return false;
*p_primaries =
iso_23001_8_cp_to_vlc_primaries( p_sps->vui.colour.i_colour_primaries );
......@@ -952,3 +1013,24 @@ bool h264_decode_sei_recovery_point( bs_t *p_bs, h264_sei_recovery_point_t *p_re
//int i_changing_slice_group = bs_read( p_bs, 2 );
return true;
}
bool h264_decode_sei_pic_timing( bs_t *p_bs,
const h264_sequence_parameter_set_t *p_sps,
uint8_t *pic_struct, uint8_t *output_delay )
{
if( !p_sps->vui_parameters_present_flag )
return false;
if( p_sps->vui.b_hrd_parameters_present_flag )
{
bs_read( p_bs, p_sps->vui.i_cpb_removal_delay_length_minus1 + 1 );
*output_delay =
bs_read( p_bs, p_sps->vui.i_dpb_output_delay_length_minus1 + 1 );
}
if( p_sps->vui.b_pic_struct_present_flag )
*pic_struct = bs_read( p_bs, 4 );
/* + unparsed remains */
return true;
}
......@@ -99,6 +99,9 @@ void h264_release_sps( h264_sequence_parameter_set_t * );
void h264_release_pps( h264_picture_parameter_set_t * );
void h264_release_sps_extension( h264_sequence_parameter_set_extension_t * );
uint8_t h264_get_sps_id( const h264_sequence_parameter_set_t * );
uint8_t h264_get_pps_sps_id( const h264_picture_parameter_set_t * );
struct h264_sequence_parameter_set_t
{
uint8_t i_id;
......@@ -130,8 +133,8 @@ struct h264_sequence_parameter_set_t
int32_t offset_for_ref_frame[255];
int i_log2_max_pic_order_cnt_lsb;
bool vui_parameters_present_flag;
struct {
bool b_valid;
int i_sar_num, i_sar_den;
struct {
bool b_full_range;
......@@ -207,10 +210,22 @@ uint8_t * h264_avcC_to_AnnexB_NAL( const uint8_t *p_buf, size_t i_buf,
bool h264_get_dpb_values( const h264_sequence_parameter_set_t *,
uint8_t *pi_depth, unsigned *pi_delay );
unsigned h264_get_max_frame_num( const h264_sequence_parameter_set_t * );
bool h264_is_frames_only( const h264_sequence_parameter_set_t * );
bool h264_using_adaptive_frames( const h264_sequence_parameter_set_t * );
bool h264_get_sps_profile_tier_level( const h264_sequence_parameter_set_t *,
uint8_t *pi_profile, uint8_t *pi_level );
bool h264_get_constraints_set( const h264_sequence_parameter_set_t *p_sps,
uint8_t *pi_constraints );
bool h264_get_picture_size( const h264_sequence_parameter_set_t *,
unsigned *p_ox, unsigned *p_oy,
unsigned *p_w, unsigned *p_h,
unsigned *p_vw, unsigned *p_vh );
bool h264_get_frame_rate( const h264_sequence_parameter_set_t *,
unsigned *pi_num, unsigned *pi_den );
bool h264_get_aspect_ratio( const h264_sequence_parameter_set_t *,
unsigned *pi_num, unsigned *pi_den );
bool h264_get_chroma_luma( const h264_sequence_parameter_set_t *, uint8_t *pi_chroma_format,
uint8_t *pi_depth_luma, uint8_t *pi_depth_chroma );
bool h264_get_colorimetry( const h264_sequence_parameter_set_t *p_sps,
......@@ -229,6 +244,9 @@ typedef struct
} h264_sei_recovery_point_t;
bool h264_decode_sei_recovery_point( bs_t *, h264_sei_recovery_point_t * );
bool h264_decode_sei_pic_timing( bs_t *, const h264_sequence_parameter_set_t *,
uint8_t *, uint8_t * );
#ifdef __cplusplus
}
......
......@@ -29,14 +29,84 @@
#include "hxxx_nal.h"
#include "hxxx_ep3b.h"
bool h264_decode_slice( const uint8_t *p_buffer, size_t i_buffer,
void (* get_sps_pps)(uint8_t, void *,
struct h264_slice_s
{
int i_nal_type;
int i_nal_ref_idc;
int type;
int i_pic_parameter_set_id;
unsigned i_frame_num;
int i_field_pic_flag;
int i_bottom_field_flag;
int i_idr_pic_id;
int i_pic_order_cnt_type;
int i_pic_order_cnt_lsb;
int i_delta_pic_order_cnt_bottom;
int i_delta_pic_order_cnt0;
int i_delta_pic_order_cnt1;
bool no_output_of_prior_pics_flag;
bool has_mmco5;
};
enum h264_slice_type_e h264_get_slice_type( const h264_slice_t *p_slice )
{
return p_slice->type;
}
bool h264_has_mmco5( const h264_slice_t *p_slice )
{
return p_slice->has_mmco5;
}
bool h264_is_field_pic( const h264_slice_t *p_slice )
{
return p_slice->i_field_pic_flag;
}
int h264_get_slice_pps_id( const h264_slice_t *p_slice )
{
return p_slice->i_pic_parameter_set_id;
}
unsigned h264_get_frame_num( const h264_slice_t *p_slice )
{
return p_slice->i_frame_num;
}
unsigned h264_get_nal_ref_idc( const h264_slice_t *p_slice )
{
return p_slice->i_nal_ref_idc;
}
void h264_slice_release( h264_slice_t *p_slice )
{
free( p_slice );
}
void h264_slice_copy_idr_id( const h264_slice_t *src, h264_slice_t *dst )
{
if( !src || src->i_nal_type != H264_NAL_SLICE_IDR ) /* value only set on IDR */
return;
dst->i_idr_pic_id = src->i_idr_pic_id;
}
h264_slice_t * h264_decode_slice( const uint8_t *p_buffer, size_t i_buffer,
void (* get_sps_pps)(uint8_t, void *,
const h264_sequence_parameter_set_t **,
const h264_picture_parameter_set_t ** ),
void *priv, h264_slice_t *p_slice )
void *priv )
{
h264_slice_t *p_slice = calloc( 1, sizeof(*p_slice) );
if( !p_slice )
return NULL;
int i_slice_type;
h264_slice_init( p_slice );
bs_t s;
struct hxxx_bsfw_ep3b_ctx_s bsctx;
hxxx_bsfw_ep3b_ctx_init( &bsctx );
......@@ -52,6 +122,8 @@ bool h264_decode_slice( const uint8_t *p_buffer, size_t i_buffer,
/* slice_type */
i_slice_type = bs_read_ue( &s );
if( i_slice_type > 9 )
goto error;
p_slice->type = i_slice_type % 5;
/* */
......@@ -60,7 +132,7 @@ bool h264_decode_slice( const uint8_t *p_buffer, size_t i_buffer,
p_slice->i_pic_parameter_set_id = bs_read_ue( &s );
if( p_slice->i_pic_parameter_set_id > H264_PPS_ID_MAX )
return false;
goto error;
const h264_sequence_parameter_set_t *p_sps;
const h264_picture_parameter_set_t *p_pps;
......@@ -68,7 +140,7 @@ bool h264_decode_slice( const uint8_t *p_buffer, size_t i_buffer,
/* Bind matched/referred PPS and SPS */
get_sps_pps( p_slice->i_pic_parameter_set_id, priv, &p_sps, &p_pps );
if( !p_sps || !p_pps )
return false;
goto error;
p_slice->i_frame_num = bs_read( &s, p_sps->i_log2_max_frame_num + 4 );
......@@ -81,7 +153,11 @@ bool h264_decode_slice( const uint8_t *p_buffer, size_t i_buffer,
}
if( p_slice->i_nal_type == H264_NAL_SLICE_IDR )
{
p_slice->i_idr_pic_id = bs_read_ue( &s );
if( p_slice->i_idr_pic_id > 65535 )
goto error;
}
p_slice->i_pic_order_cnt_type = p_sps->i_pic_order_cnt_type;
if( p_sps->i_pic_order_cnt_type == 0 )
......@@ -122,7 +198,7 @@ bool h264_decode_slice( const uint8_t *p_buffer, size_t i_buffer,
{
/* Early END, don't waste parsing below */
p_slice->has_mmco5 = false;
return true;
return p_slice;
}
/* ref_pic_list_[mvc_]modification() */
......@@ -149,7 +225,7 @@ bool h264_decode_slice( const uint8_t *p_buffer, size_t i_buffer,
}
if( bs_error( &s ) )
return false;
goto error;
/* pred_weight_table() */
if( ( p_pps->weighted_pred_flag && ( i_slice_type == 0 || i_slice_type == 5 || /* P, SP */
......@@ -198,6 +274,8 @@ bool h264_decode_slice( const uint8_t *p_buffer, size_t i_buffer,
do
{
mmco = bs_read_ue( &s );
if( mmco > 6 )
goto error;
if( mmco == 1 || mmco == 3 )
bs_read_ue( &s ); /* diff_pics_minus1 */
if( mmco == 2 )
......@@ -218,7 +296,13 @@ bool h264_decode_slice( const uint8_t *p_buffer, size_t i_buffer,
/* If you need to store anything else than MMCO presence above, care of "Early END" cases */
return !bs_error( &s );
if(bs_error( &s ))
goto error;
return p_slice;
error:
h264_slice_release( p_slice );
return NULL;
}
......@@ -383,3 +467,49 @@ uint8_t h264_get_num_ts( const h264_sequence_parameter_set_t *p_sps,
const uint8_t rgi_numclock[9] = { 2, 1, 1, 2, 2, 3, 3, 4, 6 };
return rgi_numclock[ i_pic_struct ];
}
bool h264_slice_top_field( const h264_slice_t *p_slice )
{
return !p_slice->i_bottom_field_flag;
}
bool h264_IsFirstVCLNALUnit( const h264_slice_t *p_prev, const h264_slice_t *p_cur )
{
/* Detection of the first VCL NAL unit of a primary coded picture
* (cf. 7.4.1.2.4) */
if( !p_prev )
return true;
if( p_cur->i_frame_num != p_prev->i_frame_num ||
p_cur->i_pic_parameter_set_id != p_prev->i_pic_parameter_set_id ||
p_cur->i_field_pic_flag != p_prev->i_field_pic_flag ||
!p_cur->i_nal_ref_idc != !p_prev->i_nal_ref_idc )
return true;
if( p_cur->i_field_pic_flag && /* present in both and differs in value */
p_cur->i_bottom_field_flag != p_prev->i_bottom_field_flag )
return true;
if( p_cur->i_pic_order_cnt_type == p_prev->i_pic_order_cnt_type )
{
if( p_cur->i_pic_order_cnt_type == 0 &&
( p_cur->i_pic_order_cnt_lsb != p_prev->i_pic_order_cnt_lsb ||
p_cur->i_delta_pic_order_cnt_bottom != p_prev->i_delta_pic_order_cnt_bottom ) )
return true;
else if( p_cur->i_pic_order_cnt_type == 1 &&
( p_cur->i_delta_pic_order_cnt0 != p_prev->i_delta_pic_order_cnt0 ||
p_cur->i_delta_pic_order_cnt1 != p_prev->i_delta_pic_order_cnt1 ) )
return true;
}
if( ( p_cur->i_nal_type == H264_NAL_SLICE_IDR || p_prev->i_nal_type == H264_NAL_SLICE_IDR ) &&
( p_cur->i_nal_type != p_prev->i_nal_type || p_cur->i_idr_pic_id != p_prev->i_idr_pic_id ) )
return true;
return false;
}
bool h264_CanSwapPTSWithDTS( const h264_slice_t *p_slice, const h264_sequence_parameter_set_t *p_sps )
{
if( p_slice->i_nal_ref_idc == 0 && p_slice->type == H264_SLICE_TYPE_B )
return true;
else if( p_sps->vui_parameters_present_flag )
return p_sps->vui.i_max_num_reorder_frames == 0;
else
return p_sps->i_profile == PROFILE_H264_CAVLC_INTRA;
}
......@@ -30,54 +30,33 @@ enum h264_slice_type_e
H264_SLICE_TYPE_UNKNOWN,
};
typedef struct
{
int i_nal_type;
int i_nal_ref_idc;
enum h264_slice_type_e type;
int i_pic_parameter_set_id;
unsigned i_frame_num;
typedef struct h264_slice_s h264_slice_t;
int i_field_pic_flag;
int i_bottom_field_flag;
enum h264_slice_type_e h264_get_slice_type( const h264_slice_t *p_slice );
int i_idr_pic_id;
enum h264_slice_struct_e
{
H264_SLICE_FRAME,
H264_SLICE_FIELD,
H264_SLICE_MBAFF,
};
int i_pic_order_cnt_type;
int i_pic_order_cnt_lsb;
int i_delta_pic_order_cnt_bottom;
enum h264_slice_struct_e h264_get_slice_struct( const h264_slice_t *p_slice );
bool h264_is_field_pic( const h264_slice_t *p_slice );
int i_delta_pic_order_cnt0;
int i_delta_pic_order_cnt1;
int h264_get_slice_pps_id( const h264_slice_t *p_slice );
unsigned h264_get_frame_num( const h264_slice_t *p_slice );
unsigned h264_get_nal_ref_idc( const h264_slice_t *p_slice );
bool h264_has_mmco5( const h264_slice_t *p_slice );
void h264_slice_release( h264_slice_t *p_slice );
void h264_slice_copy_idr_id( const h264_slice_t *src, h264_slice_t *dst );
bool no_output_of_prior_pics_flag;
bool has_mmco5;
} h264_slice_t;
static inline void h264_slice_init( h264_slice_t *p_slice )
{
p_slice->i_nal_type = -1;
p_slice->i_nal_ref_idc = -1;
p_slice->i_idr_pic_id = -1;
p_slice->i_frame_num = 0;
p_slice->type = H264_SLICE_TYPE_UNKNOWN;
p_slice->i_pic_parameter_set_id = -1;
p_slice->i_field_pic_flag = 0;
p_slice->i_bottom_field_flag = -1;
p_slice->i_pic_order_cnt_type = -1;
p_slice->i_pic_order_cnt_lsb = -1;
p_slice->i_delta_pic_order_cnt_bottom = -1;
p_slice->i_delta_pic_order_cnt0 = 0;
p_slice->i_delta_pic_order_cnt1 = 0;
p_slice->has_mmco5 = false;
}
bool h264_decode_slice( const uint8_t *p_buffer, size_t i_buffer,
h264_slice_t * h264_decode_slice( const uint8_t *p_buffer, size_t i_buffer,
void (* get_sps_pps)(uint8_t pps_id, void *,
const h264_sequence_parameter_set_t **,
const h264_picture_parameter_set_t ** ),
void *, h264_slice_t *p_slice );
void * );
typedef struct
{
......@@ -110,4 +89,10 @@ void h264_compute_poc( const h264_sequence_parameter_set_t *p_sps,
uint8_t h264_get_num_ts( const h264_sequence_parameter_set_t *p_sps,
const h264_slice_t *p_slice, uint8_t pic_struct, int tFOC, int bFOC );
bool h264_slice_top_field( const h264_slice_t *p_slice );
bool h264_IsFirstVCLNALUnit( const h264_slice_t *p_prev, const h264_slice_t *p_cur );
bool h264_CanSwapPTSWithDTS( const h264_slice_t *p_slice, const h264_sequence_parameter_set_t * );
#endif
/*****************************************************************************
* h26x_nal_common.h: h26x shared code
*****************************************************************************
* Copyright © 2010-2024 VideoLabs, VideoLAN and VLC Authors
*
* 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 H26X_NAL_COMMON_H
# define H26X_NAL_COMMON_H
#include <vlc_common.h>
#include "iso_color_tables.h"
typedef uint8_t nal_u1_t;
typedef uint8_t nal_u2_t;
typedef uint8_t nal_u3_t;
typedef uint8_t nal_u4_t;
typedef uint8_t nal_u5_t;
typedef uint8_t nal_u6_t;
typedef uint8_t nal_u7_t;
typedef uint8_t nal_u8_t;
typedef int32_t nal_se_t;
typedef uint32_t nal_ue_t;
typedef struct
{
nal_ue_t left_offset;
nal_ue_t right_offset;
nal_ue_t top_offset;
nal_ue_t bottom_offset;
} h26x_conf_window_t;
static inline
bool h26x_get_picture_size( nal_u2_t chroma_format_idc,
nal_ue_t pic_width_in_luma_samples,
nal_ue_t pic_height_in_luma_samples,
const h26x_conf_window_t *conf_win,
unsigned *p_ox, unsigned *p_oy,
unsigned *p_w, unsigned *p_h,
unsigned *p_vw, unsigned *p_vh )
{
unsigned ox, oy, w, h, vw, vh;
w = vw = pic_width_in_luma_samples;
h = vh = pic_height_in_luma_samples;
static const uint8_t SubWidthHeight[4][2] = { {1, 1}, {2, 2}, {2, 1}, {1, 1} };
ox = conf_win->left_offset * SubWidthHeight[chroma_format_idc][0];
oy = conf_win->top_offset * SubWidthHeight[chroma_format_idc][1];
vw -= (conf_win->left_offset + conf_win->right_offset) *
SubWidthHeight[chroma_format_idc][0];
vh -= (conf_win->bottom_offset + conf_win->top_offset) *
SubWidthHeight[chroma_format_idc][1];
if ( vw > w || vh > h )
return false;
*p_ox = ox; *p_oy = oy;
*p_w = w; *p_h = h;
*p_vw = vw; *p_vh = vh;
return true;
}
typedef struct
{
nal_u8_t aspect_ratio_idc;
uint16_t sar_width;
uint16_t sar_height;
} h26x_aspect_ratio_t;
static inline
bool h26x_get_aspect_ratio( const h26x_aspect_ratio_t *ar,
unsigned *num, unsigned *den )
{
if( ar->aspect_ratio_idc != 255 )
{
static const uint8_t ar_table[16][2] =
{
{ 1, 1 },
{ 12, 11 },
{ 10, 11 },
{ 16, 11 },
{ 40, 33 },
{ 24, 11 },
{ 20, 11 },
{ 32, 11 },
{ 80, 33 },
{ 18, 11 },
{ 15, 11 },
{ 64, 33 },
{ 160, 99 },
{ 4, 3 },
{ 3, 2 },
{ 2, 1 },
};
if( ar->aspect_ratio_idc == 0 ||
ar->aspect_ratio_idc >= 17 )
return false;
*num = ar_table[ar->aspect_ratio_idc - 1][0];
*den = ar_table[ar->aspect_ratio_idc - 1][1];
}
else
{
*num = ar->sar_width;
*den = ar->sar_height;
}
return true;
}
typedef struct
{
nal_u8_t colour_primaries;
nal_u8_t transfer_characteristics;
nal_u8_t matrix_coeffs;
nal_u1_t full_range_flag;
} h26x_colour_description_t;
static inline
bool h26x_get_colorimetry( const h26x_colour_description_t *colour,
video_color_primaries_t *p_primaries,
video_transfer_func_t *p_transfer,
video_color_space_t *p_colorspace,
video_color_range_t *p_full_range )
{
*p_primaries =
iso_23001_8_cp_to_vlc_primaries( colour->colour_primaries );
*p_transfer =
iso_23001_8_tc_to_vlc_xfer( colour->transfer_characteristics );
*p_colorspace =
iso_23001_8_mc_to_vlc_coeffs( colour->matrix_coeffs );
*p_full_range = colour->full_range_flag ? COLOR_RANGE_FULL : COLOR_RANGE_LIMITED;
return true;
}
#endif
......@@ -120,7 +120,6 @@ static block_t *GetXPSCopy(decoder_sys_t *);
#define BLOCK_FLAG_DROP (1 << BLOCK_FLAG_PRIVATE_SHIFT)
static const uint8_t p_hevc_startcode[3] = {0x00, 0x00, 0x01};
/****************************************************************************
* Helpers
****************************************************************************/
......@@ -220,8 +219,8 @@ static int Open(vlc_object_t *p_this)
INITQ(post);
packetizer_Init(&p_sys->packetizer,
p_hevc_startcode, sizeof(p_hevc_startcode), startcode_FindAnnexB,
p_hevc_startcode, 1, 5,
annexb_startcode3, 3, startcode_FindAnnexB,
annexb_startcode3, 1, 5,
PacketizeReset, PacketizeParse, PacketizeValidate, PacketizeDrain,
p_dec);
......
......@@ -24,9 +24,9 @@
#include <stdbit.h>
#include "hevc_nal.h"
#include "h26x_nal_common.h"
#include "hxxx_nal.h"
#include "hxxx_ep3b.h"
#include "iso_color_tables.h"
#include <vlc_common.h>
#include <vlc_bits.h>
......@@ -35,17 +35,6 @@
//#define HEVC_POC_DEBUG
typedef uint8_t nal_u1_t;
typedef uint8_t nal_u2_t;
typedef uint8_t nal_u3_t;
typedef uint8_t nal_u4_t;
typedef uint8_t nal_u5_t;
typedef uint8_t nal_u6_t;
typedef uint8_t nal_u7_t;
typedef uint8_t nal_u8_t;
typedef int32_t nal_se_t;
typedef uint32_t nal_ue_t;
typedef struct
{
nal_u2_t profile_space;
......@@ -97,12 +86,7 @@ typedef struct
typedef struct
{
nal_u1_t aspect_ratio_info_present_flag;
struct
{
nal_u8_t aspect_ratio_idc;
uint16_t sar_width;
uint16_t sar_height;
} ar;
h26x_aspect_ratio_t ar;
nal_u1_t overscan_info_present_flag;
nal_u1_t overscan_appropriate_flag;
......@@ -110,14 +94,8 @@ typedef struct
struct
{
nal_u3_t video_format;
nal_u1_t video_full_range_flag;
nal_u1_t colour_description_present_flag;
struct
{
nal_u8_t colour_primaries;
nal_u8_t transfer_characteristics;
nal_u8_t matrix_coeffs;
} colour;
h26x_colour_description_t colour;
} vs;
nal_u1_t chroma_loc_info_present_flag;
......@@ -197,13 +175,7 @@ struct hevc_sequence_parameter_set_t
nal_ue_t pic_height_in_luma_samples;
nal_u1_t conformance_window_flag;
struct
{
nal_ue_t left_offset;
nal_ue_t right_offset;
nal_ue_t top_offset;
nal_ue_t bottom_offset;
} conf_win;
h26x_conf_window_t conf_win;
nal_ue_t bit_depth_luma_minus8;
nal_ue_t bit_depth_chroma_minus8;
......@@ -461,7 +433,7 @@ static bool hevc_parse_vui_parameters_rbsp( bs_t *p_bs, hevc_vui_parameters_t *p
if( p_vui->video_signal_type_present_flag )
{
p_vui->vs.video_format = bs_read( p_bs, 3 );
p_vui->vs.video_full_range_flag = bs_read1( p_bs );
p_vui->vs.colour.full_range_flag = bs_read1( p_bs );
p_vui->vs.colour_description_present_flag = bs_read1( p_bs );
if( p_vui->vs.colour_description_present_flag )
{
......@@ -1065,38 +1037,11 @@ bool hevc_get_picture_size( const hevc_sequence_parameter_set_t *p_sps,
unsigned *p_w, unsigned *p_h,
unsigned *p_vw, unsigned *p_vh )
{
*p_w = *p_vw = p_sps->pic_width_in_luma_samples;
*p_h = *p_vh = p_sps->pic_height_in_luma_samples;
if( p_sps->conformance_window_flag )
{
unsigned sub_width_c, sub_height_c;
if( p_sps->chroma_format_idc == 1 )
{
sub_width_c = 2;
sub_height_c = 2;
}
else if( p_sps->chroma_format_idc == 2 )
{
sub_width_c = 2;
sub_height_c = 1;
}
else
{
sub_width_c = 1;
sub_height_c = 1;
}
*p_oy = p_sps->conf_win.top_offset * sub_height_c;
*p_ox = p_sps->conf_win.left_offset * sub_width_c;
*p_vh -= (p_sps->conf_win.bottom_offset + p_sps->conf_win.top_offset) * sub_height_c;
*p_vw -= (p_sps->conf_win.left_offset + p_sps->conf_win.right_offset) * sub_width_c;
}
else
{
*p_oy = *p_ox = 0;
}
return true;
return h26x_get_picture_size( p_sps->chroma_format_idc,
p_sps->pic_width_in_luma_samples,
p_sps->pic_height_in_luma_samples,
&p_sps->conf_win,
p_ox, p_oy, p_w, p_h, p_vw, p_vh );
}
void hevc_get_dpb_values( const hevc_sequence_parameter_set_t *p_sps, uint8_t *max_num_reorder_pics,
......@@ -1152,45 +1097,9 @@ bool hevc_get_frame_rate( const hevc_sequence_parameter_set_t *p_sps,
bool hevc_get_aspect_ratio( const hevc_sequence_parameter_set_t *p_sps,
unsigned *num, unsigned *den )
{
if( p_sps->vui_parameters_present_flag )
{
if( p_sps->vui.ar.aspect_ratio_idc != 255 )
{
static const uint8_t ar_table[16][2] =
{
{ 1, 1 },
{ 12, 11 },
{ 10, 11 },
{ 16, 11 },
{ 40, 33 },
{ 24, 11 },
{ 20, 11 },
{ 32, 11 },
{ 80, 33 },
{ 18, 11 },
{ 15, 11 },
{ 64, 33 },
{ 160, 99 },
{ 4, 3 },
{ 3, 2 },
{ 2, 1 },
};
if( p_sps->vui.ar.aspect_ratio_idc > 0 &&
p_sps->vui.ar.aspect_ratio_idc < 17 )
{
*num = ar_table[p_sps->vui.ar.aspect_ratio_idc - 1][0];
*den = ar_table[p_sps->vui.ar.aspect_ratio_idc - 1][1];
return true;
}
}
else
{
*num = p_sps->vui.ar.sar_width;
*den = p_sps->vui.ar.sar_height;
return true;
}
}
return false;
if( !p_sps->vui_parameters_present_flag )
return false;
return h26x_get_aspect_ratio( &p_sps->vui.ar, num, den );
}
bool hevc_get_chroma_luma( const hevc_sequence_parameter_set_t *p_sps, uint8_t *pi_chroma_format,
......@@ -1210,14 +1119,8 @@ bool hevc_get_colorimetry( const hevc_sequence_parameter_set_t *p_sps,
{
if( !p_sps->vui_parameters_present_flag )
return false;
*p_primaries =
iso_23001_8_cp_to_vlc_primaries( p_sps->vui.vs.colour.colour_primaries );
*p_transfer =
iso_23001_8_tc_to_vlc_xfer( p_sps->vui.vs.colour.transfer_characteristics );
*p_colorspace =
iso_23001_8_mc_to_vlc_coeffs( p_sps->vui.vs.colour.matrix_coeffs );
*p_full_range = p_sps->vui.vs.video_full_range_flag ? COLOR_RANGE_FULL : COLOR_RANGE_LIMITED;
return true;
return h26x_get_colorimetry( &p_sps->vui.vs.colour,
p_primaries, p_transfer, p_colorspace, p_full_range );
}
static bool hevc_parse_slice_segment_header_rbsp( bs_t *p_bs,
......
......@@ -40,7 +40,7 @@
#include <vlc_block_helper.h>
#include "packetizer_helper.h"
#include "startcode_helper.h"
#include "iso_color_tables.h"
#include "h26x_nal_common.h"
/*****************************************************************************
* Module descriptor
......@@ -460,28 +460,32 @@ static int ParseVO( decoder_t *p_dec, block_t *p_vo )
if( visual_object_type == 1 /* video ID */ ||
visual_object_type == 2 /* still texture ID */ )
{
uint8_t colour_primaries = 1;
uint8_t colour_xfer = 1;
uint8_t colour_matrix_coeff = 1;
uint8_t full_range = 0;
h26x_colour_description_t colour =
{
.colour_primaries = 1,
.transfer_characteristics = 1,
.matrix_coeffs = 1,
.full_range_flag = 0,
};
if( bs_read1( &s ) ) /* video_signal_type */
{
bs_read( &s, 3 );
full_range = bs_read( &s, 1 );
colour.full_range_flag = bs_read( &s, 1 );
if( bs_read( &s, 1 ) ) /* colour description */
{
colour_primaries = bs_read( &s, 8 );
colour_xfer = bs_read( &s, 8 );
colour_matrix_coeff = bs_read( &s, 8 );
colour.colour_primaries = bs_read( &s, 8 );
colour.transfer_characteristics = bs_read( &s, 8 );
colour.matrix_coeffs = bs_read( &s, 8 );
}
}
if( p_dec->fmt_in->video.primaries == COLOR_PRIMARIES_UNDEF )
{
p_dec->fmt_out.video.primaries = iso_23001_8_cp_to_vlc_primaries( colour_primaries );
p_dec->fmt_out.video.transfer = iso_23001_8_tc_to_vlc_xfer( colour_xfer );
p_dec->fmt_out.video.space = iso_23001_8_mc_to_vlc_coeffs( colour_matrix_coeff );
p_dec->fmt_out.video.color_range = full_range ? COLOR_RANGE_FULL : COLOR_RANGE_LIMITED;
h26x_get_colorimetry( &colour,
&p_dec->fmt_out.video.primaries,
&p_dec->fmt_out.video.transfer,
&p_dec->fmt_out.video.space,
&p_dec->fmt_out.video.color_range );
}
}
......
......@@ -54,7 +54,7 @@
#include "../codec/cc.h"
#include "packetizer_helper.h"
#include "startcode_helper.h"
#include "iso_color_tables.h"
#include "h26x_nal_common.h"
#include <limits.h>
......@@ -947,17 +947,20 @@ static block_t *ParseMPEGBlock( decoder_t *p_dec, block_t *p_frag )
/* Sequence display extension */
bool contains_color_description = (p_frag->p_buffer[4] & 0x01);
//uint8_t video_format = (p_frag->p_buffer[4] & 0x0f) >> 1;
if( contains_color_description && p_frag->i_buffer > 11 )
{
p_dec->fmt_out.video.primaries =
iso_23001_8_cp_to_vlc_primaries( p_frag->p_buffer[5] );
p_dec->fmt_out.video.transfer =
iso_23001_8_tc_to_vlc_xfer( p_frag->p_buffer[6] );
p_dec->fmt_out.video.space =
iso_23001_8_mc_to_vlc_coeffs( p_frag->p_buffer[7] );
h26x_colour_description_t colour;
colour.colour_primaries = p_frag->p_buffer[5];
colour.transfer_characteristics = p_frag->p_buffer[6];
colour.matrix_coeffs = p_frag->p_buffer[7];
colour.full_range_flag = 0;
video_color_range_t range;
h26x_get_colorimetry( &colour,
&p_dec->fmt_out.video.primaries,
&p_dec->fmt_out.video.transfer,
&p_dec->fmt_out.video.space,
&range );
}
}
}
else if( startcode == USER_DATA_STARTCODE && p_frag->i_buffer > 8 )
......