diff options
-rw-r--r-- | contrib/ffmpeg/A00-qsv.patch | 20 | ||||
-rw-r--r-- | contrib/ffmpeg/A01-encoding-tool-tag.patch | 40 | ||||
-rw-r--r-- | contrib/ffmpeg/A02-hevcmux.patch | 1411 | ||||
-rw-r--r-- | contrib/ffmpeg/P01-solaris.patch | 4 | ||||
-rw-r--r-- | contrib/ffmpeg/P02-darwin-pic.patch | 6 | ||||
-rw-r--r-- | contrib/ffmpeg/module.defs | 2 |
6 files changed, 16 insertions, 1467 deletions
diff --git a/contrib/ffmpeg/A00-qsv.patch b/contrib/ffmpeg/A00-qsv.patch index 95289a15d..e8f04270d 100644 --- a/contrib/ffmpeg/A00-qsv.patch +++ b/contrib/ffmpeg/A00-qsv.patch @@ -1,5 +1,5 @@ diff --git a/configure b/configure -index 945a012..3fdc346 100755 +index c6789d5..d1a8661 100755 --- a/configure +++ b/configure @@ -132,6 +132,7 @@ Component options: @@ -10,7 +10,7 @@ index 945a012..3fdc346 100755 --enable-vaapi enable VAAPI code --enable-vda enable VDA code --enable-vdpau enable VDPAU code -@@ -1137,6 +1138,7 @@ EXTERNAL_LIBRARY_LIST=" +@@ -1139,6 +1140,7 @@ EXTERNAL_LIBRARY_LIST=" HWACCEL_LIST=" dxva2 @@ -18,7 +18,7 @@ index 945a012..3fdc346 100755 vaapi vda vdpau -@@ -1797,6 +1799,7 @@ zmbv_encoder_deps="zlib" +@@ -1800,6 +1802,7 @@ zmbv_encoder_deps="zlib" # hardware accelerators dxva2_deps="dxva2api_h" @@ -26,7 +26,7 @@ index 945a012..3fdc346 100755 vaapi_deps="va_va_h" vda_deps="VideoDecodeAcceleration_VDADecoder_h pthreads" vda_extralibs="-framework CoreFoundation -framework VideoDecodeAcceleration -framework QuartzCore" -@@ -1808,6 +1811,8 @@ h263_vdpau_hwaccel_deps="vdpau" +@@ -1811,6 +1814,8 @@ h263_vdpau_hwaccel_deps="vdpau" h263_vdpau_hwaccel_select="h263_decoder" h264_dxva2_hwaccel_deps="dxva2" h264_dxva2_hwaccel_select="h264_decoder" @@ -35,7 +35,7 @@ index 945a012..3fdc346 100755 h264_vaapi_hwaccel_deps="vaapi" h264_vaapi_hwaccel_select="h264_decoder" h264_vda_hwaccel_deps="vda" -@@ -3853,6 +3858,7 @@ check_header dxva.h +@@ -3861,6 +3866,7 @@ check_header dxva.h check_header dxva2api.h check_header io.h check_header malloc.h @@ -44,7 +44,7 @@ index 945a012..3fdc346 100755 check_header sys/mman.h check_header sys/param.h diff --git a/libavcodec/Makefile b/libavcodec/Makefile -index 75426c4..87bbc81 100644 +index 9e4dd25..1fbee4a 100644 --- a/libavcodec/Makefile +++ b/libavcodec/Makefile @@ -4,6 +4,7 @@ FFLIBS = avutil @@ -63,7 +63,7 @@ index 75426c4..87bbc81 100644 OBJS-$(CONFIG_RANGECODER) += rangecoder.o RDFT-OBJS-$(CONFIG_HARDCODED_TABLES) += sin_tables.o OBJS-$(CONFIG_RDFT) += rdft.o $(RDFT-OBJS-yes) -@@ -198,6 +200,7 @@ OBJS-$(CONFIG_H264_DECODER) += h264.o \ +@@ -199,6 +201,7 @@ OBJS-$(CONFIG_H264_DECODER) += h264.o \ h264_loopfilter.o h264_direct.o \ cabac.o h264_sei.o h264_ps.o \ h264_refs.o h264_cavlc.o h264_cabac.o @@ -71,7 +71,7 @@ index 75426c4..87bbc81 100644 OBJS-$(CONFIG_HEVC_DECODER) += hevc.o hevc_mvs.o hevc_ps.o hevc_sei.o \ hevc_cabac.o hevc_refs.o hevcpred.o \ hevcdsp.o hevc_filter.o cabac.o -@@ -691,6 +694,7 @@ SKIPHEADERS += %_tablegen.h \ +@@ -692,6 +695,7 @@ SKIPHEADERS += %_tablegen.h \ SKIPHEADERS-$(CONFIG_DXVA2) += dxva2.h dxva2_internal.h SKIPHEADERS-$(CONFIG_LIBSCHROEDINGER) += libschroedinger.h SKIPHEADERS-$(CONFIG_MPEG_XVMC_DECODER) += xvmc.h @@ -80,10 +80,10 @@ index 75426c4..87bbc81 100644 SKIPHEADERS-$(CONFIG_VDA) += vda.h SKIPHEADERS-$(CONFIG_VDPAU) += vdpau.h vdpau_internal.h diff --git a/libavcodec/allcodecs.c b/libavcodec/allcodecs.c -index 2e56ec1..e9053ac 100644 +index b6c27c0..287b912 100644 --- a/libavcodec/allcodecs.c +++ b/libavcodec/allcodecs.c -@@ -154,6 +154,7 @@ void avcodec_register_all(void) +@@ -155,6 +155,7 @@ void avcodec_register_all(void) REGISTER_DECODER(H263I, h263i); REGISTER_ENCODER(H263P, h263p); REGISTER_DECODER(H264, h264); diff --git a/contrib/ffmpeg/A01-encoding-tool-tag.patch b/contrib/ffmpeg/A01-encoding-tool-tag.patch deleted file mode 100644 index 8a9301150..000000000 --- a/contrib/ffmpeg/A01-encoding-tool-tag.patch +++ /dev/null @@ -1,40 +0,0 @@ -diff --git a/libavformat/matroskaenc.c b/libavformat/matroskaenc.c -index cc645a5..3ab3139 100644 ---- a/libavformat/matroskaenc.c -+++ b/libavformat/matroskaenc.c -@@ -805,7 +805,8 @@ static int mkv_write_tag(AVFormatContext *s, AVDictionary *m, unsigned int eleme - end_ebml_master(s->pb, targets); - - while ((t = av_dict_get(m, "", t, AV_DICT_IGNORE_SUFFIX))) -- if (av_strcasecmp(t->key, "title")) -+ if (av_strcasecmp(t->key, "title") && -+ av_strcasecmp(t->key, "encoding_tool")) - mkv_write_simpletag(s->pb, t); - - end_ebml_master(s->pb, tag); -@@ -965,7 +966,10 @@ static int mkv_write_header(AVFormatContext *s) - segment_uid[i] = av_lfg_get(&lfg); - - put_ebml_string(pb, MATROSKA_ID_MUXINGAPP , LIBAVFORMAT_IDENT); -- put_ebml_string(pb, MATROSKA_ID_WRITINGAPP, LIBAVFORMAT_IDENT); -+ if ((tag = av_dict_get(s->metadata, "encoding_tool", NULL, 0))) -+ put_ebml_string(pb, MATROSKA_ID_WRITINGAPP, tag->value); -+ else -+ put_ebml_string(pb, MATROSKA_ID_WRITINGAPP, LIBAVFORMAT_IDENT); - put_ebml_binary(pb, MATROSKA_ID_SEGMENTUID, segment_uid, 16); - } - -diff --git a/libavformat/movenc.c b/libavformat/movenc.c -index 43a1647..5bc0ca3 100644 ---- a/libavformat/movenc.c -+++ b/libavformat/movenc.c -@@ -1858,7 +1858,8 @@ static int mov_write_ilst_tag(AVIOContext *pb, MOVMuxContext *mov, - mov_write_string_metadata(s, pb, "\251wrt", "composer" , 1); - mov_write_string_metadata(s, pb, "\251alb", "album" , 1); - mov_write_string_metadata(s, pb, "\251day", "date" , 1); -- mov_write_string_tag(pb, "\251too", LIBAVFORMAT_IDENT, 0, 1); -+ if (!mov_write_string_metadata(s, pb, "\251too", "encoding_tool", 1)) -+ mov_write_string_tag(pb, "\251too", LIBAVFORMAT_IDENT, 0, 1); - mov_write_string_metadata(s, pb, "\251cmt", "comment" , 1); - mov_write_string_metadata(s, pb, "\251gen", "genre" , 1); - mov_write_string_metadata(s, pb, "\251cpy", "copyright", 1); diff --git a/contrib/ffmpeg/A02-hevcmux.patch b/contrib/ffmpeg/A02-hevcmux.patch deleted file mode 100644 index ddbc494eb..000000000 --- a/contrib/ffmpeg/A02-hevcmux.patch +++ /dev/null @@ -1,1411 +0,0 @@ -diff --git a/libavcodec/golomb.h b/libavcodec/golomb.h -index efe5059..ce3500f 100644 ---- a/libavcodec/golomb.h -+++ b/libavcodec/golomb.h -@@ -206,6 +206,18 @@ static inline int get_se_golomb(GetBitContext *gb) - } - } - -+static inline int get_se_golomb_long(GetBitContext *gb) -+{ -+ unsigned int buf = get_ue_golomb_long(gb); -+ -+ if (buf & 1) -+ buf = -(buf >> 1); -+ else -+ buf = (buf >> 1); -+ -+ return buf; -+} -+ - static inline int svq3_get_se_golomb(GetBitContext *gb) - { - unsigned int buf; -diff --git a/libavformat/Makefile b/libavformat/Makefile -index d491d43..5694314 100644 ---- a/libavformat/Makefile -+++ b/libavformat/Makefile -@@ -168,7 +168,7 @@ OBJS-$(CONFIG_M4V_MUXER) += rawenc.o - OBJS-$(CONFIG_MATROSKA_DEMUXER) += matroskadec.o matroska.o \ - isom.o rmsipr.o - OBJS-$(CONFIG_MATROSKA_MUXER) += matroskaenc.o matroska.o \ -- isom.o avc.o \ -+ isom.o avc.o hevc.o \ - flacenc_header.o avlanguage.o wv.o - OBJS-$(CONFIG_MD5_MUXER) += md5enc.o - OBJS-$(CONFIG_MJPEG_DEMUXER) += rawdec.o -@@ -179,7 +179,7 @@ OBJS-$(CONFIG_MM_DEMUXER) += mm.o - OBJS-$(CONFIG_MMF_DEMUXER) += mmf.o pcm.o - OBJS-$(CONFIG_MMF_MUXER) += mmf.o - OBJS-$(CONFIG_MOV_DEMUXER) += mov.o isom.o mov_chan.o --OBJS-$(CONFIG_MOV_MUXER) += movenc.o isom.o avc.o \ -+OBJS-$(CONFIG_MOV_MUXER) += movenc.o isom.o avc.o hevc.o \ - movenchint.o mov_chan.o - OBJS-$(CONFIG_MP2_MUXER) += mp3enc.o rawenc.o id3v2enc.o - OBJS-$(CONFIG_MP3_DEMUXER) += mp3dec.o -diff --git a/libavformat/hevc.c b/libavformat/hevc.c -new file mode 100644 -index 0000000..37b35b4 ---- /dev/null -+++ b/libavformat/hevc.c -@@ -0,0 +1,1140 @@ -+/* -+ * Copyright (c) 2014 Tim Walker <[email protected]> -+ * -+ * This file is part of Libav. -+ * -+ * Libav 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. -+ * -+ * Libav 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 Libav; if not, write to the Free Software -+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -+ */ -+ -+#include "libavcodec/get_bits.h" -+#include "libavcodec/golomb.h" -+#include "libavcodec/hevc.h" -+#include "libavutil/intreadwrite.h" -+#include "avc.h" -+#include "avio.h" -+#include "hevc.h" -+ -+#define MAX_SPATIAL_SEGMENTATION 4096 // max. value of u(12) field -+ -+typedef struct HVCCNALUnitArray { -+ uint8_t array_completeness; -+ uint8_t NAL_unit_type; -+ uint16_t numNalus; -+ uint16_t *nalUnitLength; -+ uint8_t **nalUnit; -+} HVCCNALUnitArray; -+ -+typedef struct HEVCDecoderConfigurationRecord { -+ uint8_t configurationVersion; -+ uint8_t general_profile_space; -+ uint8_t general_tier_flag; -+ uint8_t general_profile_idc; -+ uint32_t general_profile_compatibility_flags; -+ uint64_t general_constraint_indicator_flags; -+ uint8_t general_level_idc; -+ uint16_t min_spatial_segmentation_idc; -+ uint8_t parallelismType; -+ uint8_t chromaFormat; -+ uint8_t bitDepthLumaMinus8; -+ uint8_t bitDepthChromaMinus8; -+ uint16_t avgFrameRate; -+ uint8_t constantFrameRate; -+ uint8_t numTemporalLayers; -+ uint8_t temporalIdNested; -+ uint8_t lengthSizeMinusOne; -+ uint8_t numOfArrays; -+ HVCCNALUnitArray *array; -+} HEVCDecoderConfigurationRecord; -+ -+typedef struct HVCCProfileTierLevel { -+ uint8_t profile_space; -+ uint8_t tier_flag; -+ uint8_t profile_idc; -+ uint32_t profile_compatibility_flags; -+ uint64_t constraint_indicator_flags; -+ uint8_t level_idc; -+} HVCCProfileTierLevel; -+ -+static void hvcc_update_ptl(HEVCDecoderConfigurationRecord *hvcc, -+ HVCCProfileTierLevel *ptl) -+{ -+ /* -+ * The value of general_profile_space in all the parameter sets must be -+ * identical. -+ */ -+ hvcc->general_profile_space = ptl->profile_space; -+ -+ /* -+ * The level indication general_level_idc must indicate a level of -+ * capability equal to or greater than the highest level indicated for the -+ * highest tier in all the parameter sets. -+ */ -+ if (hvcc->general_tier_flag < ptl->tier_flag) -+ hvcc->general_level_idc = ptl->level_idc; -+ else -+ hvcc->general_level_idc = FFMAX(hvcc->general_level_idc, ptl->level_idc); -+ -+ /* -+ * The tier indication general_tier_flag must indicate a tier equal to or -+ * greater than the highest tier indicated in all the parameter sets. -+ */ -+ hvcc->general_tier_flag = FFMAX(hvcc->general_tier_flag, ptl->tier_flag); -+ -+ /* -+ * The profile indication general_profile_idc must indicate a profile to -+ * which the stream associated with this configuration record conforms. -+ * -+ * If the sequence parameter sets are marked with different profiles, then -+ * the stream may need examination to determine which profile, if any, the -+ * entire stream conforms to. If the entire stream is not examined, or the -+ * examination reveals that there is no profile to which the entire stream -+ * conforms, then the entire stream must be split into two or more -+ * sub-streams with separate configuration records in which these rules can -+ * be met. -+ * -+ * Note: set the profile to the highest value for the sake of simplicity. -+ */ -+ hvcc->general_profile_idc = FFMAX(hvcc->general_profile_idc, ptl->profile_idc); -+ -+ /* -+ * Each bit in general_profile_compatibility_flags may only be set if all -+ * the parameter sets set that bit. -+ */ -+ hvcc->general_profile_compatibility_flags &= ptl->profile_compatibility_flags; -+ -+ /* -+ * Each bit in general_constraint_indicator_flags may only be set if all -+ * the parameter sets set that bit. -+ */ -+ hvcc->general_constraint_indicator_flags &= ptl->constraint_indicator_flags; -+} -+ -+static void hvcc_parse_ptl(GetBitContext *gb, -+ HEVCDecoderConfigurationRecord *hvcc, -+ unsigned int max_sub_layers_minus1) -+{ -+ unsigned int i; -+ HVCCProfileTierLevel general_ptl; -+ uint8_t sub_layer_profile_present_flag[MAX_SUB_LAYERS]; -+ uint8_t sub_layer_level_present_flag[MAX_SUB_LAYERS]; -+ -+ general_ptl.profile_space = get_bits(gb, 2); -+ general_ptl.tier_flag = get_bits1(gb); -+ general_ptl.profile_idc = get_bits(gb, 5); -+ general_ptl.profile_compatibility_flags = get_bits_long(gb, 32); -+ general_ptl.constraint_indicator_flags = get_bits64(gb, 48); -+ general_ptl.level_idc = get_bits(gb, 8); -+ hvcc_update_ptl(hvcc, &general_ptl); -+ -+ for (i = 0; i < max_sub_layers_minus1; i++) { -+ sub_layer_profile_present_flag[i] = get_bits1(gb); -+ sub_layer_level_present_flag[i] = get_bits1(gb); -+ } -+ -+ if (max_sub_layers_minus1 > 0) -+ for (i = max_sub_layers_minus1; i < 8; i++) -+ skip_bits(gb, 2); // reserved_zero_2bits[i] -+ -+ for (i = 0; i < max_sub_layers_minus1; i++) { -+ if (sub_layer_profile_present_flag[i]) { -+ /* -+ * sub_layer_profile_space[i] u(2) -+ * sub_layer_tier_flag[i] u(1) -+ * sub_layer_profile_idc[i] u(5) -+ * sub_layer_profile_compatibility_flag[i][0..31] u(32) -+ * sub_layer_progressive_source_flag[i] u(1) -+ * sub_layer_interlaced_source_flag[i] u(1) -+ * sub_layer_non_packed_constraint_flag[i] u(1) -+ * sub_layer_frame_only_constraint_flag[i] u(1) -+ * sub_layer_reserved_zero_44bits[i] u(44) -+ */ -+ skip_bits_long(gb, 32); -+ skip_bits_long(gb, 32); -+ skip_bits (gb, 24); -+ } -+ -+ if (sub_layer_level_present_flag[i]) -+ skip_bits(gb, 8); -+ } -+} -+ -+static void skip_sub_layer_hrd_parameters(GetBitContext *gb, -+ unsigned int cpb_cnt_minus1, -+ uint8_t sub_pic_hrd_params_present_flag) -+{ -+ unsigned int i; -+ -+ for (i = 0; i <= cpb_cnt_minus1; i++) { -+ get_ue_golomb_long(gb); // bit_rate_value_minus1 -+ get_ue_golomb_long(gb); // cpb_size_value_minus1 -+ -+ if (sub_pic_hrd_params_present_flag) { -+ get_ue_golomb_long(gb); // cpb_size_du_value_minus1 -+ get_ue_golomb_long(gb); // bit_rate_du_value_minus1 -+ } -+ -+ skip_bits1(gb); // cbr_flag -+ } -+} -+ -+static void skip_hrd_parameters(GetBitContext *gb, uint8_t cprms_present_flag, -+ unsigned int max_sub_layers_minus1) -+{ -+ unsigned int i; -+ uint8_t sub_pic_hrd_params_present_flag = 0; -+ uint8_t nal_hrd_parameters_present_flag = 0; -+ uint8_t vcl_hrd_parameters_present_flag = 0; -+ -+ if (cprms_present_flag) { -+ nal_hrd_parameters_present_flag = get_bits1(gb); -+ vcl_hrd_parameters_present_flag = get_bits1(gb); -+ -+ if (nal_hrd_parameters_present_flag || -+ vcl_hrd_parameters_present_flag) { -+ sub_pic_hrd_params_present_flag = get_bits1(gb); -+ -+ if (sub_pic_hrd_params_present_flag) -+ /* -+ * tick_divisor_minus2 u(8) -+ * du_cpb_removal_delay_increment_length_minus1 u(5) -+ * sub_pic_cpb_params_in_pic_timing_sei_flag u(1) -+ * dpb_output_delay_du_length_minus1 u(5) -+ */ -+ skip_bits(gb, 19); -+ -+ /* -+ * bit_rate_scale u(4) -+ * cpb_size_scale u(4) -+ */ -+ skip_bits(gb, 8); -+ -+ if (sub_pic_hrd_params_present_flag) -+ skip_bits(gb, 4); // cpb_size_du_scale -+ -+ /* -+ * initial_cpb_removal_delay_length_minus1 u(5) -+ * au_cpb_removal_delay_length_minus1 u(5) -+ * dpb_output_delay_length_minus1 u(5) -+ */ -+ skip_bits(gb, 15); -+ } -+ } -+ -+ for (i = 0; i <= max_sub_layers_minus1; i++) { -+ unsigned int cpb_cnt_minus1 = 0; -+ uint8_t low_delay_hrd_flag = 0; -+ uint8_t fixed_pic_rate_within_cvs_flag = 0; -+ uint8_t fixed_pic_rate_general_flag = get_bits1(gb); -+ -+ if (!fixed_pic_rate_general_flag) -+ fixed_pic_rate_within_cvs_flag = get_bits1(gb); -+ -+ if (fixed_pic_rate_within_cvs_flag) -+ get_ue_golomb_long(gb); // elemental_duration_in_tc_minus1 -+ else -+ low_delay_hrd_flag = get_bits1(gb); -+ -+ if (!low_delay_hrd_flag) -+ cpb_cnt_minus1 = get_ue_golomb_long(gb); -+ -+ if (nal_hrd_parameters_present_flag) -+ skip_sub_layer_hrd_parameters(gb, cpb_cnt_minus1, -+ sub_pic_hrd_params_present_flag); -+ -+ if (vcl_hrd_parameters_present_flag) -+ skip_sub_layer_hrd_parameters(gb, cpb_cnt_minus1, -+ sub_pic_hrd_params_present_flag); -+ } -+} -+ -+static void skip_timing_info(GetBitContext *gb) -+{ -+ skip_bits_long(gb, 32); // num_units_in_tick -+ skip_bits_long(gb, 32); // time_scale -+ -+ if (get_bits1(gb)) // poc_proportional_to_timing_flag -+ get_ue_golomb_long(gb); // num_ticks_poc_diff_one_minus1 -+} -+ -+static void hvcc_parse_vui(GetBitContext *gb, -+ HEVCDecoderConfigurationRecord *hvcc, -+ unsigned int max_sub_layers_minus1) -+{ -+ unsigned int min_spatial_segmentation_idc; -+ -+ if (get_bits1(gb)) // aspect_ratio_info_present_flag -+ if (get_bits(gb, 8) == 255) // aspect_ratio_idc -+ skip_bits_long(gb, 32); // sar_width u(16), sar_height u(16) -+ -+ if (get_bits1(gb)) // overscan_info_present_flag -+ skip_bits1(gb); // overscan_appropriate_flag -+ -+ if (get_bits1(gb)) { // video_signal_type_present_flag -+ skip_bits(gb, 4); // video_format u(3), video_full_range_flag u(1) -+ -+ if (get_bits1(gb)) // colour_description_present_flag -+ /* -+ * colour_primaries u(8) -+ * transfer_characteristics u(8) -+ * matrix_coeffs u(8) -+ */ -+ skip_bits(gb, 24); -+ } -+ -+ if (get_bits1(gb)) { // chroma_loc_info_present_flag -+ get_ue_golomb_long(gb); // chroma_sample_loc_type_top_field -+ get_ue_golomb_long(gb); // chroma_sample_loc_type_bottom_field -+ } -+ -+ /* -+ * neutral_chroma_indication_flag u(1) -+ * field_seq_flag u(1) -+ * frame_field_info_present_flag u(1) -+ */ -+ skip_bits(gb, 3); -+ -+ if (get_bits1(gb)) { // default_display_window_flag -+ get_ue_golomb_long(gb); // def_disp_win_left_offset -+ get_ue_golomb_long(gb); // def_disp_win_right_offset -+ get_ue_golomb_long(gb); // def_disp_win_top_offset -+ get_ue_golomb_long(gb); // def_disp_win_bottom_offset -+ } -+ -+ if (get_bits1(gb)) { // vui_timing_info_present_flag -+ skip_timing_info(gb); -+ -+ if (get_bits1(gb)) // vui_hrd_parameters_present_flag -+ skip_hrd_parameters(gb, 1, max_sub_layers_minus1); -+ } -+ -+ if (get_bits1(gb)) { // bitstream_restriction_flag -+ /* -+ * tiles_fixed_structure_flag u(1) -+ * motion_vectors_over_pic_boundaries_flag u(1) -+ * restricted_ref_pic_lists_flag u(1) -+ */ -+ skip_bits(gb, 3); -+ -+ min_spatial_segmentation_idc = get_ue_golomb_long(gb); -+ -+ /* -+ * unsigned int(12) min_spatial_segmentation_idc; -+ * -+ * The min_spatial_segmentation_idc indication must indicate a level of -+ * spatial segmentation equal to or less than the lowest level of -+ * spatial segmentation indicated in all the parameter sets. -+ */ -+ hvcc->min_spatial_segmentation_idc = FFMIN(hvcc->min_spatial_segmentation_idc, -+ min_spatial_segmentation_idc); -+ -+ get_ue_golomb_long(gb); // max_bytes_per_pic_denom -+ get_ue_golomb_long(gb); // max_bits_per_min_cu_denom -+ get_ue_golomb_long(gb); // log2_max_mv_length_horizontal -+ get_ue_golomb_long(gb); // log2_max_mv_length_vertical -+ } -+} -+ -+static void skip_sub_layer_ordering_info(GetBitContext *gb) -+{ -+ get_ue_golomb_long(gb); // max_dec_pic_buffering_minus1 -+ get_ue_golomb_long(gb); // max_num_reorder_pics -+ get_ue_golomb_long(gb); // max_latency_increase_plus1 -+} -+ -+static int hvcc_parse_vps(GetBitContext *gb, -+ HEVCDecoderConfigurationRecord *hvcc) -+{ -+ unsigned int vps_max_sub_layers_minus1; -+ -+ /* -+ * vps_video_parameter_set_id u(4) -+ * vps_reserved_three_2bits u(2) -+ * vps_max_layers_minus1 u(6) -+ */ -+ skip_bits(gb, 12); -+ -+ vps_max_sub_layers_minus1 = get_bits(gb, 3); -+ -+ /* -+ * numTemporalLayers greater than 1 indicates that the stream to which this -+ * configuration record applies is temporally scalable and the contained -+ * number of temporal layers (also referred to as temporal sub-layer or -+ * sub-layer in ISO/IEC 23008-2) is equal to numTemporalLayers. Value 1 -+ * indicates that the stream is not temporally scalable. Value 0 indicates -+ * that it is unknown whether the stream is temporally scalable. -+ */ -+ hvcc->numTemporalLayers = FFMAX(hvcc->numTemporalLayers, -+ vps_max_sub_layers_minus1 + 1); -+ -+ /* -+ * vps_temporal_id_nesting_flag u(1) -+ * vps_reserved_0xffff_16bits u(16) -+ */ -+ skip_bits(gb, 17); -+ -+ hvcc_parse_ptl(gb, hvcc, vps_max_sub_layers_minus1); -+ -+ /* nothing useful for hvcC past this point */ -+ return 0; -+} -+ -+static void skip_scaling_list_data(GetBitContext *gb) -+{ -+ int i, j, k, num_coeffs; -+ -+ for (i = 0; i < 4; i++) -+ for (j = 0; j < (i == 3 ? 2 : 6); j++) -+ if (!get_bits1(gb)) // scaling_list_pred_mode_flag[i][j] -+ get_ue_golomb_long(gb); // scaling_list_pred_matrix_id_delta[i][j] -+ else { -+ num_coeffs = FFMIN(64, 1 << (4 + (i << 1))); -+ -+ if (i > 1) -+ get_se_golomb_long(gb); // scaling_list_dc_coef_minus8[i-2][j] -+ -+ for (k = 0; k < num_coeffs; k++) -+ get_se_golomb_long(gb); // scaling_list_delta_coef -+ } -+} -+ -+static int parse_rps(GetBitContext *gb, unsigned int rps_idx, -+ unsigned int num_rps, -+ unsigned int num_delta_pocs[MAX_SHORT_TERM_RPS_COUNT]) -+{ -+ unsigned int i; -+ -+ if (rps_idx && get_bits1(gb)) { // inter_ref_pic_set_prediction_flag -+ /* this should only happen for slice headers, and this isn't one */ -+ if (rps_idx >= num_rps) -+ return AVERROR_INVALIDDATA; -+ -+ skip_bits1 (gb); // delta_rps_sign -+ get_ue_golomb_long(gb); // abs_delta_rps_minus1 -+ -+ num_delta_pocs[rps_idx] = 0; -+ -+ /* -+ * From libavcodec/hevc_ps.c: -+ * -+ * if (is_slice_header) { -+ * //foo -+ * } else -+ * rps_ridx = &sps->st_rps[rps - sps->st_rps - 1]; -+ * -+ * where: -+ * rps: &sps->st_rps[rps_idx] -+ * sps->st_rps: &sps->st_rps[0] -+ * is_slice_header: rps_idx == num_rps -+ * -+ * thus: -+ * if (num_rps != rps_idx) -+ * rps_ridx = &sps->st_rps[rps_idx - 1]; -+ * -+ * NumDeltaPocs[RefRpsIdx]: num_delta_pocs[rps_idx - 1] -+ */ -+ for (i = 0; i < num_delta_pocs[rps_idx - 1]; i++) { -+ uint8_t use_delta_flag = 0; -+ uint8_t used_by_curr_pic_flag = get_bits1(gb); -+ if (!used_by_curr_pic_flag) -+ use_delta_flag = get_bits1(gb); -+ -+ if (used_by_curr_pic_flag || use_delta_flag) -+ num_delta_pocs[rps_idx]++; -+ } -+ } else { -+ unsigned int num_negative_pics = get_ue_golomb_long(gb); -+ unsigned int num_positive_pics = get_ue_golomb_long(gb); -+ -+ num_delta_pocs[rps_idx] = num_negative_pics + num_positive_pics; -+ -+ for (i = 0; i < num_negative_pics; i++) { -+ get_ue_golomb_long(gb); // delta_poc_s0_minus1[rps_idx] -+ skip_bits1 (gb); // used_by_curr_pic_s0_flag[rps_idx] -+ } -+ -+ for (i = 0; i < num_positive_pics; i++) { -+ get_ue_golomb_long(gb); // delta_poc_s1_minus1[rps_idx] -+ skip_bits1 (gb); // used_by_curr_pic_s1_flag[rps_idx] -+ } -+ } -+ -+ return 0; -+} -+ -+static int hvcc_parse_sps(GetBitContext *gb, -+ HEVCDecoderConfigurationRecord *hvcc) -+{ -+ unsigned int i, sps_max_sub_layers_minus1, log2_max_pic_order_cnt_lsb_minus4; -+ unsigned int num_short_term_ref_pic_sets, num_delta_pocs[MAX_SHORT_TERM_RPS_COUNT]; -+ -+ skip_bits(gb, 4); // sps_video_parameter_set_id -+ -+ sps_max_sub_layers_minus1 = get_bits (gb, 3); -+ -+ /* -+ * numTemporalLayers greater than 1 indicates that the stream to which this -+ * configuration record applies is temporally scalable and the contained -+ * number of temporal layers (also referred to as temporal sub-layer or -+ * sub-layer in ISO/IEC 23008-2) is equal to numTemporalLayers. Value 1 -+ * indicates that the stream is not temporally scalable. Value 0 indicates -+ * that it is unknown whether the stream is temporally scalable. -+ */ -+ hvcc->numTemporalLayers = FFMAX(hvcc->numTemporalLayers, -+ sps_max_sub_layers_minus1 + 1); -+ -+ hvcc->temporalIdNested = get_bits1(gb); -+ -+ hvcc_parse_ptl(gb, hvcc, sps_max_sub_layers_minus1); -+ -+ get_ue_golomb_long(gb); // sps_seq_parameter_set_id -+ -+ hvcc->chromaFormat = get_ue_golomb_long(gb); -+ -+ if (hvcc->chromaFormat == 3) -+ skip_bits1(gb); // separate_colour_plane_flag -+ -+ get_ue_golomb_long(gb); // pic_width_in_luma_samples -+ get_ue_golomb_long(gb); // pic_height_in_luma_samples -+ -+ if (get_bits1(gb)) { // conformance_window_flag -+ get_ue_golomb_long(gb); // conf_win_left_offset -+ get_ue_golomb_long(gb); // conf_win_right_offset -+ get_ue_golomb_long(gb); // conf_win_top_offset -+ get_ue_golomb_long(gb); // conf_win_bottom_offset -+ } -+ -+ hvcc->bitDepthLumaMinus8 = get_ue_golomb_long(gb); -+ hvcc->bitDepthChromaMinus8 = get_ue_golomb_long(gb); -+ log2_max_pic_order_cnt_lsb_minus4 = get_ue_golomb_long(gb); -+ -+ /* sps_sub_layer_ordering_info_present_flag */ -+ i = get_bits1(gb) ? 0 : sps_max_sub_layers_minus1; -+ for (; i <= sps_max_sub_layers_minus1; i++) -+ skip_sub_layer_ordering_info(gb); -+ -+ get_ue_golomb_long(gb); // log2_min_luma_coding_block_size_minus3 -+ get_ue_golomb_long(gb); // log2_diff_max_min_luma_coding_block_size -+ get_ue_golomb_long(gb); // log2_min_transform_block_size_minus2 -+ get_ue_golomb_long(gb); // log2_diff_max_min_transform_block_size -+ get_ue_golomb_long(gb); // max_transform_hierarchy_depth_inter -+ get_ue_golomb_long(gb); // max_transform_hierarchy_depth_intra -+ -+ if (get_bits1(gb) && // scaling_list_enabled_flag -+ get_bits1(gb)) // sps_scaling_list_data_present_flag -+ skip_scaling_list_data(gb); -+ -+ skip_bits1(gb); // amp_enabled_flag -+ skip_bits1(gb); // sample_adaptive_offset_enabled_flag -+ -+ if (get_bits1(gb)) { // pcm_enabled_flag -+ skip_bits (gb, 4); // pcm_sample_bit_depth_luma_minus1 -+ skip_bits (gb, 4); // pcm_sample_bit_depth_chroma_minus1 -+ get_ue_golomb_long(gb); // log2_min_pcm_luma_coding_block_size_minus3 -+ get_ue_golomb_long(gb); // log2_diff_max_min_pcm_luma_coding_block_size -+ skip_bits1 (gb); // pcm_loop_filter_disabled_flag -+ } -+ -+ num_short_term_ref_pic_sets = get_ue_golomb_long(gb); -+ if (num_short_term_ref_pic_sets > MAX_SHORT_TERM_RPS_COUNT) -+ return AVERROR_INVALIDDATA; -+ -+ for (i = 0; i < num_short_term_ref_pic_sets; i++) { -+ int ret = parse_rps(gb, i, num_short_term_ref_pic_sets, num_delta_pocs); -+ if (ret < 0) -+ return ret; -+ } -+ -+ if (get_bits1(gb)) { // long_term_ref_pics_present_flag -+ for (i = 0; i < get_ue_golomb_long(gb); i++) { // num_long_term_ref_pics_sps -+ int len = FFMIN(log2_max_pic_order_cnt_lsb_minus4 + 4, 16); -+ skip_bits (gb, len); // lt_ref_pic_poc_lsb_sps[i] -+ skip_bits1(gb); // used_by_curr_pic_lt_sps_flag[i] -+ } -+ } -+ -+ skip_bits1(gb); // sps_temporal_mvp_enabled_flag -+ skip_bits1(gb); // strong_intra_smoothing_enabled_flag -+ -+ if (get_bits1(gb)) // vui_parameters_present_flag -+ hvcc_parse_vui(gb, hvcc, sps_max_sub_layers_minus1); -+ -+ /* nothing useful for hvcC past this point */ -+ return 0; -+} -+ -+static int hvcc_parse_pps(GetBitContext *gb, -+ HEVCDecoderConfigurationRecord *hvcc) -+{ -+ uint8_t tiles_enabled_flag, entropy_coding_sync_enabled_flag; -+ -+ get_ue_golomb_long(gb); // pps_pic_parameter_set_id -+ get_ue_golomb_long(gb); // pps_seq_parameter_set_id -+ -+ /* -+ * dependent_slice_segments_enabled_flag u(1) -+ * output_flag_present_flag u(1) -+ * num_extra_slice_header_bits u(3) -+ * sign_data_hiding_enabled_flag u(1) -+ * cabac_init_present_flag u(1) -+ */ -+ skip_bits(gb, 7); -+ -+ get_ue_golomb_long(gb); // num_ref_idx_l0_default_active_minus1 -+ get_ue_golomb_long(gb); // num_ref_idx_l1_default_active_minus1 -+ get_se_golomb_long(gb); // init_qp_minus26 -+ -+ /* -+ * constrained_intra_pred_flag u(1) -+ * transform_skip_enabled_flag u(1) -+ */ -+ skip_bits(gb, 2); -+ -+ if (get_bits1(gb)) // cu_qp_delta_enabled_flag -+ get_ue_golomb_long(gb); // diff_cu_qp_delta_depth -+ -+ get_se_golomb_long(gb); // pps_cb_qp_offset -+ get_se_golomb_long(gb); // pps_cr_qp_offset -+ -+ /* -+ * weighted_pred_flag u(1) -+ * weighted_bipred_flag u(1) -+ * transquant_bypass_enabled_flag u(1) -+ */ -+ skip_bits(gb, 3); -+ -+ tiles_enabled_flag = get_bits1(gb); -+ entropy_coding_sync_enabled_flag = get_bits1(gb); -+ -+ if (entropy_coding_sync_enabled_flag && tiles_enabled_flag) -+ hvcc->parallelismType = 0; // mixed-type parallel decoding -+ else if (entropy_coding_sync_enabled_flag) -+ hvcc->parallelismType = 3; // wavefront-based parallel decoding -+ else if (tiles_enabled_flag) -+ hvcc->parallelismType = 2; // tile-based parallel decoding -+ else -+ hvcc->parallelismType = 1; // slice-based parallel decoding -+ -+ /* nothing useful for hvcC past this point */ -+ return 0; -+} -+ -+static uint8_t *nal_unit_extract_rbsp(const uint8_t *src, uint32_t src_len, -+ uint32_t *dst_len) -+{ -+ uint8_t *dst; -+ uint32_t i, len; -+ -+ dst = av_malloc(src_len); -+ if (!dst) -+ return NULL; -+ -+ /* NAL unit header (2 bytes) */ -+ i = len = 0; -+ while (i < 2 && i < src_len) -+ dst[len++] = src[i++]; -+ -+ while (i + 2 < src_len) -+ if (!src[i] && !src[i + 1] && src[i + 2] == 3) { -+ dst[len++] = src[i++]; -+ dst[len++] = src[i++]; -+ i++; // remove emulation_prevention_three_byte -+ } else -+ dst[len++] = src[i++]; -+ -+ while (i < src_len) -+ dst[len++] = src[i++]; -+ -+ *dst_len = len; -+ return dst; -+} -+ -+ -+ -+static void nal_unit_parse_header(GetBitContext *gb, uint8_t *nal_type) -+{ -+ skip_bits1(gb); // forbidden_zero_bit -+ -+ *nal_type = get_bits(gb, 6); -+ -+ /* -+ * nuh_layer_id u(6) -+ * nuh_temporal_id_plus1 u(3) -+ */ -+ skip_bits(gb, 9); -+} -+ -+static int hvcc_array_add_nal_unit(uint8_t *nal_buf, uint32_t nal_size, -+ uint8_t nal_type, int ps_array_completeness, -+ HEVCDecoderConfigurationRecord *hvcc) -+{ -+ int ret; -+ uint8_t index; -+ uint16_t numNalus; -+ HVCCNALUnitArray *array; -+ -+ for (index = 0; index < hvcc->numOfArrays; index++) -+ if (hvcc->array[index].NAL_unit_type == nal_type) -+ break; -+ -+ if (index >= hvcc->numOfArrays) { -+ uint8_t i; -+ -+ ret = av_reallocp_array(&hvcc->array, index + 1, sizeof(HVCCNALUnitArray)); -+ if (ret < 0) -+ return ret; -+ -+ for (i = hvcc->numOfArrays; i <= index; i++) -+ memset(&hvcc->array[i], 0, sizeof(HVCCNALUnitArray)); -+ hvcc->numOfArrays = index + 1; -+ } -+ -+ array = &hvcc->array[index]; -+ numNalus = array->numNalus; -+ -+ ret = av_reallocp_array(&array->nalUnit, numNalus + 1, sizeof(uint8_t*)); -+ if (ret < 0) -+ return ret; -+ -+ ret = av_reallocp_array(&array->nalUnitLength, numNalus + 1, sizeof(uint16_t)); -+ if (ret < 0) -+ return ret; -+ -+ array->nalUnit [numNalus] = nal_buf; -+ array->nalUnitLength[numNalus] = nal_size; -+ array->NAL_unit_type = nal_type; -+ array->numNalus++; -+ -+ /* -+ * When the sample entry name is ‘hvc1’, the default and mandatory value of -+ * array_completeness is 1 for arrays of all types of parameter sets, and 0 -+ * for all other arrays. When the sample entry name is ‘hev1’, the default -+ * value of array_completeness is 0 for all arrays. -+ */ -+ if (nal_type == NAL_VPS || nal_type == NAL_SPS || nal_type == NAL_PPS) -+ array->array_completeness = ps_array_completeness; -+ -+ return 0; -+} -+ -+static int hvcc_add_nal_unit(uint8_t *nal_buf, uint32_t nal_size, -+ int ps_array_completeness, -+ HEVCDecoderConfigurationRecord *hvcc) -+{ -+ int ret = 0; -+ GetBitContext gbc; -+ uint8_t nal_type; -+ uint8_t *rbsp_buf; -+ uint32_t rbsp_size; -+ -+ rbsp_buf = nal_unit_extract_rbsp(nal_buf, nal_size, &rbsp_size); -+ if (!rbsp_buf) { -+ ret = AVERROR(ENOMEM); -+ goto end; -+ } -+ -+ ret = init_get_bits8(&gbc, rbsp_buf, rbsp_size); -+ if (ret < 0) -+ goto end; -+ -+ nal_unit_parse_header(&gbc, &nal_type); -+ -+ /* -+ * Note: only 'declarative' SEI messages are allowed in -+ * hvcC. Perhaps the SEI playload type should be checked -+ * and non-declarative SEI messages discarded? -+ */ -+ switch (nal_type) { -+ case NAL_VPS: -+ case NAL_SPS: -+ case NAL_PPS: -+ case NAL_SEI_PREFIX: -+ case NAL_SEI_SUFFIX: -+ ret = hvcc_array_add_nal_unit(nal_buf, nal_size, nal_type, -+ ps_array_completeness, hvcc); -+ if (ret < 0) -+ goto end; -+ else if (nal_type == NAL_VPS) -+ ret = hvcc_parse_vps(&gbc, hvcc); -+ else if (nal_type == NAL_SPS) -+ ret = hvcc_parse_sps(&gbc, hvcc); -+ else if (nal_type == NAL_PPS) -+ ret = hvcc_parse_pps(&gbc, hvcc); -+ if (ret < 0) -+ goto end; -+ break; -+ default: -+ ret = AVERROR_INVALIDDATA; -+ goto end; -+ } -+ -+end: -+ av_free(rbsp_buf); -+ return ret; -+} -+ -+static void hvcc_init(HEVCDecoderConfigurationRecord *hvcc) -+{ -+ memset(hvcc, 0, sizeof(HEVCDecoderConfigurationRecord)); -+ hvcc->configurationVersion = 1; -+ hvcc->lengthSizeMinusOne = 3; // 4 bytes -+ -+ /* -+ * The following fields have all their valid bits set by default, -+ * the ProfileTierLevel parsing code will unset them when needed. -+ */ -+ hvcc->general_profile_compatibility_flags = 0xffffffff; -+ hvcc->general_constraint_indicator_flags = 0xffffffffffff; -+ -+ /* -+ * Initialize this field with an invalid value which can be used to detect -+ * whether we didn't see any VUI (in wich case it should be reset to zero). -+ */ -+ hvcc->min_spatial_segmentation_idc = MAX_SPATIAL_SEGMENTATION + 1; -+} -+ -+static void hvcc_close(HEVCDecoderConfigurationRecord *hvcc) -+{ -+ uint8_t i; -+ -+ for (i = 0; i < hvcc->numOfArrays; i++) { -+ hvcc->array[i].numNalus = 0; -+ av_freep(&hvcc->array[i].nalUnit); -+ av_freep(&hvcc->array[i].nalUnitLength); -+ } -+ -+ hvcc->numOfArrays = 0; -+ av_freep(&hvcc->array); -+} -+ -+static int hvcc_write(AVIOContext *pb, HEVCDecoderConfigurationRecord *hvcc) -+{ -+ uint8_t i; -+ uint16_t j, vps_count = 0, sps_count = 0, pps_count = 0; -+ -+ /* -+ * We only support writing HEVCDecoderConfigurationRecord version 1. -+ */ -+ hvcc->configurationVersion = 1; -+ -+ /* -+ * If min_spatial_segmentation_idc is invalid, reset to 0 (unspecified). -+ */ -+ if (hvcc->min_spatial_segmentation_idc > MAX_SPATIAL_SEGMENTATION) -+ hvcc->min_spatial_segmentation_idc = 0; -+ -+ /* -+ * parallelismType indicates the type of parallelism that is used to meet -+ * the restrictions imposed by min_spatial_segmentation_idc when the value -+ * of min_spatial_segmentation_idc is greater than 0. -+ */ -+ if (!hvcc->min_spatial_segmentation_idc) -+ hvcc->parallelismType = 0; -+ -+ /* -+ * It's unclear how to properly compute these fields, so -+ * let's always set them to values meaning 'unspecified'. -+ */ -+ hvcc->avgFrameRate = 0; -+ hvcc->constantFrameRate = 0; -+ -+ av_dlog(NULL, "configurationVersion: %"PRIu8"\n", -+ hvcc->configurationVersion); -+ av_dlog(NULL, "general_profile_space: %"PRIu8"\n", -+ hvcc->general_profile_space); -+ av_dlog(NULL, "general_tier_flag: %"PRIu8"\n", -+ hvcc->general_tier_flag); -+ av_dlog(NULL, "general_profile_idc: %"PRIu8"\n", -+ hvcc->general_profile_idc); -+ av_dlog(NULL, "general_profile_compatibility_flags: 0x%08"PRIx32"\n", -+ hvcc->general_profile_compatibility_flags); -+ av_dlog(NULL, "general_constraint_indicator_flags: 0x%012"PRIx64"\n", -+ hvcc->general_constraint_indicator_flags); -+ av_dlog(NULL, "general_level_idc: %"PRIu8"\n", -+ hvcc->general_level_idc); -+ av_dlog(NULL, "min_spatial_segmentation_idc: %"PRIu16"\n", -+ hvcc->min_spatial_segmentation_idc); -+ av_dlog(NULL, "parallelismType: %"PRIu8"\n", -+ hvcc->parallelismType); -+ av_dlog(NULL, "chromaFormat: %"PRIu8"\n", -+ hvcc->chromaFormat); -+ av_dlog(NULL, "bitDepthLumaMinus8: %"PRIu8"\n", -+ hvcc->bitDepthLumaMinus8); -+ av_dlog(NULL, "bitDepthChromaMinus8: %"PRIu8"\n", -+ hvcc->bitDepthChromaMinus8); -+ av_dlog(NULL, "avgFrameRate: %"PRIu16"\n", -+ hvcc->avgFrameRate); -+ av_dlog(NULL, "constantFrameRate: %"PRIu8"\n", -+ hvcc->constantFrameRate); -+ av_dlog(NULL, "numTemporalLayers: %"PRIu8"\n", -+ hvcc->numTemporalLayers); -+ av_dlog(NULL, "temporalIdNested: %"PRIu8"\n", -+ hvcc->temporalIdNested); -+ av_dlog(NULL, "lengthSizeMinusOne: %"PRIu8"\n", -+ hvcc->lengthSizeMinusOne); -+ av_dlog(NULL, "numOfArrays: %"PRIu8"\n", -+ hvcc->numOfArrays); -+ for (i = 0; i < hvcc->numOfArrays; i++) { -+ av_dlog(NULL, "array_completeness[%"PRIu8"]: %"PRIu8"\n", -+ i, hvcc->array[i].array_completeness); -+ av_dlog(NULL, "NAL_unit_type[%"PRIu8"]: %"PRIu8"\n", -+ i, hvcc->array[i].NAL_unit_type); -+ av_dlog(NULL, "numNalus[%"PRIu8"]: %"PRIu16"\n", -+ i, hvcc->array[i].numNalus); -+ for (j = 0; j < hvcc->array[i].numNalus; j++) -+ av_dlog(NULL, -+ "nalUnitLength[%"PRIu8"][%"PRIu16"]: %"PRIu16"\n", -+ i, j, hvcc->array[i].nalUnitLength[j]); -+ } -+ -+ /* -+ * We need at least one of each: VPS, SPS and PPS. -+ */ -+ for (i = 0; i < hvcc->numOfArrays; i++) -+ switch (hvcc->array[i].NAL_unit_type) { -+ case NAL_VPS: -+ vps_count += hvcc->array[i].numNalus; -+ break; -+ case NAL_SPS: -+ sps_count += hvcc->array[i].numNalus; -+ break; -+ case NAL_PPS: -+ pps_count += hvcc->array[i].numNalus; -+ break; -+ default: -+ break; -+ } -+ if (!vps_count || vps_count > MAX_VPS_COUNT || -+ !sps_count || sps_count > MAX_SPS_COUNT || -+ !pps_count || pps_count > MAX_PPS_COUNT) -+ return AVERROR_INVALIDDATA; -+ -+ /* unsigned int(8) configurationVersion = 1; */ -+ avio_w8(pb, hvcc->configurationVersion); -+ -+ /* -+ * unsigned int(2) general_profile_space; -+ * unsigned int(1) general_tier_flag; -+ * unsigned int(5) general_profile_idc; -+ */ -+ avio_w8(pb, hvcc->general_profile_space << 6 | -+ hvcc->general_tier_flag << 5 | -+ hvcc->general_profile_idc); -+ -+ /* unsigned int(32) general_profile_compatibility_flags; */ -+ avio_wb32(pb, hvcc->general_profile_compatibility_flags); -+ -+ /* unsigned int(48) general_constraint_indicator_flags; */ -+ avio_wb32(pb, hvcc->general_constraint_indicator_flags >> 16); -+ avio_wb16(pb, hvcc->general_constraint_indicator_flags); -+ -+ /* unsigned int(8) general_level_idc; */ -+ avio_w8(pb, hvcc->general_level_idc); -+ -+ /* -+ * bit(4) reserved = ‘1111’b; -+ * unsigned int(12) min_spatial_segmentation_idc; -+ */ -+ avio_wb16(pb, hvcc->min_spatial_segmentation_idc | 0xf000); -+ -+ /* -+ * bit(6) reserved = ‘111111’b; -+ * unsigned int(2) parallelismType; -+ */ -+ avio_w8(pb, hvcc->parallelismType | 0xfc); -+ -+ /* -+ * bit(6) reserved = ‘111111’b; -+ * unsigned int(2) chromaFormat; -+ */ -+ avio_w8(pb, hvcc->chromaFormat | 0xfc); -+ -+ /* -+ * bit(5) reserved = ‘11111’b; -+ * unsigned int(3) bitDepthLumaMinus8; -+ */ -+ avio_w8(pb, hvcc->bitDepthLumaMinus8 | 0xf8); -+ -+ /* -+ * bit(5) reserved = ‘11111’b; -+ * unsigned int(3) bitDepthChromaMinus8; -+ */ -+ avio_w8(pb, hvcc->bitDepthChromaMinus8 | 0xf8); -+ -+ /* bit(16) avgFrameRate; */ -+ avio_wb16(pb, hvcc->avgFrameRate); -+ -+ /* -+ * bit(2) constantFrameRate; -+ * bit(3) numTemporalLayers; -+ * bit(1) temporalIdNested; -+ * unsigned int(2) lengthSizeMinusOne; -+ */ -+ avio_w8(pb, hvcc->constantFrameRate << 6 | -+ hvcc->numTemporalLayers << 3 | -+ hvcc->temporalIdNested << 2 | -+ hvcc->lengthSizeMinusOne); -+ -+ /* unsigned int(8) numOfArrays; */ -+ avio_w8(pb, hvcc->numOfArrays); -+ -+ for (i = 0; i < hvcc->numOfArrays; i++) { -+ /* -+ * bit(1) array_completeness; -+ * unsigned int(1) reserved = 0; -+ * unsigned int(6) NAL_unit_type; -+ */ -+ avio_w8(pb, hvcc->array[i].array_completeness << 7 | -+ hvcc->array[i].NAL_unit_type & 0x3f); -+ -+ /* unsigned int(16) numNalus; */ -+ avio_wb16(pb, hvcc->array[i].numNalus); -+ -+ for (j = 0; j < hvcc->array[i].numNalus; j++) { -+ /* unsigned int(16) nalUnitLength; */ -+ avio_wb16(pb, hvcc->array[i].nalUnitLength[j]); -+ -+ /* bit(8*nalUnitLength) nalUnit; */ -+ avio_write(pb, hvcc->array[i].nalUnit[j], -+ hvcc->array[i].nalUnitLength[j]); -+ } -+ } -+ -+ return 0; -+} -+ -+int ff_hevc_annexb2mp4(AVIOContext *pb, const uint8_t *buf_in, -+ int size, int filter_ps, int *ps_count) -+{ -+ int num_ps = 0, ret = 0; -+ uint8_t *buf, *end, *start = NULL; -+ -+ if (!filter_ps) { -+ ret = ff_avc_parse_nal_units(pb, buf_in, size); -+ goto end; -+ } -+ -+ ret = ff_avc_parse_nal_units_buf(buf_in, &start, &size); -+ if (ret < 0) -+ goto end; -+ -+ ret = 0; -+ buf = start; -+ end = start + size; -+ -+ while (end - buf > 4) { -+ uint32_t len = FFMIN(AV_RB32(buf), end - buf - 4); -+ uint8_t type = (buf[4] >> 1) & 0x3f; -+ -+ buf += 4; -+ -+ switch (type) { -+ case NAL_VPS: -+ case NAL_SPS: -+ case NAL_PPS: -+ num_ps++; -+ break; -+ default: -+ ret += 4 + len; -+ avio_wb32(pb, len); -+ avio_write(pb, buf, len); -+ break; -+ } -+ -+ buf += len; -+ } -+ -+end: -+ av_free(start); -+ if (ps_count) -+ *ps_count = num_ps; -+ return ret; -+} -+ -+int ff_hevc_annexb2mp4_buf(const uint8_t *buf_in, uint8_t **buf_out, -+ int *size, int filter_ps, int *ps_count) -+{ -+ AVIOContext *pb; -+ int ret; -+ -+ ret = avio_open_dyn_buf(&pb); -+ if (ret < 0) -+ return ret; -+ -+ ret = ff_hevc_annexb2mp4(pb, buf_in, *size, filter_ps, ps_count); -+ *size = avio_close_dyn_buf(pb, buf_out); -+ -+ return ret; -+} -+ -+int ff_isom_write_hvcc(AVIOContext *pb, const uint8_t *data, -+ int size, int ps_array_completeness) -+{ -+ int ret = 0; -+ uint8_t *buf, *end, *start = NULL; -+ HEVCDecoderConfigurationRecord hvcc; -+ -+ hvcc_init(&hvcc); -+ -+ if (size < 6) { -+ /* We can't write a valid hvcC from the provided data */ -+ ret = AVERROR_INVALIDDATA; -+ goto end; -+ } else if (*data == 1) { -+ /* Data is already hvcC-formatted */ -+ avio_write(pb, data, size); -+ goto end; -+ } else if (!(AV_RB24(data) == 1 || AV_RB32(data) == 1)) { -+ /* Not a valid Annex B start code prefix */ -+ ret = AVERROR_INVALIDDATA; -+ goto end; -+ } -+ -+ ret = ff_avc_parse_nal_units_buf(data, &start, &size); -+ if (ret < 0) -+ goto end; -+ -+ buf = start; -+ end = start + size; -+ -+ while (end - buf > 4) { -+ uint32_t len = FFMIN(AV_RB32(buf), end - buf - 4); -+ uint8_t type = (buf[4] >> 1) & 0x3f; -+ -+ buf += 4; -+ -+ switch (type) { -+ case NAL_VPS: -+ case NAL_SPS: -+ case NAL_PPS: -+ case NAL_SEI_PREFIX: -+ case NAL_SEI_SUFFIX: -+ ret = hvcc_add_nal_unit(buf, len, ps_array_completeness, &hvcc); -+ if (ret < 0) -+ goto end; -+ break; -+ default: -+ break; -+ } -+ -+ buf += len; -+ } -+ -+ ret = hvcc_write(pb, &hvcc); -+ -+end: -+ hvcc_close(&hvcc); -+ av_free(start); -+ return ret; -+} -diff --git a/libavformat/hevc.h b/libavformat/hevc.h -new file mode 100644 -index 0000000..03c43bd ---- /dev/null -+++ b/libavformat/hevc.h -@@ -0,0 +1,98 @@ -+/* -+ * Copyright (c) 2014 Tim Walker <[email protected]> -+ * -+ * This file is part of Libav. -+ * -+ * Libav 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. -+ * -+ * Libav 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 Libav; if not, write to the Free Software -+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -+ */ -+ -+/** -+ * @file -+ * internal header for HEVC (de)muxer utilities -+ */ -+ -+#ifndef AVFORMAT_HEVC_H -+#define AVFORMAT_HEVC_H -+ -+#include <stdint.h> -+#include "avio.h" -+ -+/** -+ * Writes Annex B formatted HEVC NAL units to the provided AVIOContext. -+ * -+ * The NAL units are converted to an MP4-compatible format (start code prefixes -+ * are replaced by 4-byte size fields, as per ISO/IEC 14496-15). -+ * -+ * If filter_ps is non-zero, any HEVC parameter sets found in the input will be -+ * discarded, and *ps_count will be set to the number of discarded PS NAL units. -+ * -+ * @param pb address of the AVIOContext where the data shall be written -+ * @param buf_in address of the buffer holding the input data -+ * @param size size (in bytes) of the input buffer -+ * @param filter_ps whether to write parameter set NAL units to the output (0) -+ * or to discard them (non-zero) -+ * @param ps_count address of the variable where the number of discarded -+ * parameter set NAL units shall be written, may be NULL -+ * @return the amount (in bytes) of data written in case of success, a negative -+ * value corresponding to an AVERROR code in case of failure -+ */ -+int ff_hevc_annexb2mp4(AVIOContext *pb, const uint8_t *buf_in, -+ int size, int filter_ps, int *ps_count); -+ -+/** -+ * Writes Annex B formatted HEVC NAL units to a data buffer. -+ * -+ * The NAL units are converted to an MP4-compatible format (start code prefixes -+ * are replaced by 4-byte size fields, as per ISO/IEC 14496-15). -+ * -+ * If filter_ps is non-zero, any HEVC parameter sets found in the input will be -+ * discarded, and *ps_count will be set to the number of discarded PS NAL units. -+ * -+ * On output, *size holds the size (in bytes) of the output data buffer. -+ * -+ * @param buf_in address of the buffer holding the input data -+ * @param size address of the variable holding the size (in bytes) of the input -+ * buffer (on input) and of the output buffer (on output) -+ * @param buf_out address of the variable holding the address of the output -+ * buffer -+ * @param filter_ps whether to write parameter set NAL units to the output (0) -+ * or to discard them (non-zero) -+ * @param ps_count address of the variable where the number of discarded -+ * parameter set NAL units shall be written, may be NULL -+ * @return the amount (in bytes) of data written in case of success, a negative -+ * value corresponding to an AVERROR code in case of failure -+ */ -+int ff_hevc_annexb2mp4_buf(const uint8_t *buf_in, uint8_t **buf_out, -+ int *size, int filter_ps, int *ps_count); -+ -+/** -+ * Writes HEVC extradata (parameter sets, declarative SEI NAL units) to the -+ * provided AVIOContext. -+ * -+ * If the extradata is Annex B format, it gets converted to hvcC format before -+ * writing. -+ * -+ * @param pb address of the AVIOContext where the hvcC shall be written -+ * @param data address of the buffer holding the data needed to write the hvcC -+ * @param size size (in bytes) of the data buffer -+ * @param ps_array_completeness whether all parameter sets are in the hvcC (1) -+ * or there may be additional parameter sets in the bitstream (0) -+ * @return 0 in case of success, a negative value corresponding to an AVERROR -+ * code in case of failure -+ */ -+int ff_isom_write_hvcc(AVIOContext *pb, const uint8_t *data, -+ int size, int ps_array_completeness); -+ -+#endif /* AVFORMAT_HEVC_H */ -diff --git a/libavformat/isom.c b/libavformat/isom.c -index 9b32b7d..76c455b 100644 ---- a/libavformat/isom.c -+++ b/libavformat/isom.c -@@ -33,6 +33,7 @@ const AVCodecTag ff_mp4_obj_type[] = { - { AV_CODEC_ID_MOV_TEXT , 0x08 }, - { AV_CODEC_ID_MPEG4 , 0x20 }, - { AV_CODEC_ID_H264 , 0x21 }, -+ { AV_CODEC_ID_HEVC , 0x23 }, - { AV_CODEC_ID_AAC , 0x40 }, - { AV_CODEC_ID_MP4ALS , 0x40 }, /* 14496-3 ALS */ - { AV_CODEC_ID_MPEG2VIDEO , 0x61 }, /* MPEG2 Main */ -@@ -136,8 +137,8 @@ const AVCodecTag ff_codec_movvideo_tags[] = { - - { AV_CODEC_ID_RAWVIDEO, MKTAG('W', 'R', 'A', 'W') }, - -- { AV_CODEC_ID_HEVC, MKTAG('h', 'v', 'c', '1') }, /* HEVC/H.265 which indicates parameter sets shall not be in ES */ - { AV_CODEC_ID_HEVC, MKTAG('h', 'e', 'v', '1') }, /* HEVC/H.265 which indicates parameter sets may be in ES */ -+ { AV_CODEC_ID_HEVC, MKTAG('h', 'v', 'c', '1') }, /* HEVC/H.265 which indicates parameter sets shall not be in ES */ - - { AV_CODEC_ID_H264, MKTAG('a', 'v', 'c', '1') }, /* AVC-1/H.264 */ - { AV_CODEC_ID_H264, MKTAG('a', 'i', '5', 'p') }, /* AVC-Intra 50M 720p24/30/60 */ -diff --git a/libavformat/matroskaenc.c b/libavformat/matroskaenc.c -index cc645a5..08f5552 100644 ---- a/libavformat/matroskaenc.c -+++ b/libavformat/matroskaenc.c -@@ -22,6 +22,7 @@ - #include <stdint.h> - - #include "avc.h" -+#include "hevc.h" - #include "avformat.h" - #include "avlanguage.h" - #include "flacenc.h" -@@ -500,6 +501,8 @@ static int mkv_write_codecprivate(AVFormatContext *s, AVIOContext *pb, AVCodecCo - ret = put_wv_codecpriv(dyn_cp, codec); - else if (codec->codec_id == AV_CODEC_ID_H264) - ret = ff_isom_write_avcc(dyn_cp, codec->extradata, codec->extradata_size); -+ else if (codec->codec_id == AV_CODEC_ID_HEVC) -+ ret = ff_isom_write_hvcc(dyn_cp, codec->extradata, codec->extradata_size, 0); - else if (codec->codec_id == AV_CODEC_ID_ALAC) { - if (codec->extradata_size < 36) { - av_log(s, AV_LOG_ERROR, -@@ -1160,6 +1163,10 @@ static void mkv_write_block(AVFormatContext *s, AVIOContext *pb, - if (codec->codec_id == AV_CODEC_ID_H264 && codec->extradata_size > 0 && - (AV_RB24(codec->extradata) == 1 || AV_RB32(codec->extradata) == 1)) - ff_avc_parse_nal_units_buf(pkt->data, &data, &size); -+ else if (codec->codec_id == AV_CODEC_ID_HEVC && codec->extradata_size > 6 && -+ (AV_RB24(codec->extradata) == 1 || AV_RB32(codec->extradata) == 1)) -+ /* extradata is Annex B, assume the bitstream is too and convert it */ -+ ff_hevc_annexb2mp4_buf(pkt->data, &data, &size, 0, NULL); - else if (codec->codec_id == AV_CODEC_ID_WAVPACK) { - int ret = mkv_strip_wavpack(pkt->data, &data, &size); - if (ret < 0) { -diff --git a/libavformat/movenc.c b/libavformat/movenc.c -index 43a1647..415d808 100644 ---- a/libavformat/movenc.c -+++ b/libavformat/movenc.c -@@ -39,6 +39,7 @@ - #include "libavutil/mathematics.h" - #include "libavutil/opt.h" - #include "libavutil/dict.h" -+#include "hevc.h" - #include "rtpenc.h" - #include "mov_chan.h" - -@@ -685,6 +686,16 @@ static int mov_write_avcc_tag(AVIOContext *pb, MOVTrack *track) - return update_size(pb, pos); - } - -+static int mov_write_hvcc_tag(AVIOContext *pb, MOVTrack *track) -+{ -+ int64_t pos = avio_tell(pb); -+ -+ avio_wb32(pb, 0); -+ ffio_wfourcc(pb, "hvcC"); -+ ff_isom_write_hvcc(pb, track->vos_data, track->vos_len, 0); -+ return update_size(pb, pos); -+} -+ - /* also used by all avid codecs (dv, imx, meridien) and their variants */ - static int mov_write_avid_tag(AVIOContext *pb, MOVTrack *track) - { -@@ -741,6 +752,7 @@ static int mp4_get_codec_tag(AVFormatContext *s, MOVTrack *track) - return 0; - - if (track->enc->codec_id == AV_CODEC_ID_H264) tag = MKTAG('a','v','c','1'); -+ else if (track->enc->codec_id == AV_CODEC_ID_HEVC) tag = MKTAG('h','e','v','1'); - else if (track->enc->codec_id == AV_CODEC_ID_AC3) tag = MKTAG('a','c','-','3'); - else if (track->enc->codec_id == AV_CODEC_ID_DIRAC) tag = MKTAG('d','r','a','c'); - else if (track->enc->codec_id == AV_CODEC_ID_MOV_TEXT) tag = MKTAG('t','x','3','g'); -@@ -1035,6 +1047,8 @@ static int mov_write_video_tag(AVIOContext *pb, MOVTrack *track) - mov_write_svq3_tag(pb); - else if (track->enc->codec_id == AV_CODEC_ID_DNXHD) - mov_write_avid_tag(pb, track); -+ else if (track->enc->codec_id == AV_CODEC_ID_HEVC) -+ mov_write_hvcc_tag(pb, track); - else if (track->enc->codec_id == AV_CODEC_ID_H264) { - mov_write_avcc_tag(pb, track); - if (track->mode == MODE_IPOD) -@@ -2925,6 +2939,15 @@ int ff_mov_write_packet(AVFormatContext *s, AVPacket *pkt) - } else { - size = ff_avc_parse_nal_units(pb, pkt->data, pkt->size); - } -+ } else if (enc->codec_id == AV_CODEC_ID_HEVC && trk->vos_len > 6 && -+ (AV_RB24(trk->vos_data) == 1 || AV_RB32(trk->vos_data) == 1)) { -+ /* extradata is Annex B, assume the bitstream is too and convert it */ -+ if (trk->hint_track >= 0 && trk->hint_track < mov->nb_streams) { -+ ff_hevc_annexb2mp4_buf(pkt->data, &reformatted_data, &size, 0, NULL); -+ avio_write(pb, reformatted_data, size); -+ } else { -+ size = ff_hevc_annexb2mp4(pb, pkt->data, pkt->size, 0, NULL); -+ } - } else { - avio_write(pb, pkt->data, size); - } diff --git a/contrib/ffmpeg/P01-solaris.patch b/contrib/ffmpeg/P01-solaris.patch index e9f0ce3f4..501a1f1d9 100644 --- a/contrib/ffmpeg/P01-solaris.patch +++ b/contrib/ffmpeg/P01-solaris.patch @@ -1,8 +1,8 @@ diff --git a/configure b/configure -index 945a012..704ee87 100755 +index c6789d5..2ff3621 100755 --- a/configure +++ b/configure -@@ -3593,7 +3593,7 @@ EOF +@@ -3602,7 +3602,7 @@ EOF check_cc <<EOF || die "endian test failed" unsigned int endian = 'B' << 24 | 'I' << 16 | 'G' << 8 | 'E'; EOF diff --git a/contrib/ffmpeg/P02-darwin-pic.patch b/contrib/ffmpeg/P02-darwin-pic.patch index ee1fa01a2..79fd3313a 100644 --- a/contrib/ffmpeg/P02-darwin-pic.patch +++ b/contrib/ffmpeg/P02-darwin-pic.patch @@ -1,8 +1,8 @@ diff --git a/configure b/configure -index 945a012..e9b706f 100755 +index c6789d5..d041718 100755 --- a/configure +++ b/configure -@@ -3267,6 +3267,7 @@ case $target_os in +@@ -3276,6 +3276,7 @@ case $target_os in SLIBNAME_WITH_MAJOR='$(SLIBPREF)$(FULLNAME).$(LIBMAJOR)$(SLIBSUF)' objformat="macho" enabled x86_64 && objformat="macho64" @@ -10,7 +10,7 @@ index 945a012..e9b706f 100755 enabled_any pic shared || { check_cflags -mdynamic-no-pic && add_asflags -mdynamic-no-pic; } ;; -@@ -3506,7 +3507,7 @@ esc(){ +@@ -3515,7 +3516,7 @@ esc(){ echo "config:$arch:$subarch:$cpu:$target_os:$(esc $cc_ident):$(esc $LIBAV_CONFIGURATION)" >config.fate diff --git a/contrib/ffmpeg/module.defs b/contrib/ffmpeg/module.defs index b04c65bb4..32e4e7624 100644 --- a/contrib/ffmpeg/module.defs +++ b/contrib/ffmpeg/module.defs @@ -5,7 +5,7 @@ $(eval $(call import.MODULE.defs,FFMPEG,ffmpeg,YASM BZIP2 ZLIB FDKAAC)) endif $(eval $(call import.CONTRIB.defs,FFMPEG)) -FFMPEG.FETCH.url = http://download.handbrake.fr/handbrake/contrib/libav-v10_beta1.tar.bz2 +FFMPEG.FETCH.url = http://download.handbrake.fr/handbrake/contrib/libav-v10_beta2.tar.bz2 FFMPEG.CONFIGURE.deps = FFMPEG.CONFIGURE.env = |