diff options
author | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2018-12-10 16:19:40 +0100 |
---|---|---|
committer | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2018-12-10 16:01:50 +0000 |
commit | 51f6c2793adab2d864b3d2b360000ef8db1d3e92 (patch) | |
tree | 835b3b4446b012c75e80177cef9fbe6972cc7dbe /chromium/third_party/ffmpeg/libavformat | |
parent | 6036726eb981b6c4b42047513b9d3f4ac865daac (diff) | |
download | qtwebengine-chromium-51f6c2793adab2d864b3d2b360000ef8db1d3e92.tar.gz |
BASELINE: Update Chromium to 71.0.3578.93
Change-Id: I6a32086c33670e1b033f8b10e6bf1fd4da1d105d
Reviewed-by: Alexandru Croitor <alexandru.croitor@qt.io>
Diffstat (limited to 'chromium/third_party/ffmpeg/libavformat')
48 files changed, 1421 insertions, 408 deletions
diff --git a/chromium/third_party/ffmpeg/libavformat/Makefile b/chromium/third_party/ffmpeg/libavformat/Makefile index f2f3aabdc29..ccb39b54699 100644 --- a/chromium/third_party/ffmpeg/libavformat/Makefile +++ b/chromium/third_party/ffmpeg/libavformat/Makefile @@ -115,6 +115,8 @@ OBJS-$(CONFIG_AVI_MUXER) += avienc.o mpegtsenc.o avlanguage.o ra OBJS-$(CONFIG_AVM2_MUXER) += swfenc.o swf.o OBJS-$(CONFIG_AVR_DEMUXER) += avr.o pcm.o OBJS-$(CONFIG_AVS_DEMUXER) += avs.o voc_packet.o vocdec.o voc.o +OBJS-$(CONFIG_AVS2_DEMUXER) += davs2.o rawdec.o +OBJS-$(CONFIG_AVS2_MUXER) += rawenc.o OBJS-$(CONFIG_BETHSOFTVID_DEMUXER) += bethsoftvid.o OBJS-$(CONFIG_BFI_DEMUXER) += bfi.o OBJS-$(CONFIG_BINK_DEMUXER) += bink.o @@ -285,7 +287,7 @@ OBJS-$(CONFIG_MATROSKA_DEMUXER) += matroskadec.o matroska.o \ oggparsevorbis.o vorbiscomment.o \ flac_picture.o replaygain.o OBJS-$(CONFIG_MATROSKA_MUXER) += matroskaenc.o matroska.o \ - avc.o hevc.o \ + av1.o avc.o hevc.o \ flacenc_header.o avlanguage.o vorbiscomment.o wv.o \ webmdashenc.o webm_chunk.o OBJS-$(CONFIG_MD5_MUXER) += hashenc.o @@ -529,7 +531,7 @@ OBJS-$(CONFIG_WAV_DEMUXER) += wavdec.o pcm.o OBJS-$(CONFIG_WAV_MUXER) += wavenc.o OBJS-$(CONFIG_WC3_DEMUXER) += wc3movie.o OBJS-$(CONFIG_WEBM_MUXER) += matroskaenc.o matroska.o \ - avc.o hevc.o \ + av1.o avc.o hevc.o \ flacenc_header.o avlanguage.o \ wv.o vorbiscomment.o \ webmdashenc.o webm_chunk.o @@ -557,20 +559,12 @@ OBJS-$(CONFIG_YOP_DEMUXER) += yop.o OBJS-$(CONFIG_YUV4MPEGPIPE_DEMUXER) += yuv4mpegdec.o OBJS-$(CONFIG_YUV4MPEGPIPE_MUXER) += yuv4mpegenc.o -# external libraries +# external library muxers/demuxers OBJS-$(CONFIG_AVISYNTH_DEMUXER) += avisynth.o OBJS-$(CONFIG_CHROMAPRINT_MUXER) += chromaprint.o OBJS-$(CONFIG_LIBGME_DEMUXER) += libgme.o OBJS-$(CONFIG_LIBMODPLUG_DEMUXER) += libmodplug.o OBJS-$(CONFIG_LIBOPENMPT_DEMUXER) += libopenmpt.o -OBJS-$(CONFIG_LIBRTMP_PROTOCOL) += librtmp.o -OBJS-$(CONFIG_LIBRTMPE_PROTOCOL) += librtmp.o -OBJS-$(CONFIG_LIBRTMPS_PROTOCOL) += librtmp.o -OBJS-$(CONFIG_LIBRTMPT_PROTOCOL) += librtmp.o -OBJS-$(CONFIG_LIBRTMPTE_PROTOCOL) += librtmp.o -OBJS-$(CONFIG_LIBSRT_PROTOCOL) += libsrt.o -OBJS-$(CONFIG_LIBSSH_PROTOCOL) += libssh.o -OBJS-$(CONFIG_LIBSMBCLIENT_PROTOCOL) += libsmbclient.o OBJS-$(CONFIG_VAPOURSYNTH_DEMUXER) += vapoursynth.o # protocols I/O @@ -619,6 +613,16 @@ OBJS-$(CONFIG_UDP_PROTOCOL) += udp.o OBJS-$(CONFIG_UDPLITE_PROTOCOL) += udp.o OBJS-$(CONFIG_UNIX_PROTOCOL) += unix.o +# external library protocols +OBJS-$(CONFIG_LIBRTMP_PROTOCOL) += librtmp.o +OBJS-$(CONFIG_LIBRTMPE_PROTOCOL) += librtmp.o +OBJS-$(CONFIG_LIBRTMPS_PROTOCOL) += librtmp.o +OBJS-$(CONFIG_LIBRTMPT_PROTOCOL) += librtmp.o +OBJS-$(CONFIG_LIBRTMPTE_PROTOCOL) += librtmp.o +OBJS-$(CONFIG_LIBSMBCLIENT_PROTOCOL) += libsmbclient.o +OBJS-$(CONFIG_LIBSRT_PROTOCOL) += libsrt.o +OBJS-$(CONFIG_LIBSSH_PROTOCOL) += libssh.o + # libavdevice dependencies OBJS-$(CONFIG_IEC61883_INDEV) += dv.o diff --git a/chromium/third_party/ffmpeg/libavformat/allformats.c b/chromium/third_party/ffmpeg/libavformat/allformats.c index adcc8d90a7d..5c32ee6dff9 100644 --- a/chromium/third_party/ffmpeg/libavformat/allformats.c +++ b/chromium/third_party/ffmpeg/libavformat/allformats.c @@ -76,6 +76,8 @@ extern AVInputFormat ff_avisynth_demuxer; extern AVOutputFormat ff_avm2_muxer; extern AVInputFormat ff_avr_demuxer; extern AVInputFormat ff_avs_demuxer; +extern AVInputFormat ff_avs2_demuxer; +extern AVOutputFormat ff_avs2_muxer; extern AVInputFormat ff_bethsoftvid_demuxer; extern AVInputFormat ff_bfi_demuxer; extern AVInputFormat ff_bintext_demuxer; diff --git a/chromium/third_party/ffmpeg/libavformat/audiointerleave.c b/chromium/third_party/ffmpeg/libavformat/audiointerleave.c index 6d4954befed..dea5d99821c 100644 --- a/chromium/third_party/ffmpeg/libavformat/audiointerleave.c +++ b/chromium/third_party/ffmpeg/libavformat/audiointerleave.c @@ -81,15 +81,19 @@ static int interleave_new_audio_packet(AVFormatContext *s, AVPacket *pkt, AVStream *st = s->streams[stream_index]; AudioInterleaveContext *aic = st->priv_data; int ret; - int size = FFMIN(av_fifo_size(aic->fifo), *aic->samples * aic->sample_size); + int frame_size = *aic->samples * aic->sample_size; + int size = FFMIN(av_fifo_size(aic->fifo), frame_size); if (!size || (!flush && size == av_fifo_size(aic->fifo))) return 0; - ret = av_new_packet(pkt, size); + ret = av_new_packet(pkt, frame_size); if (ret < 0) return ret; av_fifo_generic_read(aic->fifo, pkt->data, size, NULL); + if (size < pkt->size) + memset(pkt->data + size, 0, pkt->size - size); + pkt->dts = pkt->pts = aic->dts; pkt->duration = av_rescale_q(*aic->samples, st->time_base, aic->time_base); pkt->stream_index = stream_index; @@ -99,7 +103,7 @@ static int interleave_new_audio_packet(AVFormatContext *s, AVPacket *pkt, if (!*aic->samples) aic->samples = aic->samples_per_frame; - return size; + return pkt->size; } int ff_audio_rechunk_interleave(AVFormatContext *s, AVPacket *out, AVPacket *pkt, int flush, diff --git a/chromium/third_party/ffmpeg/libavformat/av1.c b/chromium/third_party/ffmpeg/libavformat/av1.c index 7db29c8d764..a0aad436a69 100644 --- a/chromium/third_party/ffmpeg/libavformat/av1.c +++ b/chromium/third_party/ffmpeg/libavformat/av1.c @@ -22,6 +22,8 @@ #include "libavutil/mem.h" #include "libavcodec/av1.h" #include "libavcodec/av1_parse.h" +#include "libavcodec/profiles.h" +#include "libavcodec/put_bits.h" #include "av1.h" #include "avio.h" @@ -33,26 +35,23 @@ int ff_av1_filter_obus(AVIOContext *pb, const uint8_t *buf, int size) size = 0; while (buf < end) { - int ret = parse_obu_header(buf, end - buf, &obu_size, &start_pos, + int len = parse_obu_header(buf, end - buf, &obu_size, &start_pos, &type, &temporal_id, &spatial_id); - if (ret < 0) - return ret; - - obu_size += start_pos; - if (obu_size > INT_MAX) - return AVERROR_INVALIDDATA; + if (len < 0) + return len; switch (type) { case AV1_OBU_TEMPORAL_DELIMITER: case AV1_OBU_REDUNDANT_FRAME_HEADER: + case AV1_OBU_TILE_LIST: case AV1_OBU_PADDING: break; default: - avio_write(pb, buf, obu_size); - size += obu_size; + avio_write(pb, buf, len); + size += len; break; } - buf += obu_size; + buf += len; } return size; @@ -77,32 +76,318 @@ int ff_av1_filter_obus_buf(const uint8_t *buf, uint8_t **out, int *size) return ret; } +typedef struct AV1SequenceParameters { + uint8_t seq_profile; + uint8_t seq_level_idx_0; + uint8_t seq_tier_0; + uint8_t high_bitdepth; + uint8_t twelve_bit; + uint8_t monochrome; + uint8_t chroma_subsampling_x; + uint8_t chroma_subsampling_y; + uint8_t chroma_sample_position; +} AV1SequenceParameters; + +static inline void uvlc(GetBitContext *gb) +{ + int leading_zeros = 0; + + while (get_bits_left(gb)) { + if (get_bits1(gb)) + break; + leading_zeros++; + } + + if (leading_zeros >= 32) + return; + + skip_bits_long(gb, leading_zeros); +} + +static int parse_color_config(AV1SequenceParameters *seq_params, GetBitContext *gb) +{ + int color_primaries, transfer_characteristics, matrix_coefficients; + + seq_params->high_bitdepth = get_bits1(gb); + if (seq_params->seq_profile == FF_PROFILE_AV1_PROFESSIONAL && seq_params->high_bitdepth) + seq_params->twelve_bit = get_bits1(gb); + + if (seq_params->seq_profile == FF_PROFILE_AV1_HIGH) + seq_params->monochrome = 0; + else + seq_params->monochrome = get_bits1(gb); + + if (get_bits1(gb)) { // color_description_present_flag + color_primaries = get_bits(gb, 8); + transfer_characteristics = get_bits(gb, 8); + matrix_coefficients = get_bits(gb, 8); + } else { + color_primaries = AVCOL_PRI_UNSPECIFIED; + transfer_characteristics = AVCOL_TRC_UNSPECIFIED; + matrix_coefficients = AVCOL_SPC_UNSPECIFIED; + } + + if (seq_params->monochrome) { + skip_bits1(gb); // color_range + seq_params->chroma_subsampling_x = 1; + seq_params->chroma_subsampling_y = 1; + seq_params->chroma_sample_position = 0; + return 0; + } else if (color_primaries == AVCOL_PRI_BT709 && + transfer_characteristics == AVCOL_TRC_IEC61966_2_1 && + matrix_coefficients == AVCOL_SPC_RGB) { + seq_params->chroma_subsampling_x = 0; + seq_params->chroma_subsampling_y = 0; + } else { + skip_bits1(gb); // color_range + + if (seq_params->seq_profile == FF_PROFILE_AV1_MAIN) { + seq_params->chroma_subsampling_x = 1; + seq_params->chroma_subsampling_y = 1; + } else if (seq_params->seq_profile == FF_PROFILE_AV1_HIGH) { + seq_params->chroma_subsampling_x = 0; + seq_params->chroma_subsampling_y = 0; + } else { + if (seq_params->twelve_bit) { + seq_params->chroma_subsampling_x = get_bits1(gb); + if (seq_params->chroma_subsampling_x) + seq_params->chroma_subsampling_y = get_bits1(gb); + else + seq_params->chroma_subsampling_y = 0; + } else { + seq_params->chroma_subsampling_x = 1; + seq_params->chroma_subsampling_y = 0; + } + } + if (seq_params->chroma_subsampling_x && seq_params->chroma_subsampling_y) + seq_params->chroma_sample_position = get_bits(gb, 2); + } + + skip_bits1(gb); // separate_uv_delta_q + + return 0; +} + +static int parse_sequence_header(AV1SequenceParameters *seq_params, const uint8_t *buf, int size) +{ + GetBitContext gb; + int reduced_still_picture_header; + int frame_width_bits_minus_1, frame_height_bits_minus_1; + int size_bits, ret; + + size_bits = get_obu_bit_length(buf, size, AV1_OBU_SEQUENCE_HEADER); + if (size_bits < 0) + return size_bits; + + ret = init_get_bits(&gb, buf, size_bits); + if (ret < 0) + return ret; + + memset(seq_params, 0, sizeof(*seq_params)); + + seq_params->seq_profile = get_bits(&gb, 3); + + skip_bits1(&gb); // still_picture + reduced_still_picture_header = get_bits1(&gb); + + if (reduced_still_picture_header) { + seq_params->seq_level_idx_0 = get_bits(&gb, 5); + seq_params->seq_tier_0 = 0; + } else { + int initial_display_delay_present_flag, operating_points_cnt_minus_1; + int decoder_model_info_present_flag, buffer_delay_length_minus_1; + + if (get_bits1(&gb)) { // timing_info_present_flag + skip_bits_long(&gb, 32); // num_units_in_display_tick + skip_bits_long(&gb, 32); // time_scale + + if (get_bits1(&gb)) // equal_picture_interval + uvlc(&gb); // num_ticks_per_picture_minus_1 + + decoder_model_info_present_flag = get_bits1(&gb); + if (decoder_model_info_present_flag) { + buffer_delay_length_minus_1 = get_bits(&gb, 5); + skip_bits_long(&gb, 32); // num_units_in_decoding_tick + skip_bits(&gb, 10); // buffer_removal_time_length_minus_1 (5) + // frame_presentation_time_length_minus_1 (5) + } + } else + decoder_model_info_present_flag = 0; + + initial_display_delay_present_flag = get_bits1(&gb); + + operating_points_cnt_minus_1 = get_bits(&gb, 5); + for (int i = 0; i <= operating_points_cnt_minus_1; i++) { + int seq_level_idx, seq_tier; + + skip_bits(&gb, 12); // operating_point_idc + seq_level_idx = get_bits(&gb, 5); + + if (seq_level_idx > 7) + seq_tier = get_bits1(&gb); + else + seq_tier = 0; + + if (decoder_model_info_present_flag) { + if (get_bits1(&gb)) { // decoder_model_present_for_this_op + skip_bits_long(&gb, buffer_delay_length_minus_1 + 1); // decoder_buffer_delay + skip_bits_long(&gb, buffer_delay_length_minus_1 + 1); // encoder_buffer_delay + skip_bits1(&gb); // low_delay_mode_flag + } + } + + if (initial_display_delay_present_flag) { + if (get_bits1(&gb)) // initial_display_delay_present_for_this_op + skip_bits(&gb, 4); // initial_display_delay_minus_1 + } + + if (i == 0) { + seq_params->seq_level_idx_0 = seq_level_idx; + seq_params->seq_tier_0 = seq_tier; + } + } + } + + frame_width_bits_minus_1 = get_bits(&gb, 4); + frame_height_bits_minus_1 = get_bits(&gb, 4); + + skip_bits(&gb, frame_width_bits_minus_1 + 1); // max_frame_width_minus_1 + skip_bits(&gb, frame_height_bits_minus_1 + 1); // max_frame_height_minus_1 + + if (!reduced_still_picture_header) { + if (get_bits1(&gb)) // frame_id_numbers_present_flag + skip_bits(&gb, 7); // delta_frame_id_length_minus_2 (4), additional_frame_id_length_minus_1 (3) + } + + skip_bits(&gb, 3); // use_128x128_superblock (1), enable_filter_intra (1), enable_intra_edge_filter (1) + + if (!reduced_still_picture_header) { + int enable_order_hint, seq_force_screen_content_tools; + + skip_bits(&gb, 4); // enable_intraintra_compound (1), enable_masked_compound (1) + // enable_warped_motion (1), enable_dual_filter (1) + + enable_order_hint = get_bits1(&gb); + if (enable_order_hint) + skip_bits(&gb, 2); // enable_jnt_comp (1), enable_ref_frame_mvs (1) + + if (get_bits1(&gb)) // seq_choose_screen_content_tools + seq_force_screen_content_tools = 2; + else + seq_force_screen_content_tools = get_bits1(&gb); + + if (seq_force_screen_content_tools) { + if (!get_bits1(&gb)) // seq_choose_integer_mv + skip_bits1(&gb); // seq_force_integer_mv + } + + if (enable_order_hint) + skip_bits(&gb, 3); // order_hint_bits_minus_1 + } + + skip_bits(&gb, 3); // enable_superres (1), enable_cdef (1), enable_restoration (1) + + parse_color_config(seq_params, &gb); + + skip_bits1(&gb); // film_grain_params_present + + if (get_bits_left(&gb)) + return AVERROR_INVALIDDATA; + + return 0; +} + int ff_isom_write_av1c(AVIOContext *pb, const uint8_t *buf, int size) { + AVIOContext *seq_pb = NULL, *meta_pb = NULL; + AV1SequenceParameters seq_params; + PutBitContext pbc; + uint8_t header[4]; + uint8_t *seq = NULL, *meta = NULL; int64_t obu_size; int start_pos, type, temporal_id, spatial_id; + int ret, nb_seq = 0, seq_size, meta_size; + + if (size <= 0) + return AVERROR_INVALIDDATA; + + ret = avio_open_dyn_buf(&seq_pb); + if (ret < 0) + return ret; + ret = avio_open_dyn_buf(&meta_pb); + if (ret < 0) + goto fail; while (size > 0) { - int ret = parse_obu_header(buf, size, &obu_size, &start_pos, + int len = parse_obu_header(buf, size, &obu_size, &start_pos, &type, &temporal_id, &spatial_id); - if (ret < 0) - return ret; - - obu_size += start_pos; - if (obu_size > INT_MAX) - return AVERROR_INVALIDDATA; + if (len < 0) { + ret = len; + goto fail; + } switch (type) { case AV1_OBU_SEQUENCE_HEADER: + nb_seq++; + if (!obu_size || nb_seq > 1) { + ret = AVERROR_INVALIDDATA; + goto fail; + } + ret = parse_sequence_header(&seq_params, buf + start_pos, obu_size); + if (ret < 0) + goto fail; + + avio_write(seq_pb, buf, len); + break; case AV1_OBU_METADATA: - avio_write(pb, buf, obu_size); + if (!obu_size) { + ret = AVERROR_INVALIDDATA; + goto fail; + } + avio_write(meta_pb, buf, len); break; default: break; } - size -= obu_size; - buf += obu_size; + size -= len; + buf += len; } - return 0; + seq_size = avio_close_dyn_buf(seq_pb, &seq); + if (!seq_size) { + ret = AVERROR_INVALIDDATA; + goto fail; + } + + init_put_bits(&pbc, header, sizeof(header)); + + put_bits(&pbc, 1, 1); // marker + put_bits(&pbc, 7, 1); // version + put_bits(&pbc, 3, seq_params.seq_profile); + put_bits(&pbc, 5, seq_params.seq_level_idx_0); + put_bits(&pbc, 1, seq_params.seq_tier_0); + put_bits(&pbc, 1, seq_params.high_bitdepth); + put_bits(&pbc, 1, seq_params.twelve_bit); + put_bits(&pbc, 1, seq_params.monochrome); + put_bits(&pbc, 1, seq_params.chroma_subsampling_x); + put_bits(&pbc, 1, seq_params.chroma_subsampling_y); + put_bits(&pbc, 2, seq_params.chroma_sample_position); + flush_put_bits(&pbc); + + avio_write(pb, header, sizeof(header)); + avio_write(pb, seq, seq_size); + + meta_size = avio_close_dyn_buf(meta_pb, &meta); + if (meta_size) + avio_write(pb, meta, meta_size); + +fail: + if (!seq) + avio_close_dyn_buf(seq_pb, &seq); + if (!meta) + avio_close_dyn_buf(meta_pb, &meta); + av_free(seq); + av_free(meta); + + return ret; } diff --git a/chromium/third_party/ffmpeg/libavformat/avidec.c b/chromium/third_party/ffmpeg/libavformat/avidec.c index bafe1dc8da0..3f074795a75 100644 --- a/chromium/third_party/ffmpeg/libavformat/avidec.c +++ b/chromium/third_party/ffmpeg/libavformat/avidec.c @@ -1231,6 +1231,11 @@ start_sync: goto start_sync; } + if (d[2] == 'w' && d[3] == 'c' && n < s->nb_streams) { + avio_skip(pb, 16 * 3 + 8); + goto start_sync; + } + if (avi->dv_demux && n != 0) continue; diff --git a/chromium/third_party/ffmpeg/libavformat/avs.c b/chromium/third_party/ffmpeg/libavformat/avs.c index 763ba63f64f..62f5a42ac92 100644 --- a/chromium/third_party/ffmpeg/libavformat/avs.c +++ b/chromium/third_party/ffmpeg/libavformat/avs.c @@ -19,6 +19,12 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ +/** + * @file + * Argonaut Games' Creature Shock demuxer + * @see http://wiki.multimedia.cx/index.php?title=AVS + */ + #include "avformat.h" #include "voc.h" @@ -225,7 +231,7 @@ static int avs_read_close(AVFormatContext * s) AVInputFormat ff_avs_demuxer = { .name = "avs", - .long_name = NULL_IF_CONFIG_SMALL("AVS"), + .long_name = NULL_IF_CONFIG_SMALL("Argonaut Games Creature Shock"), .priv_data_size = sizeof(AvsFormat), .read_probe = avs_probe, .read_header = avs_read_header, diff --git a/chromium/third_party/ffmpeg/libavformat/dashdec.c b/chromium/third_party/ffmpeg/libavformat/dashdec.c index 89f3ac27597..497e7e469cb 100644 --- a/chromium/third_party/ffmpeg/libavformat/dashdec.c +++ b/chromium/third_party/ffmpeg/libavformat/dashdec.c @@ -122,6 +122,19 @@ struct representation { typedef struct DASHContext { const AVClass *class; char *base_url; + char *adaptionset_contenttype_val; + char *adaptionset_par_val; + char *adaptionset_lang_val; + char *adaptionset_minbw_val; + char *adaptionset_maxbw_val; + char *adaptionset_minwidth_val; + char *adaptionset_maxwidth_val; + char *adaptionset_minheight_val; + char *adaptionset_maxheight_val; + char *adaptionset_minframerate_val; + char *adaptionset_maxframerate_val; + char *adaptionset_segmentalignment_val; + char *adaptionset_bitstreamswitching_val; int n_videos; struct representation **videos; @@ -132,6 +145,7 @@ typedef struct DASHContext { uint64_t media_presentation_duration; uint64_t suggested_presentation_delay; uint64_t availability_start_time; + uint64_t availability_end_time; uint64_t publish_time; uint64_t minimum_update_period; uint64_t time_shift_buffer_depth; @@ -143,9 +157,6 @@ typedef struct DASHContext { int is_live; AVIOInterruptCB *interrupt_callback; - char *user_agent; ///< holds HTTP user agent set as an AVOption to the HTTP protocol context - char *cookies; ///< holds HTTP cookie values set in either the initial response or as an AVOption to the HTTP protocol context - char *headers; ///< holds HTTP headers set as an AVOption to the HTTP protocol context char *allowed_extensions; AVDictionary *avio_opts; int max_url_size; @@ -262,6 +273,12 @@ static int64_t get_segment_start_time_based_on_timeline(struct representation *p goto finish; start_time += pls->timelines[i]->duration; + + if (pls->timelines[i]->repeat == -1) { + start_time = pls->timelines[i]->duration * cur_seq_no; + goto finish; + } + for (j = 0; j < pls->timelines[i]->repeat; j++) { num++; if (num == cur_seq_no) @@ -377,24 +394,6 @@ static void free_audio_list(DASHContext *c) c->n_audios = 0; } -static void set_httpheader_options(DASHContext *c, AVDictionary **opts) -{ - // broker prior HTTP options that should be consistent across requests - av_dict_set(opts, "user_agent", c->user_agent, 0); - av_dict_set(opts, "cookies", c->cookies, 0); - av_dict_set(opts, "headers", c->headers, 0); - if (c->is_live) { - av_dict_set(opts, "seekable", "0", 0); - } -} -static void update_options(char **dest, const char *name, void *src) -{ - av_freep(dest); - av_opt_get(src, name, AV_OPT_SEARCH_CHILDREN, (uint8_t**)dest); - if (*dest) - av_freep(dest); -} - static int open_url(AVFormatContext *s, AVIOContext **pb, const char *url, AVDictionary *opts, AVDictionary *opts2, int *is_http) { @@ -448,11 +447,9 @@ static int open_url(AVFormatContext *s, AVIOContext **pb, const char *url, av_opt_get(*pb, "cookies", AV_OPT_SEARCH_CHILDREN, (uint8_t**)&new_cookies); if (new_cookies) { - av_free(c->cookies); - c->cookies = new_cookies; + av_dict_set(&opts, "cookies", new_cookies, AV_DICT_DONT_STRDUP_VAL); } - av_dict_set(&opts, "cookies", c->cookies, 0); } av_dict_free(&tmp); @@ -754,9 +751,12 @@ static int resolve_content_path(AVFormatContext *s, const char *url, int *max_ur if (!(node = baseurl_nodes[rootId])) { continue; } - if (ishttp(xmlNodeGetContent(node))) { + text = xmlNodeGetContent(node); + if (ishttp(text)) { + xmlFree(text); break; } + xmlFree(text); } node = baseurl_nodes[rootId]; @@ -871,7 +871,9 @@ static int parse_manifest_representation(AVFormatContext *s, const char *url, baseurl_nodes[3] = representation_baseurl_node; ret = resolve_content_path(s, url, &c->max_url_size, baseurl_nodes, 4); - c->max_url_size = aligned(c->max_url_size + strlen(rep_id_val) + strlen(rep_bandwidth_val)); + c->max_url_size = aligned(c->max_url_size + + (rep_id_val ? strlen(rep_id_val) : 0) + + (rep_bandwidth_val ? strlen(rep_bandwidth_val) : 0)); if (ret == AVERROR(ENOMEM) || ret == 0) { goto end; } @@ -917,18 +919,22 @@ static int parse_manifest_representation(AVFormatContext *s, const char *url, if (presentation_timeoffset_val) { rep->presentation_timeoffset = (int64_t) strtoll(presentation_timeoffset_val, NULL, 10); + av_log(s, AV_LOG_TRACE, "rep->presentation_timeoffset = [%"PRId64"]\n", rep->presentation_timeoffset); xmlFree(presentation_timeoffset_val); } if (duration_val) { rep->fragment_duration = (int64_t) strtoll(duration_val, NULL, 10); + av_log(s, AV_LOG_TRACE, "rep->fragment_duration = [%"PRId64"]\n", rep->fragment_duration); xmlFree(duration_val); } if (timescale_val) { rep->fragment_timescale = (int64_t) strtoll(timescale_val, NULL, 10); + av_log(s, AV_LOG_TRACE, "rep->fragment_timescale = [%"PRId64"]\n", rep->fragment_timescale); xmlFree(timescale_val); } if (startnumber_val) { rep->first_seq_no = (int64_t) strtoll(startnumber_val, NULL, 10); + av_log(s, AV_LOG_TRACE, "rep->first_seq_no = [%"PRId64"]\n", rep->first_seq_no); xmlFree(startnumber_val); } if (adaptionset_supplementalproperty_node) { @@ -986,10 +992,12 @@ static int parse_manifest_representation(AVFormatContext *s, const char *url, timescale_val = get_val_from_nodes_tab(segmentlists_tab, 2, "timescale"); if (duration_val) { rep->fragment_duration = (int64_t) strtoll(duration_val, NULL, 10); + av_log(s, AV_LOG_TRACE, "rep->fragment_duration = [%"PRId64"]\n", rep->fragment_duration); xmlFree(duration_val); } if (timescale_val) { rep->fragment_timescale = (int64_t) strtoll(timescale_val, NULL, 10); + av_log(s, AV_LOG_TRACE, "rep->fragment_timescale = [%"PRId64"]\n", rep->fragment_timescale); xmlFree(timescale_val); } fragmenturl_node = xmlFirstElementChild(representation_segmentlist_node); @@ -1072,12 +1080,26 @@ static int parse_manifest_adaptationset(AVFormatContext *s, const char *url, xmlNodePtr period_segmentlist_node) { int ret = 0; + DASHContext *c = s->priv_data; xmlNodePtr fragment_template_node = NULL; xmlNodePtr content_component_node = NULL; xmlNodePtr adaptionset_baseurl_node = NULL; xmlNodePtr adaptionset_segmentlist_node = NULL; xmlNodePtr adaptionset_supplementalproperty_node = NULL; xmlNodePtr node = NULL; + c->adaptionset_contenttype_val = xmlGetProp(adaptionset_node, "contentType"); + c->adaptionset_par_val = xmlGetProp(adaptionset_node, "par"); + c->adaptionset_lang_val = xmlGetProp(adaptionset_node, "lang"); + c->adaptionset_minbw_val = xmlGetProp(adaptionset_node, "minBandwidth"); + c->adaptionset_maxbw_val = xmlGetProp(adaptionset_node, "maxBandwidth"); + c->adaptionset_minwidth_val = xmlGetProp(adaptionset_node, "minWidth"); + c->adaptionset_maxwidth_val = xmlGetProp(adaptionset_node, "maxWidth"); + c->adaptionset_minheight_val = xmlGetProp(adaptionset_node, "minHeight"); + c->adaptionset_maxheight_val = xmlGetProp(adaptionset_node, "maxHeight"); + c->adaptionset_minframerate_val = xmlGetProp(adaptionset_node, "minFrameRate"); + c->adaptionset_maxframerate_val = xmlGetProp(adaptionset_node, "maxFrameRate"); + c->adaptionset_segmentalignment_val = xmlGetProp(adaptionset_node, "segmentAlignment"); + c->adaptionset_bitstreamswitching_val = xmlGetProp(adaptionset_node, "bitstreamSwitching"); node = xmlFirstElementChild(adaptionset_node); while (node) { @@ -1139,7 +1161,7 @@ static int parse_manifest(AVFormatContext *s, const char *url, AVIOContext *in) if (!in) { close_in = 1; - set_httpheader_options(c, &opts); + av_dict_copy(&opts, c->avio_opts, 0); ret = avio_open2(&in, url, AVIO_FLAG_READ, c->interrupt_callback, &opts); av_dict_free(&opts); if (ret < 0) @@ -1203,18 +1225,28 @@ static int parse_manifest(AVFormatContext *s, const char *url, AVIOContext *in) if (!av_strcasecmp(attr->name, (const char *)"availabilityStartTime")) { c->availability_start_time = get_utc_date_time_insec(s, (const char *)val); + av_log(s, AV_LOG_TRACE, "c->availability_start_time = [%"PRId64"]\n", c->availability_start_time); + } else if (!av_strcasecmp(attr->name, (const char *)"availabilityEndTime")) { + c->availability_end_time = get_utc_date_time_insec(s, (const char *)val); + av_log(s, AV_LOG_TRACE, "c->availability_end_time = [%"PRId64"]\n", c->availability_end_time); } else if (!av_strcasecmp(attr->name, (const char *)"publishTime")) { c->publish_time = get_utc_date_time_insec(s, (const char *)val); + av_log(s, AV_LOG_TRACE, "c->publish_time = [%"PRId64"]\n", c->publish_time); } else if (!av_strcasecmp(attr->name, (const char *)"minimumUpdatePeriod")) { c->minimum_update_period = get_duration_insec(s, (const char *)val); + av_log(s, AV_LOG_TRACE, "c->minimum_update_period = [%"PRId64"]\n", c->minimum_update_period); } else if (!av_strcasecmp(attr->name, (const char *)"timeShiftBufferDepth")) { c->time_shift_buffer_depth = get_duration_insec(s, (const char *)val); + av_log(s, AV_LOG_TRACE, "c->time_shift_buffer_depth = [%"PRId64"]\n", c->time_shift_buffer_depth); } else if (!av_strcasecmp(attr->name, (const char *)"minBufferTime")) { c->min_buffer_time = get_duration_insec(s, (const char *)val); + av_log(s, AV_LOG_TRACE, "c->min_buffer_time = [%"PRId64"]\n", c->min_buffer_time); } else if (!av_strcasecmp(attr->name, (const char *)"suggestedPresentationDelay")) { c->suggested_presentation_delay = get_duration_insec(s, (const char *)val); + av_log(s, AV_LOG_TRACE, "c->suggested_presentation_delay = [%"PRId64"]\n", c->suggested_presentation_delay); } else if (!av_strcasecmp(attr->name, (const char *)"mediaPresentationDuration")) { c->media_presentation_duration = get_duration_insec(s, (const char *)val); + av_log(s, AV_LOG_TRACE, "c->media_presentation_duration = [%"PRId64"]\n", c->media_presentation_duration); } attr = attr->next; xmlFree(val); @@ -1296,8 +1328,10 @@ static int64_t calc_cur_seg_no(AVFormatContext *s, struct representation *pls) if (c->is_live) { if (pls->n_fragments) { + av_log(s, AV_LOG_TRACE, "in n_fragments mode\n"); num = pls->first_seq_no; } else if (pls->n_timelines) { + av_log(s, AV_LOG_TRACE, "in n_timelines mode\n"); start_time_offset = get_segment_start_time_based_on_timeline(pls, 0xFFFFFFFF) - 60 * pls->fragment_timescale; // 60 seconds before end num = calc_next_seg_no_from_timelines(pls, start_time_offset); if (num == -1) @@ -1305,10 +1339,15 @@ static int64_t calc_cur_seg_no(AVFormatContext *s, struct representation *pls) else num += pls->first_seq_no; } else if (pls->fragment_duration){ + av_log(s, AV_LOG_TRACE, "in fragment_duration mode fragment_timescale = %"PRId64", presentation_timeoffset = %"PRId64"\n", pls->fragment_timescale, pls->presentation_timeoffset); if (pls->presentation_timeoffset) { - num = pls->presentation_timeoffset * pls->fragment_timescale / pls->fragment_duration; + num = pls->first_seq_no + (((get_current_time_in_sec() - c->availability_start_time) * pls->fragment_timescale)-pls->presentation_timeoffset) / pls->fragment_duration - c->min_buffer_time; } else if (c->publish_time > 0 && !c->availability_start_time) { - num = pls->first_seq_no + (((c->publish_time - c->availability_start_time) - c->suggested_presentation_delay) * pls->fragment_timescale) / pls->fragment_duration; + if (c->min_buffer_time) { + num = pls->first_seq_no + (((c->publish_time + pls->fragment_duration) - c->suggested_presentation_delay) * pls->fragment_timescale) / pls->fragment_duration - c->min_buffer_time; + } else { + num = pls->first_seq_no + (((c->publish_time - c->time_shift_buffer_depth + pls->fragment_duration) - c->suggested_presentation_delay) * pls->fragment_timescale) / pls->fragment_duration; + } } else { num = pls->first_seq_no + (((get_current_time_in_sec() - c->availability_start_time) - c->suggested_presentation_delay) * pls->fragment_timescale) / pls->fragment_duration; } @@ -1325,6 +1364,7 @@ static int64_t calc_min_seg_no(AVFormatContext *s, struct representation *pls) int64_t num = 0; if (c->is_live && pls->fragment_duration) { + av_log(s, AV_LOG_TRACE, "in live mode\n"); num = pls->first_seq_no + (((get_current_time_in_sec() - c->availability_start_time) - c->time_shift_buffer_depth) * pls->fragment_timescale) / pls->fragment_duration; } else { num = pls->first_seq_no; @@ -1342,7 +1382,12 @@ static int64_t calc_max_seg_no(struct representation *pls, DASHContext *c) int i = 0; num = pls->first_seq_no + pls->n_timelines - 1; for (i = 0; i < pls->n_timelines; i++) { - num += pls->timelines[i]->repeat; + if (pls->timelines[i]->repeat == -1) { + int length_of_each_segment = pls->timelines[i]->duration / pls->fragment_timescale; + num = c->period_duration / length_of_each_segment; + } else { + num += pls->timelines[i]->repeat; + } } } else if (c->is_live && pls->fragment_duration) { num = pls->first_seq_no + (((get_current_time_in_sec() - c->availability_start_time)) * pls->fragment_timescale) / pls->fragment_duration; @@ -1545,14 +1590,8 @@ static struct fragment *get_current_fragment(struct representation *pls) return seg; } -enum ReadFromURLMode { - READ_NORMAL, - READ_COMPLETE, -}; - static int read_from_url(struct representation *pls, struct fragment *seg, - uint8_t *buf, int buf_size, - enum ReadFromURLMode mode) + uint8_t *buf, int buf_size) { int ret; @@ -1560,14 +1599,7 @@ static int read_from_url(struct representation *pls, struct fragment *seg, if (seg->size >= 0) buf_size = FFMIN(buf_size, pls->cur_seg_size - pls->cur_seg_offset); - if (mode == READ_COMPLETE) { - ret = avio_read(pls->input, buf, buf_size); - if (ret < buf_size) { - av_log(pls->parent, AV_LOG_WARNING, "Could not read complete fragment.\n"); - } - } else { - ret = avio_read(pls->input, buf, buf_size); - } + ret = avio_read(pls->input, buf, buf_size); if (ret > 0) pls->cur_seg_offset += ret; @@ -1584,7 +1616,7 @@ static int open_input(DASHContext *c, struct representation *pls, struct fragmen if (!url) { goto cleanup; } - set_httpheader_options(c, &opts); + if (seg->size >= 0) { /* try to restrict the HTTP request to the part we want * (if this is in fact a HTTP request) */ @@ -1643,7 +1675,7 @@ static int update_init_section(struct representation *pls) av_fast_malloc(&pls->init_sec_buf, &pls->init_sec_buf_size, sec_size); ret = read_from_url(pls, pls->init_section, pls->init_sec_buf, - pls->init_sec_buf_size, READ_COMPLETE); + pls->init_sec_buf_size); ff_format_io_close(pls->parent, &pls->input); if (ret < 0) @@ -1714,7 +1746,7 @@ restart: ret = AVERROR_EOF; goto end; } - ret = read_from_url(v, v->cur_seg, buf, buf_size, READ_NORMAL); + ret = read_from_url(v, v->cur_seg, buf, buf_size); if (ret > 0) goto end; @@ -1731,7 +1763,7 @@ end: static int save_avio_options(AVFormatContext *s) { DASHContext *c = s->priv_data; - const char *opts[] = { "headers", "user_agent", "user_agent", "cookies", NULL }, **opt = opts; + const char *opts[] = { "headers", "user_agent", "cookies", NULL }, **opt = opts; uint8_t *buf = NULL; int ret = 0; @@ -1784,6 +1816,12 @@ static int reopen_demux_for_component(AVFormatContext *s, struct representation if (pls->ctx) { close_demux_for_component(pls); } + + if (ff_check_interrupt(&s->interrupt_callback)) { + ret = AVERROR_EXIT; + goto fail; + } + if (!(pls->ctx = avformat_alloc_context())) { ret = AVERROR(ENOMEM); goto fail; @@ -1899,7 +1937,6 @@ static int is_common_init_section_exist(struct representation **pls, int n_pls) static void copy_init_section(struct representation *rep_dest, struct representation *rep_src) { - *rep_dest->init_section = *rep_src->init_section; rep_dest->init_sec_buf = av_mallocz(rep_src->init_sec_buf_size); memcpy(rep_dest->init_sec_buf, rep_src->init_sec_buf, rep_src->init_sec_data_len); rep_dest->init_sec_buf_size = rep_src->init_sec_buf_size; @@ -1910,24 +1947,19 @@ static void copy_init_section(struct representation *rep_dest, struct representa static int dash_read_header(AVFormatContext *s) { - void *u = (s->flags & AVFMT_FLAG_CUSTOM_IO) ? NULL : s->pb; DASHContext *c = s->priv_data; int ret = 0; int stream_index = 0; int i; c->interrupt_callback = &s->interrupt_callback; - // if the URL context is good, read important options we must broker later - if (u) { - update_options(&c->user_agent, "user_agent", u); - update_options(&c->cookies, "cookies", u); - update_options(&c->headers, "headers", u); - } - if ((ret = parse_manifest(s, s->url, s->pb)) < 0) + if ((ret = save_avio_options(s)) < 0) goto fail; - if ((ret = save_avio_options(s)) < 0) + av_dict_set(&c->avio_opts, "seekable", "0", 0); + + if ((ret = parse_manifest(s, s->url, s->pb)) < 0) goto fail; /* If this isn't a live stream, fill the total duration of the @@ -1936,7 +1968,8 @@ static int dash_read_header(AVFormatContext *s) s->duration = (int64_t) c->media_presentation_duration * AV_TIME_BASE; } - c->is_init_section_common_video = is_common_init_section_exist(c->videos, c->n_videos); + if(c->n_videos) + c->is_init_section_common_video = is_common_init_section_exist(c->videos, c->n_videos); /* Open the demuxer for video and audio components if available */ for (i = 0; i < c->n_videos; i++) { @@ -1952,7 +1985,8 @@ static int dash_read_header(AVFormatContext *s) ++stream_index; } - c->is_init_section_common_audio = is_common_init_section_exist(c->audios, c->n_audios); + if(c->n_audios) + c->is_init_section_common_audio = is_common_init_section_exist(c->audios, c->n_audios); for (i = 0; i < c->n_audios; i++) { struct representation *cur_audio = c->audios[i]; @@ -2091,8 +2125,6 @@ static int dash_close(AVFormatContext *s) free_audio_list(c); free_video_list(c); - av_freep(&c->cookies); - av_freep(&c->user_agent); av_dict_free(&c->avio_opts); av_freep(&c->base_url); return 0; diff --git a/chromium/third_party/ffmpeg/libavformat/dashenc.c b/chromium/third_party/ffmpeg/libavformat/dashenc.c index a9b8b1d4f60..b0bb35426bb 100644 --- a/chromium/third_party/ffmpeg/libavformat/dashenc.c +++ b/chromium/third_party/ffmpeg/libavformat/dashenc.c @@ -211,7 +211,7 @@ static void set_vp9_codec_str(AVFormatContext *s, AVCodecParameters *par, VPCC vpcc; int ret = ff_isom_get_vpcc_features(s, par, frame_rate, &vpcc); if (ret == 0) { - av_strlcatf(str, size, "vp09.%02x.%02x.%02x", + av_strlcatf(str, size, "vp09.%02d.%02d.%02d", vpcc.profile, vpcc.level, vpcc.bitdepth); } else { // Default to just vp9 in case of error while finding out profile or level @@ -611,7 +611,7 @@ static int write_adaptation_set(AVFormatContext *s, AVIOContext *out, int as_ind if (os->bit_rate > 0) snprintf(bandwidth_str, sizeof(bandwidth_str), " bandwidth=\"%d\"", - os->bit_rate + os->muxer_overhead); + os->bit_rate); if (as->media_type == AVMEDIA_TYPE_VIDEO) { AVStream *st = s->streams[i]; @@ -864,11 +864,12 @@ static int write_manifest(AVFormatContext *s, int final) if (c->hls_playlist && !c->master_playlist_created) { char filename_hls[1024]; const char *audio_group = "A1"; + char audio_codec_str[128] = "\0"; int is_default = 1; int max_audio_bitrate = 0; if (*c->dirname) - snprintf(filename_hls, sizeof(filename_hls), "%s/master.m3u8", c->dirname); + snprintf(filename_hls, sizeof(filename_hls), "%smaster.m3u8", c->dirname); else snprintf(filename_hls, sizeof(filename_hls), "master.m3u8"); @@ -895,21 +896,31 @@ static int write_manifest(AVFormatContext *s, int final) playlist_file, i, is_default); max_audio_bitrate = FFMAX(st->codecpar->bit_rate + os->muxer_overhead, max_audio_bitrate); + if (!av_strnstr(audio_codec_str, os->codec_str, sizeof(audio_codec_str))) { + if (strlen(audio_codec_str)) + av_strlcat(audio_codec_str, ",", sizeof(audio_codec_str)); + av_strlcat(audio_codec_str, os->codec_str, sizeof(audio_codec_str)); + } is_default = 0; } for (i = 0; i < s->nb_streams; i++) { char playlist_file[64]; + char codec_str[128]; AVStream *st = s->streams[i]; OutputStream *os = &c->streams[i]; char *agroup = NULL; int stream_bitrate = st->codecpar->bit_rate + os->muxer_overhead; + av_strlcpy(codec_str, os->codec_str, sizeof(codec_str)); if ((st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) && max_audio_bitrate) { agroup = (char *)audio_group; stream_bitrate += max_audio_bitrate; + av_strlcat(codec_str, ",", sizeof(codec_str)); + av_strlcat(codec_str, audio_codec_str, sizeof(codec_str)); } get_hls_playlist_name(playlist_file, sizeof(playlist_file), NULL, i); - ff_hls_write_stream_info(st, out, stream_bitrate, playlist_file, agroup, NULL, NULL); + ff_hls_write_stream_info(st, out, stream_bitrate, playlist_file, agroup, + codec_str, NULL); } avio_close(out); if (use_rename) @@ -1054,7 +1065,7 @@ static int dash_init(AVFormatContext *s) if (c->segment_type == SEGMENT_TYPE_MP4) { if (c->streaming) - av_dict_set(&opts, "movflags", "frag_every_frame+dash+delay_moov", 0); + av_dict_set(&opts, "movflags", "frag_every_frame+dash+delay_moov+global_sidx", 0); else av_dict_set(&opts, "movflags", "frag_custom+dash+delay_moov", 0); } else { diff --git a/chromium/third_party/ffmpeg/libavformat/davs2.c b/chromium/third_party/ffmpeg/libavformat/davs2.c new file mode 100644 index 00000000000..df2667fec7c --- /dev/null +++ b/chromium/third_party/ffmpeg/libavformat/davs2.c @@ -0,0 +1,71 @@ +/* + * AVS2 video stream probe. + * + * Copyright (C) 2018 Huiwen Ren, <hwrenx@126.com> + * + * This file is part of FFmpeg. + * + * FFmpeg 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. + * + * FFmpeg 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 FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "avformat.h" +#include "rawdec.h" +#include "libavcodec/internal.h" +#include "libavutil/intreadwrite.h" + +#define ISSQH(x) ((x) == 0xB0 ) +#define ISEND(x) ((x) == 0xB1 ) +#define ISPIC(x) ((x) == 0xB3 || (x) == 0xB6) +#define ISUNIT(x) ( ISSQH(x) || ISEND(x) || (x) == 0xB2 || ISPIC(x) || (x) == 0xB5 || (x) == 0xB7 ) +#define ISAVS2(x) ((x) == 0x20 || (x) == 0x22 || (x) == 0x30 || (x) == 0x32 ) + +static int avs2_probe(AVProbeData *p) +{ + uint32_t code= -1, hds=0, pic=0, seq=0; + uint8_t state=0; + const uint8_t *ptr = p->buf, *end = p->buf + p->buf_size, *sqb=0; + if (AV_RB32(p->buf) != 0x1B0){ + return 0; + } + + while (ptr < end) { + ptr = avpriv_find_start_code(ptr, end, &code); + state = code & 0xFF; + if ((code & 0xffffff00) == 0x100) { + if (ISUNIT(state)) { + if (sqb && !hds) { + hds = ptr - sqb; + } + if (ISSQH(state)) { + if (!ISAVS2(*ptr)) + return 0; + sqb = ptr; + seq++; + } else if (ISPIC(state)) { + pic++; + } else if (ISEND(state)) { + break; + } + } + } + } + if (seq && hds >= 21 && pic){ + return AVPROBE_SCORE_EXTENSION + 2; // more than cavs + } + + return 0; +} + +FF_DEF_RAWVIDEO_DEMUXER(avs2, "raw AVS2-P2/IEEE1857.4", avs2_probe, "avs,avs2", AV_CODEC_ID_AVS2) diff --git a/chromium/third_party/ffmpeg/libavformat/flvdec.c b/chromium/third_party/ffmpeg/libavformat/flvdec.c index 34c3e08bad2..a2dea464e36 100644 --- a/chromium/third_party/ffmpeg/libavformat/flvdec.c +++ b/chromium/third_party/ffmpeg/libavformat/flvdec.c @@ -44,6 +44,8 @@ typedef struct FLVContext { const AVClass *class; ///< Class for private options. int trust_metadata; ///< configure streams according onMetaData + int trust_datasize; ///< trust data size of FLVTag + int dump_full_metadata; ///< Dump full metadata of the onMetadata int wrong_dts; ///< wrong dts due to negative cts uint8_t *new_extradata[FLV_STREAM_TYPE_NB]; int new_extradata_size[FLV_STREAM_TYPE_NB]; @@ -611,7 +613,7 @@ static int amf_parse_object(AVFormatContext *s, AVStream *astream, (!vpar && !strcmp(key, "videocodecid")))) s->ctx_flags &= ~AVFMTCTX_NOHEADER; //If there is either audio/video missing, codecid will be an empty object - if (!strcmp(key, "duration") || + if ((!strcmp(key, "duration") || !strcmp(key, "filesize") || !strcmp(key, "width") || !strcmp(key, "height") || @@ -623,7 +625,7 @@ static int amf_parse_object(AVFormatContext *s, AVStream *astream, !strcmp(key, "audiosamplesize") || !strcmp(key, "stereo") || !strcmp(key, "audiocodecid") || - !strcmp(key, "datastream")) + !strcmp(key, "datastream")) && !flv->dump_full_metadata) return 0; s->event_flags |= AVFMT_EVENT_FLAG_METADATA_UPDATED; @@ -654,8 +656,6 @@ static int flv_read_metabody(AVFormatContext *s, int64_t next_pos) AVStream av_unused *dstream; AVIOContext *ioc; int i; - // only needs to hold the string "onMetaData". - // Anything longer is something we don't want. char buffer[32]; astream = NULL; @@ -753,6 +753,9 @@ static int flv_read_close(AVFormatContext *s) static int flv_get_extradata(AVFormatContext *s, AVStream *st, int size) { + if (!size) + return 0; + av_freep(&st->codecpar->extradata); if (ff_get_extradata(s, st->codecpar, s->pb, size) < 0) return AVERROR(ENOMEM); @@ -763,6 +766,9 @@ static int flv_get_extradata(AVFormatContext *s, AVStream *st, int size) static int flv_queue_extradata(FLVContext *flv, AVIOContext *pb, int stream, int size) { + if (!size) + return 0; + av_free(flv->new_extradata[stream]); flv->new_extradata[stream] = av_mallocz(size + AV_INPUT_BUFFER_PADDING_SIZE); @@ -1252,16 +1258,18 @@ retry_duration: leave: last = avio_rb32(s->pb); - if (last != orig_size + 11 && last != orig_size + 10 && - !avio_feof(s->pb) && - (last != orig_size || !last) && last != flv->sum_flv_tag_size && - !flv->broken_sizes) { - av_log(s, AV_LOG_ERROR, "Packet mismatch %d %d %d\n", last, orig_size + 11, flv->sum_flv_tag_size); - avio_seek(s->pb, pos + 1, SEEK_SET); - ret = resync(s); - av_packet_unref(pkt); - if (ret >= 0) { - goto retry; + if (!flv->trust_datasize) { + if (last != orig_size + 11 && last != orig_size + 10 && + !avio_feof(s->pb) && + (last != orig_size || !last) && last != flv->sum_flv_tag_size && + !flv->broken_sizes) { + av_log(s, AV_LOG_ERROR, "Packet mismatch %d %d %d\n", last, orig_size + 11, flv->sum_flv_tag_size); + avio_seek(s->pb, pos + 1, SEEK_SET); + ret = resync(s); + av_packet_unref(pkt); + if (ret >= 0) { + goto retry; + } } } return ret; @@ -1279,6 +1287,8 @@ static int flv_read_seek(AVFormatContext *s, int stream_index, #define VD AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_DECODING_PARAM static const AVOption options[] = { { "flv_metadata", "Allocate streams according to the onMetaData array", OFFSET(trust_metadata), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, VD }, + { "flv_full_metadata", "Dump full metadata of the onMetadata", OFFSET(dump_full_metadata), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, VD }, + { "flv_ignore_prevtag", "Ignore the Size of previous tag", OFFSET(trust_datasize), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, VD }, { "missing_streams", "", OFFSET(missing_streams), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 0xFF, VD | AV_OPT_FLAG_EXPORT | AV_OPT_FLAG_READONLY }, { NULL } }; diff --git a/chromium/third_party/ffmpeg/libavformat/flvenc.c b/chromium/third_party/ffmpeg/libavformat/flvenc.c index 1c552a3e6b9..e4863f1fc73 100644 --- a/chromium/third_party/ffmpeg/libavformat/flvenc.c +++ b/chromium/third_party/ffmpeg/libavformat/flvenc.c @@ -883,6 +883,11 @@ static int flv_write_packet(AVFormatContext *s, AVPacket *pkt) int flags = -1, flags_size, ret; int64_t cur_offset = avio_tell(pb); + if (par->codec_type == AVMEDIA_TYPE_AUDIO && !pkt->size) { + av_log(s, AV_LOG_WARNING, "Empty audio Packet\n"); + return AVERROR(EINVAL); + } + if (par->codec_id == AV_CODEC_ID_VP6F || par->codec_id == AV_CODEC_ID_VP6A || par->codec_id == AV_CODEC_ID_VP6 || par->codec_id == AV_CODEC_ID_AAC) flags_size = 2; diff --git a/chromium/third_party/ffmpeg/libavformat/hls.c b/chromium/third_party/ffmpeg/libavformat/hls.c index 3d4f7f2647f..8ad08baaed4 100644 --- a/chromium/third_party/ffmpeg/libavformat/hls.c +++ b/chromium/third_party/ffmpeg/libavformat/hls.c @@ -811,6 +811,27 @@ static int parse_playlist(HLSContext *c, const char *url, ff_parse_key_value(ptr, (ff_parse_key_val_cb) handle_init_section_args, &info); cur_init_section = new_init_section(pls, &info, url); + cur_init_section->key_type = key_type; + if (has_iv) { + memcpy(cur_init_section->iv, iv, sizeof(iv)); + } else { + int seq = pls->start_seq_no + pls->n_segments; + memset(cur_init_section->iv, 0, sizeof(cur_init_section->iv)); + AV_WB32(cur_init_section->iv + 12, seq); + } + + if (key_type != KEY_NONE) { + ff_make_absolute_url(tmp_str, sizeof(tmp_str), url, key); + cur_init_section->key = av_strdup(tmp_str); + if (!cur_init_section->key) { + av_free(cur_init_section); + ret = AVERROR(ENOMEM); + goto fail; + } + } else { + cur_init_section->key = NULL; + } + } else if (av_strstart(line, "#EXT-X-ENDLIST", &ptr)) { if (pls) pls->finished = 1; diff --git a/chromium/third_party/ffmpeg/libavformat/hlsenc.c b/chromium/third_party/ffmpeg/libavformat/hlsenc.c index b5644f05c44..28c2dd62fca 100644 --- a/chromium/third_party/ffmpeg/libavformat/hlsenc.c +++ b/chromium/third_party/ffmpeg/libavformat/hlsenc.c @@ -230,39 +230,6 @@ typedef struct HLSContext { int64_t timeout; } HLSContext; -static int mkdir_p(const char *path) { - int ret = 0; - char *temp = av_strdup(path); - char *pos = temp; - char tmp_ch = '\0'; - - if (!path || !temp) { - return -1; - } - - if (!strncmp(temp, "/", 1) || !strncmp(temp, "\\", 1)) { - pos++; - } else if (!strncmp(temp, "./", 2) || !strncmp(temp, ".\\", 2)) { - pos += 2; - } - - for ( ; *pos != '\0'; ++pos) { - if (*pos == '/' || *pos == '\\') { - tmp_ch = *pos; - *pos = '\0'; - ret = mkdir(temp, 0755); - *pos = tmp_ch; - } - } - - if ((*(pos - 1) != '/') || (*(pos - 1) != '\\')) { - ret = mkdir(temp, 0755); - } - - av_free(temp); - return ret; -} - static int hlsenc_io_open(AVFormatContext *s, AVIOContext **pb, char *filename, AVDictionary **options) { HLSContext *hls = s->priv_data; @@ -877,17 +844,17 @@ static int sls_flag_check_duration_size_index(HLSContext *hls) if (hls->flags & HLS_SECOND_LEVEL_SEGMENT_DURATION) { av_log(hls, AV_LOG_ERROR, - "second_level_segment_duration hls_flag requires use_localtime to be true\n"); + "second_level_segment_duration hls_flag requires strftime to be true\n"); ret = AVERROR(EINVAL); } if (hls->flags & HLS_SECOND_LEVEL_SEGMENT_SIZE) { av_log(hls, AV_LOG_ERROR, - "second_level_segment_size hls_flag requires use_localtime to be true\n"); + "second_level_segment_size hls_flag requires strfime to be true\n"); ret = AVERROR(EINVAL); } if (hls->flags & HLS_SECOND_LEVEL_SEGMENT_INDEX) { av_log(hls, AV_LOG_ERROR, - "second_level_segment_index hls_flag requires use_localtime to be true\n"); + "second_level_segment_index hls_flag requires strftime to be true\n"); ret = AVERROR(EINVAL); } @@ -1374,7 +1341,7 @@ static int hls_window(AVFormatContext *s, int last, VariantStream *vs) char temp_filename[1024]; int64_t sequence = FFMAX(hls->start_sequence, vs->sequence - vs->nb_entries); const char *proto = avio_find_protocol_name(s->url); - int use_rename = proto && !strcmp(proto, "file"); + int use_temp_file = proto && !strcmp(proto, "file") && (s->flags & HLS_TEMP_FILE); static unsigned warned_non_file; char *key_uri = NULL; char *iv_string = NULL; @@ -1397,11 +1364,11 @@ static int hls_window(AVFormatContext *s, int last, VariantStream *vs) hls->version = 7; } - if (!use_rename && !warned_non_file++) + if (!use_temp_file && !warned_non_file++) av_log(s, AV_LOG_ERROR, "Cannot use rename on non file protocol, this may lead to races and temporary partial files\n"); set_http_options(s, &options, hls); - snprintf(temp_filename, sizeof(temp_filename), use_rename ? "%s.tmp" : "%s", vs->m3u8_name); + snprintf(temp_filename, sizeof(temp_filename), use_temp_file ? "%s.tmp" : "%s", vs->m3u8_name); if ((ret = hlsenc_io_open(s, &hls->m3u8_out, temp_filename, &options)) < 0) goto fail; @@ -1472,7 +1439,7 @@ fail: av_dict_free(&options); hlsenc_io_close(s, &hls->m3u8_out, temp_filename); hlsenc_io_close(s, &hls->sub_m3u8_out, vs->vtt_m3u8_name); - if (ret >= 0 && use_rename) + if (use_temp_file) ff_rename(temp_filename, vs->m3u8_name, s); if (ret >= 0 && hls->master_pl_name) @@ -1488,6 +1455,8 @@ static int hls_start(AVFormatContext *s, VariantStream *vs) AVFormatContext *oc = vs->avf; AVFormatContext *vtt_oc = vs->vtt_avf; AVDictionary *options = NULL; + const char *proto = avio_find_protocol_name(s->url); + int use_temp_file = proto && !strcmp(proto, "file") && (s->flags & HLS_TEMP_FILE); char *filename, iv_string[KEYSIZE*2 + 1]; int err = 0; @@ -1511,7 +1480,7 @@ static int hls_start(AVFormatContext *s, VariantStream *vs) vs->basename, 'd', vs->sequence) < 1) { #endif av_free(filename); - av_log(oc, AV_LOG_ERROR, "Invalid segment filename template '%s', you can try to use -use_localtime 1 with it\n", vs->basename); + av_log(oc, AV_LOG_ERROR, "Invalid segment filename template '%s', you can try to use -strftime 1 with it\n", vs->basename); return AVERROR(EINVAL); } ff_format_set_url(oc, filename); @@ -1527,7 +1496,7 @@ static int hls_start(AVFormatContext *s, VariantStream *vs) tm = localtime_r(&now0, &tmpbuf); ff_format_set_url(oc, buf); if (!strftime(oc->url, bufsize, vs->basename, tm)) { - av_log(oc, AV_LOG_ERROR, "Could not get segment filename with use_localtime\n"); + av_log(oc, AV_LOG_ERROR, "Could not get segment filename with strftime\n"); return AVERROR(EINVAL); } @@ -1543,7 +1512,7 @@ static int hls_start(AVFormatContext *s, VariantStream *vs) return AVERROR(ENOMEM); } dir = av_dirname(fn_copy); - if (mkdir_p(dir) == -1 && errno != EEXIST) { + if (ff_mkdir_p(dir) == -1 && errno != EEXIST) { av_log(oc, AV_LOG_ERROR, "Could not create directory %s with use_localtime_mkdir\n", dir); av_free(fn_copy); return AVERROR(errno); @@ -1559,7 +1528,7 @@ static int hls_start(AVFormatContext *s, VariantStream *vs) vs->basename, 'd', vs->sequence) < 1) { #endif av_free(filename); - av_log(oc, AV_LOG_ERROR, "Invalid segment filename template '%s' you can try to use -use_localtime 1 with it\n", vs->basename); + av_log(oc, AV_LOG_ERROR, "Invalid segment filename template '%s' you can try to use -strftime 1 with it\n", vs->basename); return AVERROR(EINVAL); } ff_format_set_url(oc, filename); @@ -1583,7 +1552,7 @@ static int hls_start(AVFormatContext *s, VariantStream *vs) set_http_options(s, &options, c); - if (c->flags & HLS_TEMP_FILE) { + if (use_temp_file) { char *new_name = av_asprintf("%s.tmp", oc->url); if (!new_name) return AVERROR(ENOMEM); @@ -1774,7 +1743,7 @@ static int format_name(char *buf, int buf_len, int index) } dir = av_dirname(mod_buf_dup); - if (mkdir_p(dir) == -1 && errno != EEXIST) { + if (ff_mkdir_p(dir) == -1 && errno != EEXIST) { ret = AVERROR(errno); goto fail; } @@ -2145,9 +2114,12 @@ static int hls_write_packet(AVFormatContext *s, AVPacket *pkt) int ret = 0, can_split = 1, i, j; int stream_index = 0; int range_length = 0; + const char *proto = avio_find_protocol_name(s->url); + int use_temp_file = proto && !strcmp(proto, "file") && (s->flags & HLS_TEMP_FILE); uint8_t *buffer = NULL; VariantStream *vs = NULL; AVDictionary *options = NULL; + char *old_filename = NULL; for (i = 0; i < hls->nb_varstreams; i++) { vs = &hls->var_streams[i]; @@ -2217,7 +2189,6 @@ static int hls_write_packet(AVFormatContext *s, AVPacket *pkt) if (vs->packets_written && can_split && av_compare_ts(pkt->pts - vs->start_pts, st->time_base, end_pts, AV_TIME_BASE_Q) >= 0) { int64_t new_start_pos; - char *old_filename = NULL; int byterange_mode = (hls->flags & HLS_SINGLE_FILE) || (hls->max_seg_size > 0); av_write_frame(vs->avf, NULL); /* Flush any buffered data */ @@ -2253,11 +2224,13 @@ static int hls_write_packet(AVFormatContext *s, AVPacket *pkt) hlsenc_io_close(s, &vs->vtt_avf->pb, vs->vtt_avf->url); } } - if ((hls->flags & HLS_TEMP_FILE) && oc->url[0]) { + + // look to rename the asset name + if (use_temp_file && oc->url[0]) { if (!(hls->flags & HLS_SINGLE_FILE) || (hls->max_seg_size <= 0)) - if ((vs->avf->oformat->priv_class && vs->avf->priv_data) && hls->segment_type != SEGMENT_TYPE_FMP4) + if ((vs->avf->oformat->priv_class && vs->avf->priv_data) && hls->segment_type != SEGMENT_TYPE_FMP4) { av_opt_set(vs->avf->priv_data, "mpegts_flags", "resend_headers", 0); - hls_rename_temp_file(s, oc); + } } if (vs->fmp4_init_mode) { @@ -2286,6 +2259,17 @@ static int hls_write_packet(AVFormatContext *s, AVPacket *pkt) return ret; } ff_format_io_close(s, &vs->out); + + // rename that segment from .tmp to the real one + if (use_temp_file && oc->url[0]) { + hls_rename_temp_file(s, oc); + av_free(old_filename); + old_filename = av_strdup(vs->avf->url); + + if (!old_filename) { + return AVERROR(ENOMEM); + } + } } } @@ -2334,10 +2318,12 @@ static int hls_write_packet(AVFormatContext *s, AVPacket *pkt) return ret; } - if (!vs->fmp4_init_mode || byterange_mode) + // if we're building a VOD playlist, skip writing the manifest multiple times, and just wait until the end + if (hls->pl_type != PLAYLIST_TYPE_VOD) { if ((ret = hls_window(s, 0, vs)) < 0) { return ret; } + } } vs->packets_written++; @@ -2352,6 +2338,8 @@ static int hls_write_trailer(struct AVFormatContext *s) AVFormatContext *oc = NULL; AVFormatContext *vtt_oc = NULL; char *old_filename = NULL; + const char *proto = avio_find_protocol_name(s->url); + int use_temp_file = proto && !strcmp(proto, "file") && (s->flags & HLS_TEMP_FILE); int i; int ret = 0; VariantStream *vs = NULL; @@ -2394,7 +2382,8 @@ failed: if (hls->segment_type != SEGMENT_TYPE_FMP4) ff_format_io_close(s, &oc->pb); - if ((hls->flags & HLS_TEMP_FILE) && oc->url[0]) { + // rename that segment from .tmp to the real one + if (use_temp_file && oc->url[0] && !(hls->flags & HLS_SINGLE_FILE)) { hls_rename_temp_file(s, oc); av_free(old_filename); old_filename = av_strdup(vs->avf->url); @@ -2841,8 +2830,14 @@ static const AVOption options[] = { {"second_level_segment_size", "include segment size in segment filenames when use_localtime", 0, AV_OPT_TYPE_CONST, {.i64 = HLS_SECOND_LEVEL_SEGMENT_SIZE }, 0, UINT_MAX, E, "flags"}, {"periodic_rekey", "reload keyinfo file periodically for re-keying", 0, AV_OPT_TYPE_CONST, {.i64 = HLS_PERIODIC_REKEY }, 0, UINT_MAX, E, "flags"}, {"independent_segments", "add EXT-X-INDEPENDENT-SEGMENTS, whenever applicable", 0, AV_OPT_TYPE_CONST, { .i64 = HLS_INDEPENDENT_SEGMENTS }, 0, UINT_MAX, E, "flags"}, - {"use_localtime", "set filename expansion with strftime at segment creation", OFFSET(use_localtime), AV_OPT_TYPE_BOOL, {.i64 = 0 }, 0, 1, E }, - {"use_localtime_mkdir", "create last directory component in strftime-generated filename", OFFSET(use_localtime_mkdir), AV_OPT_TYPE_BOOL, {.i64 = 0 }, 0, 1, E }, +#if FF_API_HLS_USE_LOCALTIME + {"use_localtime", "set filename expansion with strftime at segment creation(will be deprecated )", OFFSET(use_localtime), AV_OPT_TYPE_BOOL, {.i64 = 0 }, 0, 1, E }, +#endif + {"strftime", "set filename expansion with strftime at segment creation", OFFSET(use_localtime), AV_OPT_TYPE_BOOL, {.i64 = 0 }, 0, 1, E }, +#if FF_API_HLS_USE_LOCALTIME + {"use_localtime_mkdir", "create last directory component in strftime-generated filename(will be deprecated)", OFFSET(use_localtime_mkdir), AV_OPT_TYPE_BOOL, {.i64 = 0 }, 0, 1, E }, +#endif + {"strftime_mkdir", "create last directory component in strftime-generated filename", OFFSET(use_localtime_mkdir), AV_OPT_TYPE_BOOL, {.i64 = 0 }, 0, 1, E }, {"hls_playlist_type", "set the HLS playlist type", OFFSET(pl_type), AV_OPT_TYPE_INT, {.i64 = PLAYLIST_TYPE_NONE }, 0, PLAYLIST_TYPE_NB-1, E, "pl_type" }, {"event", "EVENT playlist", 0, AV_OPT_TYPE_CONST, {.i64 = PLAYLIST_TYPE_EVENT }, INT_MIN, INT_MAX, E, "pl_type" }, {"vod", "VOD playlist", 0, AV_OPT_TYPE_CONST, {.i64 = PLAYLIST_TYPE_VOD }, INT_MIN, INT_MAX, E, "pl_type" }, diff --git a/chromium/third_party/ffmpeg/libavformat/internal.h b/chromium/third_party/ffmpeg/libavformat/internal.h index 0b8120b8424..399d0a68beb 100644 --- a/chromium/third_party/ffmpeg/libavformat/internal.h +++ b/chromium/third_party/ffmpeg/libavformat/internal.h @@ -211,6 +211,14 @@ do {\ struct tm *ff_brktimegm(time_t secs, struct tm *tm); +/** + * Automatically create sub-directories + * + * @param path will create sub-directories by path + * @return 0, or < 0 on error + */ +int ff_mkdir_p(const char *path); + char *ff_data_to_hex(char *buf, const uint8_t *src, int size, int lowercase); /** diff --git a/chromium/third_party/ffmpeg/libavformat/isom.c b/chromium/third_party/ffmpeg/libavformat/isom.c index ce66d1bcd41..ca9d22e4f74 100644 --- a/chromium/third_party/ffmpeg/libavformat/isom.c +++ b/chromium/third_party/ffmpeg/libavformat/isom.c @@ -374,6 +374,11 @@ const AVCodecTag ff_codec_movsubtitle_tags[] = { { AV_CODEC_ID_NONE, 0 }, }; +const AVCodecTag ff_codec_movdata_tags[] = { + { AV_CODEC_ID_BIN_DATA, MKTAG('g', 'p', 'm', 'd') }, + { AV_CODEC_ID_NONE, 0 }, +}; + /* map numeric codes from mdhd atom to ISO 639 */ /* cf. QTFileFormat.pdf p253, qtff.pdf p205 */ /* http://developer.apple.com/documentation/mac/Text/Text-368.html */ diff --git a/chromium/third_party/ffmpeg/libavformat/isom.h b/chromium/third_party/ffmpeg/libavformat/isom.h index fb361125c96..e6296639496 100644 --- a/chromium/third_party/ffmpeg/libavformat/isom.h +++ b/chromium/third_party/ffmpeg/libavformat/isom.h @@ -41,6 +41,7 @@ extern const AVCodecTag ff_mp4_obj_type[]; extern const AVCodecTag ff_codec_movvideo_tags[]; extern const AVCodecTag ff_codec_movaudio_tags[]; extern const AVCodecTag ff_codec_movsubtitle_tags[]; +extern const AVCodecTag ff_codec_movdata_tags[]; int ff_mov_iso639_to_lang(const char lang[4], int mp4); int ff_mov_lang_to_iso639(unsigned code, char to[4]); @@ -118,7 +119,7 @@ typedef struct MOVEncryptionIndex { uint8_t* auxiliary_info_sizes; size_t auxiliary_info_sample_count; uint8_t auxiliary_info_default_size; - size_t* auxiliary_offsets; ///< Absolute seek position + uint64_t* auxiliary_offsets; ///< Absolute seek position size_t auxiliary_offsets_count; } MOVEncryptionIndex; @@ -217,6 +218,7 @@ typedef struct MOVStreamContext { int *extradata_size; int last_stsd_index; int stsd_count; + int stsd_version; int32_t *display_matrix; AVStereo3D *stereo3d; diff --git a/chromium/third_party/ffmpeg/libavformat/ivfenc.c b/chromium/third_party/ffmpeg/libavformat/ivfenc.c index af803d59ee8..66441a2a433 100644 --- a/chromium/third_party/ffmpeg/libavformat/ivfenc.c +++ b/chromium/third_party/ffmpeg/libavformat/ivfenc.c @@ -46,7 +46,7 @@ static int ivf_write_header(AVFormatContext *s) avio_write(pb, "DKIF", 4); avio_wl16(pb, 0); // version avio_wl16(pb, 32); // header length - avio_wl32(pb, par->codec_tag ? par->codec_tag : + avio_wl32(pb, par->codec_id == AV_CODEC_ID_VP9 ? AV_RL32("VP90") : par->codec_id == AV_CODEC_ID_VP8 ? AV_RL32("VP80") : AV_RL32("AV01")); avio_wl16(pb, par->width); diff --git a/chromium/third_party/ffmpeg/libavformat/librtmp.c b/chromium/third_party/ffmpeg/libavformat/librtmp.c index f3cfa9a8e25..43013e46e0a 100644 --- a/chromium/third_party/ffmpeg/libavformat/librtmp.c +++ b/chromium/third_party/ffmpeg/libavformat/librtmp.c @@ -261,7 +261,10 @@ static int rtmp_write(URLContext *s, const uint8_t *buf, int size) LibRTMPContext *ctx = s->priv_data; RTMP *r = &ctx->rtmp; - return RTMP_Write(r, buf, size); + int ret = RTMP_Write(r, buf, size); + if (!ret) + return AVERROR_EOF; + return ret; } static int rtmp_read(URLContext *s, uint8_t *buf, int size) @@ -269,7 +272,10 @@ static int rtmp_read(URLContext *s, uint8_t *buf, int size) LibRTMPContext *ctx = s->priv_data; RTMP *r = &ctx->rtmp; - return RTMP_Read(r, buf, size); + int ret = RTMP_Read(r, buf, size); + if (!ret) + return AVERROR_EOF; + return ret; } static int rtmp_read_pause(URLContext *s, int pause) diff --git a/chromium/third_party/ffmpeg/libavformat/libsmbclient.c b/chromium/third_party/ffmpeg/libavformat/libsmbclient.c index b68cd8bd79f..32858689574 100644 --- a/chromium/third_party/ffmpeg/libavformat/libsmbclient.c +++ b/chromium/third_party/ffmpeg/libavformat/libsmbclient.c @@ -166,7 +166,7 @@ static int libsmbc_read(URLContext *h, unsigned char *buf, int size) return ret; } - return bytes_read; + return bytes_read ? bytes_read : AVERROR_EOF; } static int libsmbc_write(URLContext *h, const unsigned char *buf, int size) diff --git a/chromium/third_party/ffmpeg/libavformat/libsrt.c b/chromium/third_party/ffmpeg/libavformat/libsrt.c index 0f9529d263a..fbfd6ace838 100644 --- a/chromium/third_party/ffmpeg/libavformat/libsrt.c +++ b/chromium/third_party/ffmpeg/libavformat/libsrt.c @@ -34,6 +34,16 @@ #include "os_support.h" #include "url.h" +/* This is for MPEG-TS and it's a default SRTO_PAYLOADSIZE for SRTT_LIVE (8 TS packets) */ +#ifndef SRT_LIVE_DEFAULT_PAYLOAD_SIZE +#define SRT_LIVE_DEFAULT_PAYLOAD_SIZE 1316 +#endif + +/* This is the maximum payload size for Live mode, should you have a different payload type than MPEG-TS */ +#ifndef SRT_LIVE_MAX_PAYLOAD_SIZE +#define SRT_LIVE_MAX_PAYLOAD_SIZE 1456 +#endif + enum SRTMode { SRT_MODE_CALLER = 0, SRT_MODE_LISTENER = 1, @@ -58,10 +68,13 @@ typedef struct SRTContext { int iptos; int64_t inputbw; int oheadbw; - int64_t tsbpddelay; + int64_t latency; int tlpktdrop; int nakreport; int64_t connect_timeout; + int payload_size; + int64_t rcvlatency; + int64_t peerlatency; enum SRTMode mode; } SRTContext; @@ -73,6 +86,10 @@ static const AVOption libsrt_options[] = { { "listen_timeout", "Connection awaiting timeout", OFFSET(listen_timeout), AV_OPT_TYPE_INT64, { .i64 = -1 }, -1, INT64_MAX, .flags = D|E }, { "send_buffer_size", "Socket send buffer size (in bytes)", OFFSET(send_buffer_size), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, INT_MAX, .flags = D|E }, { "recv_buffer_size", "Socket receive buffer size (in bytes)", OFFSET(recv_buffer_size), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, INT_MAX, .flags = D|E }, + { "pkt_size", "Maximum SRT packet size", OFFSET(payload_size), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, SRT_LIVE_MAX_PAYLOAD_SIZE, .flags = D|E, "payload_size" }, + { "payload_size", "Maximum SRT packet size", OFFSET(payload_size), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, SRT_LIVE_MAX_PAYLOAD_SIZE, .flags = D|E, "payload_size" }, + { "ts_size", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = SRT_LIVE_DEFAULT_PAYLOAD_SIZE }, INT_MIN, INT_MAX, .flags = D|E, "payload_size" }, + { "max_size", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = SRT_LIVE_MAX_PAYLOAD_SIZE }, INT_MIN, INT_MAX, .flags = D|E, "payload_size" }, { "maxbw", "Maximum bandwidth (bytes per second) that the connection can use", OFFSET(maxbw), AV_OPT_TYPE_INT64, { .i64 = -1 }, -1, INT64_MAX, .flags = D|E }, { "pbkeylen", "Crypto key len in bytes {16,24,32} Default: 16 (128-bit)", OFFSET(pbkeylen), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, 32, .flags = D|E }, { "passphrase", "Crypto PBKDF2 Passphrase size[0,10..64] 0:disable crypto", OFFSET(passphrase), AV_OPT_TYPE_STRING, { .str = NULL }, .flags = D|E }, @@ -82,7 +99,10 @@ static const AVOption libsrt_options[] = { { "iptos", "IP Type of Service", OFFSET(iptos), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, 255, .flags = D|E }, { "inputbw", "Estimated input stream rate", OFFSET(inputbw), AV_OPT_TYPE_INT64, { .i64 = -1 }, -1, INT64_MAX, .flags = D|E }, { "oheadbw", "MaxBW ceiling based on % over input stream rate", OFFSET(oheadbw), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, 100, .flags = D|E }, - { "tsbpddelay", "TsbPd receiver delay to absorb burst of missed packet retransmission", OFFSET(tsbpddelay), AV_OPT_TYPE_INT64, { .i64 = -1 }, -1, INT64_MAX, .flags = D|E }, + { "latency", "receiver delay to absorb bursts of missed packet retransmissions", OFFSET(latency), AV_OPT_TYPE_INT64, { .i64 = -1 }, -1, INT64_MAX, .flags = D|E }, + { "tsbpddelay", "deprecated, same effect as latency option", OFFSET(latency), AV_OPT_TYPE_INT64, { .i64 = -1 }, -1, INT64_MAX, .flags = D|E }, + { "rcvlatency", "receive latency", OFFSET(rcvlatency), AV_OPT_TYPE_INT64, { .i64 = -1 }, -1, INT64_MAX, .flags = D|E }, + { "peerlatency", "peer latency", OFFSET(peerlatency), AV_OPT_TYPE_INT64, { .i64 = -1 }, -1, INT64_MAX, .flags = D|E }, { "tlpktdrop", "Enable receiver pkt drop", OFFSET(tlpktdrop), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, 1, .flags = D|E }, { "nakreport", "Enable receiver to send periodic NAK reports", OFFSET(nakreport), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, 1, .flags = D|E }, { "connect_timeout", "Connect timeout. Caller default: 3000, rendezvous (x 10)", OFFSET(connect_timeout), AV_OPT_TYPE_INT64, { .i64 = -1 }, -1, INT64_MAX, .flags = D|E }, @@ -240,6 +260,15 @@ static int libsrt_setsockopt(URLContext *h, int fd, SRT_SOCKOPT optname, const c return 0; } +static int libsrt_getsockopt(URLContext *h, int fd, SRT_SOCKOPT optname, const char * optnamestr, void * optval, int * optlen) +{ + if (srt_getsockopt(fd, 0, optname, optval, optlen) < 0) { + av_log(h, AV_LOG_ERROR, "failed to get option %s on socket: %s\n", optnamestr, srt_getlasterror_str()); + return AVERROR(EIO); + } + return 0; +} + /* - The "POST" options can be altered any time on a connected socket. They MAY have also some meaning when set prior to connecting; such option is SRTO_RCVSYN, which makes connect/accept call asynchronous. @@ -262,21 +291,26 @@ static int libsrt_set_options_pre(URLContext *h, int fd) { SRTContext *s = h->priv_data; int yes = 1; - int tsbpddelay = s->tsbpddelay / 1000; + int latency = s->latency / 1000; + int rcvlatency = s->rcvlatency / 1000; + int peerlatency = s->peerlatency / 1000; int connect_timeout = s->connect_timeout; if ((s->mode == SRT_MODE_RENDEZVOUS && libsrt_setsockopt(h, fd, SRTO_RENDEZVOUS, "SRTO_RENDEZVOUS", &yes, sizeof(yes)) < 0) || (s->maxbw >= 0 && libsrt_setsockopt(h, fd, SRTO_MAXBW, "SRTO_MAXBW", &s->maxbw, sizeof(s->maxbw)) < 0) || (s->pbkeylen >= 0 && libsrt_setsockopt(h, fd, SRTO_PBKEYLEN, "SRTO_PBKEYLEN", &s->pbkeylen, sizeof(s->pbkeylen)) < 0) || - (s->passphrase && libsrt_setsockopt(h, fd, SRTO_PASSPHRASE, "SRTO_PASSPHRASE", &s->passphrase, sizeof(s->passphrase)) < 0) || + (s->passphrase && libsrt_setsockopt(h, fd, SRTO_PASSPHRASE, "SRTO_PASSPHRASE", s->passphrase, strlen(s->passphrase)) < 0) || (s->mss >= 0 && libsrt_setsockopt(h, fd, SRTO_MSS, "SRTO_MMS", &s->mss, sizeof(s->mss)) < 0) || (s->ffs >= 0 && libsrt_setsockopt(h, fd, SRTO_FC, "SRTO_FC", &s->ffs, sizeof(s->ffs)) < 0) || (s->ipttl >= 0 && libsrt_setsockopt(h, fd, SRTO_IPTTL, "SRTO_UPTTL", &s->ipttl, sizeof(s->ipttl)) < 0) || (s->iptos >= 0 && libsrt_setsockopt(h, fd, SRTO_IPTOS, "SRTO_IPTOS", &s->iptos, sizeof(s->iptos)) < 0) || - (tsbpddelay >= 0 && libsrt_setsockopt(h, fd, SRTO_TSBPDDELAY, "SRTO_TSBPDELAY", &tsbpddelay, sizeof(tsbpddelay)) < 0) || + (s->latency >= 0 && libsrt_setsockopt(h, fd, SRTO_LATENCY, "SRTO_LATENCY", &latency, sizeof(latency)) < 0) || + (s->rcvlatency >= 0 && libsrt_setsockopt(h, fd, SRTO_RCVLATENCY, "SRTO_RCVLATENCY", &rcvlatency, sizeof(rcvlatency)) < 0) || + (s->peerlatency >= 0 && libsrt_setsockopt(h, fd, SRTO_PEERLATENCY, "SRTO_PEERLATENCY", &peerlatency, sizeof(peerlatency)) < 0) || (s->tlpktdrop >= 0 && libsrt_setsockopt(h, fd, SRTO_TLPKTDROP, "SRTO_TLPKDROP", &s->tlpktdrop, sizeof(s->tlpktdrop)) < 0) || (s->nakreport >= 0 && libsrt_setsockopt(h, fd, SRTO_NAKREPORT, "SRTO_NAKREPORT", &s->nakreport, sizeof(s->nakreport)) < 0) || - (connect_timeout >= 0 && libsrt_setsockopt(h, fd, SRTO_CONNTIMEO, "SRTO_CONNTIMEO", &connect_timeout, sizeof(connect_timeout)) <0 )) { + (connect_timeout >= 0 && libsrt_setsockopt(h, fd, SRTO_CONNTIMEO, "SRTO_CONNTIMEO", &connect_timeout, sizeof(connect_timeout)) <0 ) || + (s->payload_size >= 0 && libsrt_setsockopt(h, fd, SRTO_PAYLOADSIZE, "SRTO_PAYLOADSIZE", &s->payload_size, sizeof(s->payload_size)) < 0)) { return AVERROR(EIO); } return 0; @@ -380,6 +414,16 @@ static int libsrt_setup(URLContext *h, const char *uri, int flags) goto fail; } + if (flags & AVIO_FLAG_WRITE) { + int packet_size = 0; + int optlen = sizeof(packet_size); + ret = libsrt_getsockopt(h, fd, SRTO_PAYLOADSIZE, "SRTO_PAYLOADSIZE", &packet_size, &optlen); + if (ret < 0) + goto fail1; + if (packet_size > 0) + h->max_packet_size = packet_size; + } + h->is_streamed = 1; s->fd = fd; @@ -442,8 +486,17 @@ static int libsrt_open(URLContext *h, const char *uri, int flags) if (av_find_info_tag(buf, sizeof(buf), "oheadbw", p)) { s->oheadbw = strtoll(buf, NULL, 10); } + if (av_find_info_tag(buf, sizeof(buf), "latency", p)) { + s->latency = strtol(buf, NULL, 10); + } if (av_find_info_tag(buf, sizeof(buf), "tsbpddelay", p)) { - s->tsbpddelay = strtol(buf, NULL, 10); + s->latency = strtol(buf, NULL, 10); + } + if (av_find_info_tag(buf, sizeof(buf), "rcvlatency", p)) { + s->rcvlatency = strtol(buf, NULL, 10); + } + if (av_find_info_tag(buf, sizeof(buf), "peerlatency", p)) { + s->peerlatency = strtol(buf, NULL, 10); } if (av_find_info_tag(buf, sizeof(buf), "tlpktdrop", p)) { s->tlpktdrop = strtol(buf, NULL, 10); @@ -454,6 +507,10 @@ static int libsrt_open(URLContext *h, const char *uri, int flags) if (av_find_info_tag(buf, sizeof(buf), "connect_timeout", p)) { s->connect_timeout = strtol(buf, NULL, 10); } + if (av_find_info_tag(buf, sizeof(buf), "payload_size", p) || + av_find_info_tag(buf, sizeof(buf), "pkt_size", p)) { + s->payload_size = strtol(buf, NULL, 10); + } if (av_find_info_tag(buf, sizeof(buf), "mode", p)) { if (!strcmp(buf, "caller")) { s->mode = SRT_MODE_CALLER; diff --git a/chromium/third_party/ffmpeg/libavformat/matroska.c b/chromium/third_party/ffmpeg/libavformat/matroska.c index 94ccbecedb5..4d18d147fc6 100644 --- a/chromium/third_party/ffmpeg/libavformat/matroska.c +++ b/chromium/third_party/ffmpeg/libavformat/matroska.c @@ -103,6 +103,22 @@ const CodecTags ff_mkv_codec_tags[]={ {"" , AV_CODEC_ID_NONE} }; +const CodecTags ff_webm_codec_tags[] = { + {"V_VP8" , AV_CODEC_ID_VP8}, + {"V_VP9" , AV_CODEC_ID_VP9}, + {"V_AV1" , AV_CODEC_ID_AV1}, + + {"A_VORBIS" , AV_CODEC_ID_VORBIS}, + {"A_OPUS" , AV_CODEC_ID_OPUS}, + + {"D_WEBVTT/SUBTITLES" , AV_CODEC_ID_WEBVTT}, + {"D_WEBVTT/CAPTIONS" , AV_CODEC_ID_WEBVTT}, + {"D_WEBVTT/DESCRIPTIONS", AV_CODEC_ID_WEBVTT}, + {"D_WEBVTT/METADATA" , AV_CODEC_ID_WEBVTT}, + + {"" , AV_CODEC_ID_NONE} +}; + const CodecMime ff_mkv_image_mime_tags[] = { {"image/gif" , AV_CODEC_ID_GIF}, {"image/jpeg" , AV_CODEC_ID_MJPEG}, diff --git a/chromium/third_party/ffmpeg/libavformat/matroska.h b/chromium/third_party/ffmpeg/libavformat/matroska.h index 83c824614de..86968a8de1b 100644 --- a/chromium/third_party/ffmpeg/libavformat/matroska.h +++ b/chromium/third_party/ffmpeg/libavformat/matroska.h @@ -360,6 +360,7 @@ typedef struct CodecTags{ #define MATROSKA_VIDEO_STEREO_PLANE_COUNT 3 extern const CodecTags ff_mkv_codec_tags[]; +extern const CodecTags ff_webm_codec_tags[]; extern const CodecMime ff_mkv_mime_tags[]; extern const CodecMime ff_mkv_image_mime_tags[]; extern const AVMetadataConv ff_mkv_metadata_conv[]; diff --git a/chromium/third_party/ffmpeg/libavformat/matroskadec.c b/chromium/third_party/ffmpeg/libavformat/matroskadec.c index 5b8dba254eb..cd660e66f7c 100644 --- a/chromium/third_party/ffmpeg/libavformat/matroskadec.c +++ b/chromium/third_party/ffmpeg/libavformat/matroskadec.c @@ -2429,6 +2429,10 @@ static int matroska_parse_tracks(AVFormatContext *s) /* we don't need any value stored in CodecPrivate. make sure that it's not exported as extradata. */ track->codec_priv.size = 0; + } else if (codec_id == AV_CODEC_ID_AV1 && track->codec_priv.size) { + /* For now, propagate only the OBUs, if any. Once libavcodec is + updated to handle isobmff style extradata this can be removed. */ + extradata_offset = 4; } track->codec_priv.size -= extradata_offset; diff --git a/chromium/third_party/ffmpeg/libavformat/matroskaenc.c b/chromium/third_party/ffmpeg/libavformat/matroskaenc.c index b7ff1950d33..e88d107a903 100644 --- a/chromium/third_party/ffmpeg/libavformat/matroskaenc.c +++ b/chromium/third_party/ffmpeg/libavformat/matroskaenc.c @@ -21,6 +21,7 @@ #include <stdint.h> +#include "av1.h" #include "avc.h" #include "hevc.h" #include "avformat.h" @@ -769,6 +770,13 @@ static int mkv_write_native_codecprivate(AVFormatContext *s, AVIOContext *pb, ff_isom_write_hvcc(dyn_cp, par->extradata, par->extradata_size, 0); return 0; + case AV_CODEC_ID_AV1: + if (par->extradata_size) + return ff_isom_write_av1c(dyn_cp, par->extradata, + par->extradata_size); + else + put_ebml_void(pb, 4 + 3); + break; case AV_CODEC_ID_ALAC: if (par->extradata_size < 36) { av_log(s, AV_LOG_ERROR, @@ -1230,21 +1238,38 @@ static int mkv_write_track(AVFormatContext *s, MatroskaMuxContext *mkv, if (st->disposition & AV_DISPOSITION_FORCED) put_ebml_uint(pb, MATROSKA_ID_TRACKFLAGFORCED, 1); - if (mkv->mode == MODE_WEBM && par->codec_id == AV_CODEC_ID_WEBVTT) { + if (mkv->mode == MODE_WEBM) { const char *codec_id; - if (st->disposition & AV_DISPOSITION_CAPTIONS) { - codec_id = "D_WEBVTT/CAPTIONS"; - native_id = MATROSKA_TRACK_TYPE_SUBTITLE; - } else if (st->disposition & AV_DISPOSITION_DESCRIPTIONS) { - codec_id = "D_WEBVTT/DESCRIPTIONS"; - native_id = MATROSKA_TRACK_TYPE_METADATA; - } else if (st->disposition & AV_DISPOSITION_METADATA) { - codec_id = "D_WEBVTT/METADATA"; - native_id = MATROSKA_TRACK_TYPE_METADATA; - } else { - codec_id = "D_WEBVTT/SUBTITLES"; - native_id = MATROSKA_TRACK_TYPE_SUBTITLE; + if (par->codec_type != AVMEDIA_TYPE_SUBTITLE) { + for (j = 0; ff_webm_codec_tags[j].id != AV_CODEC_ID_NONE; j++) { + if (ff_webm_codec_tags[j].id == par->codec_id) { + codec_id = ff_webm_codec_tags[j].str; + native_id = 1; + break; + } + } + } else if (par->codec_id == AV_CODEC_ID_WEBVTT) { + if (st->disposition & AV_DISPOSITION_CAPTIONS) { + codec_id = "D_WEBVTT/CAPTIONS"; + native_id = MATROSKA_TRACK_TYPE_SUBTITLE; + } else if (st->disposition & AV_DISPOSITION_DESCRIPTIONS) { + codec_id = "D_WEBVTT/DESCRIPTIONS"; + native_id = MATROSKA_TRACK_TYPE_METADATA; + } else if (st->disposition & AV_DISPOSITION_METADATA) { + codec_id = "D_WEBVTT/METADATA"; + native_id = MATROSKA_TRACK_TYPE_METADATA; + } else { + codec_id = "D_WEBVTT/SUBTITLES"; + native_id = MATROSKA_TRACK_TYPE_SUBTITLE; + } + } + + if (!native_id) { + av_log(s, AV_LOG_ERROR, + "Only VP8 or VP9 or AV1 video and Vorbis or Opus audio and WebVTT subtitles are supported for WebM.\n"); + return AVERROR(EINVAL); } + put_ebml_string(pb, MATROSKA_ID_CODECID, codec_id); } else { // look for a codec ID string specific to mkv to use, @@ -1286,16 +1311,6 @@ static int mkv_write_track(AVFormatContext *s, MatroskaMuxContext *mkv, put_ebml_uint(pb, MATROSKA_ID_SEEKPREROLL, OPUS_SEEK_PREROLL); } - if (mkv->mode == MODE_WEBM && !(par->codec_id == AV_CODEC_ID_VP8 || - par->codec_id == AV_CODEC_ID_VP9 || - par->codec_id == AV_CODEC_ID_OPUS || - par->codec_id == AV_CODEC_ID_VORBIS || - par->codec_id == AV_CODEC_ID_WEBVTT)) { - av_log(s, AV_LOG_ERROR, - "Only VP8 or VP9 video and Vorbis or Opus audio and WebVTT subtitles are supported for WebM.\n"); - return AVERROR(EINVAL); - } - switch (par->codec_type) { case AVMEDIA_TYPE_VIDEO: mkv->have_video = 1; @@ -2120,6 +2135,8 @@ static void mkv_write_block(AVFormatContext *s, AVIOContext *pb, (AV_RB24(par->extradata) == 1 || AV_RB32(par->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 (par->codec_id == AV_CODEC_ID_AV1) + ff_av1_filter_obus_buf(pkt->data, &data, &size); else if (par->codec_id == AV_CODEC_ID_WAVPACK) { int ret = mkv_strip_wavpack(pkt->data, &data, &size); if (ret < 0) { @@ -2319,6 +2336,37 @@ static int mkv_check_new_extra_data(AVFormatContext *s, AVPacket *pkt) avcodec_parameters_free(&codecpriv_par); } break; + // FIXME: Remove the following once libaom starts propagating extradata during init() + // See https://bugs.chromium.org/p/aomedia/issues/detail?id=2012 + case AV_CODEC_ID_AV1: + if (side_data_size && (s->pb->seekable & AVIO_SEEKABLE_NORMAL) && !mkv->is_live && + !par->extradata_size) { + AVIOContext *dyn_cp; + uint8_t *codecpriv; + int codecpriv_size; + int64_t curpos; + ret = avio_open_dyn_buf(&dyn_cp); + if (ret < 0) + return ret; + ff_isom_write_av1c(dyn_cp, side_data, side_data_size); + codecpriv_size = avio_close_dyn_buf(dyn_cp, &codecpriv); + if (!codecpriv_size) { + av_free(codecpriv); + return AVERROR_INVALIDDATA; + } + curpos = avio_tell(mkv->tracks_bc); + avio_seek(mkv->tracks_bc, track->codecpriv_offset, SEEK_SET); + // Do not write the OBUs as we don't have space saved for them + put_ebml_binary(mkv->tracks_bc, MATROSKA_ID_CODECPRIVATE, codecpriv, 4); + av_free(codecpriv); + avio_seek(mkv->tracks_bc, curpos, SEEK_SET); + ret = ff_alloc_extradata(par, side_data_size); + if (ret < 0) + return ret; + memcpy(par->extradata, side_data, side_data_size); + } else if (!par->extradata_size) + return AVERROR_INVALIDDATA; + break; default: if (side_data_size) av_log(s, AV_LOG_DEBUG, "Ignoring new extradata in a packet for stream %d.\n", pkt->stream_index); @@ -2638,6 +2686,16 @@ static int mkv_query_codec(enum AVCodecID codec_id, int std_compliance) return 0; } +static int webm_query_codec(enum AVCodecID codec_id, int std_compliance) +{ + int i; + for (i = 0; ff_webm_codec_tags[i].id != AV_CODEC_ID_NONE; i++) + if (ff_webm_codec_tags[i].id == codec_id) + return 1; + + return 0; +} + static int mkv_init(struct AVFormatContext *s) { int i; @@ -2693,7 +2751,6 @@ static int mkv_check_bitstream(struct AVFormatContext *s, const AVPacket *pkt) static const AVCodecTag additional_audio_tags[] = { { AV_CODEC_ID_ALAC, 0XFFFFFFFF }, - { AV_CODEC_ID_EAC3, 0XFFFFFFFF }, { AV_CODEC_ID_MLP, 0xFFFFFFFF }, { AV_CODEC_ID_OPUS, 0xFFFFFFFF }, { AV_CODEC_ID_PCM_S16BE, 0xFFFFFFFF }, @@ -2712,8 +2769,6 @@ static const AVCodecTag additional_video_tags[] = { { AV_CODEC_ID_RV10, 0xFFFFFFFF }, { AV_CODEC_ID_RV20, 0xFFFFFFFF }, { AV_CODEC_ID_RV30, 0xFFFFFFFF }, - { AV_CODEC_ID_RV40, 0xFFFFFFFF }, - { AV_CODEC_ID_VP9, 0xFFFFFFFF }, { AV_CODEC_ID_NONE, 0xFFFFFFFF } }; @@ -2793,6 +2848,7 @@ AVOutputFormat ff_webm_muxer = { .write_header = mkv_write_header, .write_packet = mkv_write_flush_packet, .write_trailer = mkv_write_trailer, + .query_codec = webm_query_codec, .check_bitstream = mkv_check_bitstream, .flags = AVFMT_GLOBALHEADER | AVFMT_VARIABLE_FPS | AVFMT_TS_NONSTRICT | AVFMT_ALLOW_FLUSH, diff --git a/chromium/third_party/ffmpeg/libavformat/mlvdec.c b/chromium/third_party/ffmpeg/libavformat/mlvdec.c index d387c871ee9..ded8196af23 100644 --- a/chromium/third_party/ffmpeg/libavformat/mlvdec.c +++ b/chromium/third_party/ffmpeg/libavformat/mlvdec.c @@ -77,7 +77,7 @@ static int check_file_header(AVIOContext *pb, uint64_t guid) return 0; } -static void read_string(AVFormatContext *avctx, AVIOContext *pb, const char *tag, int size) +static void read_string(AVFormatContext *avctx, AVIOContext *pb, const char *tag, unsigned size) { char * value = av_malloc(size + 1); if (!value) { diff --git a/chromium/third_party/ffmpeg/libavformat/mov.c b/chromium/third_party/ffmpeg/libavformat/mov.c index 2541bf54e28..76525e208ee 100644 --- a/chromium/third_party/ffmpeg/libavformat/mov.c +++ b/chromium/third_party/ffmpeg/libavformat/mov.c @@ -1911,6 +1911,8 @@ static int mov_read_glbl(MOVContext *c, AVIOContext *pb, MOVAtom atom) ret = ff_get_extradata(c->fc, st->codecpar, pb, atom.size); if (ret < 0) return ret; + if (atom.type == MKTAG('h','v','c','C') && st->codecpar->codec_tag == MKTAG('d','v','h','1')) + st->codecpar->codec_id = AV_CODEC_ID_HEVC; return 0; } @@ -2041,6 +2043,8 @@ static int mov_codec_id(AVStream *st, uint32_t format) id = ff_codec_get_id(ff_codec_movsubtitle_tags, format); if (id > 0) st->codecpar->codec_type = AVMEDIA_TYPE_SUBTITLE; + else + id = ff_codec_get_id(ff_codec_movdata_tags, format); } } @@ -2127,8 +2131,8 @@ static void mov_parse_stsd_audio(MOVContext *c, AVIOContext *pb, // Read QT version 1 fields. In version 0 these do not exist. av_log(c->fc, AV_LOG_TRACE, "version =%d, isom =%d\n", version, c->isom); if (!c->isom || - (compatible_brands && strstr(compatible_brands->value, "qt "))) { - + (compatible_brands && strstr(compatible_brands->value, "qt ")) || + (sc->stsd_version == 0 && version > 0)) { if (version == 1) { sc->samples_per_frame = avio_rb32(pb); avio_rb32(pb); /* bytes per packet */ @@ -2508,18 +2512,16 @@ int ff_mov_read_stsd_entries(MOVContext *c, AVIOContext *pb, int entries) "size=%"PRId64" 4CC=%s codec_type=%d\n", size, av_fourcc2str(format), st->codecpar->codec_type); + st->codecpar->codec_id = id; if (st->codecpar->codec_type==AVMEDIA_TYPE_VIDEO) { - st->codecpar->codec_id = id; mov_parse_stsd_video(c, pb, st, sc); } else if (st->codecpar->codec_type==AVMEDIA_TYPE_AUDIO) { - st->codecpar->codec_id = id; mov_parse_stsd_audio(c, pb, st, sc); if (st->codecpar->sample_rate < 0) { av_log(c->fc, AV_LOG_ERROR, "Invalid sample rate %d\n", st->codecpar->sample_rate); return AVERROR_INVALIDDATA; } } else if (st->codecpar->codec_type==AVMEDIA_TYPE_SUBTITLE){ - st->codecpar->codec_id = id; mov_parse_stsd_subtitle(c, pb, st, sc, size - (avio_tell(pb) - start_pos)); } else { @@ -2570,11 +2572,12 @@ static int mov_read_stsd(MOVContext *c, AVIOContext *pb, MOVAtom atom) st = c->fc->streams[c->fc->nb_streams - 1]; sc = st->priv_data; - avio_r8(pb); /* version */ + sc->stsd_version = avio_r8(pb); avio_rb24(pb); /* flags */ entries = avio_rb32(pb); - if (entries <= 0) { + /* Each entry contains a size (4 bytes) and format (4 bytes). */ + if (entries <= 0 || entries > atom.size / 8) { av_log(c->fc, AV_LOG_ERROR, "invalid STSD entries %d\n", entries); return AVERROR_INVALIDDATA; } @@ -3710,9 +3713,9 @@ static void mov_fix_index(MOVContext *mov, AVStream *st) st->index_entries[i].timestamp -= msc->min_corrected_pts; } } - // Start time should be equal to zero or the duration of any empty edits. - st->start_time = empty_edits_sum_duration; } + // Start time should be equal to zero or the duration of any empty edits. + st->start_time = empty_edits_sum_duration; // Update av stream length, if it ends up shorter than the track's media duration st->duration = FFMIN(st->duration, edit_list_dts_entry_end - start_dts); @@ -5218,27 +5221,25 @@ static int mov_read_tmcd(MOVContext *c, AVIOContext *pb, MOVAtom atom) static int mov_read_av1c(MOVContext *c, AVIOContext *pb, MOVAtom atom) { AVStream *st; - int ret, version; + int ret; if (c->fc->nb_streams < 1) return 0; st = c->fc->streams[c->fc->nb_streams - 1]; - if (atom.size < 5) { + if (atom.size < 4) { av_log(c->fc, AV_LOG_ERROR, "Empty AV1 Codec Configuration Box\n"); return AVERROR_INVALIDDATA; } - version = avio_r8(pb); - if (version != 0) { - av_log(c->fc, AV_LOG_WARNING, "Unknown AV1 Codec Configuration Box version %d\n", version); - return 0; - } - avio_skip(pb, 3); /* flags */ + /* For now, propagate only the OBUs, if any. Once libavcodec is + updated to handle isobmff style extradata this can be removed. */ + avio_skip(pb, 4); - avio_skip(pb, 1); /* reserved, initial_presentation_delay_present, initial_presentation_delay_minus_one */ + if (atom.size == 4) + return 0; - ret = ff_get_extradata(c->fc, st->codecpar, pb, atom.size - 5); + ret = ff_get_extradata(c->fc, st->codecpar, pb, atom.size - 4); if (ret < 0) return ret; @@ -5912,6 +5913,11 @@ static int mov_read_sample_encryption_info(MOVContext *c, AVIOContext *pb, MOVSt unsigned int subsample_count; AVSubsampleEncryptionInfo *subsamples; + if (!sc->cenc.default_encrypted_sample) { + av_log(c->fc, AV_LOG_ERROR, "Missing schm or tenc\n"); + return AVERROR_INVALIDDATA; + } + *sample = av_encryption_info_clone(sc->cenc.default_encrypted_sample); if (!*sample) return AVERROR(ENOMEM); diff --git a/chromium/third_party/ffmpeg/libavformat/movenc.c b/chromium/third_party/ffmpeg/libavformat/movenc.c index d530f40cab3..6b9c012bc66 100644 --- a/chromium/third_party/ffmpeg/libavformat/movenc.c +++ b/chromium/third_party/ffmpeg/libavformat/movenc.c @@ -1170,9 +1170,6 @@ static int mov_write_av1c_tag(AVIOContext *pb, MOVTrack *track) avio_wb32(pb, 0); ffio_wfourcc(pb, "av1C"); - avio_w8(pb, 0); /* version */ - avio_wb24(pb, 0); /* flags */ - avio_w8(pb, 0); /* reserved (3), initial_presentation_delay_present (1), initial_presentation_delay_minus_one/reserved (4) */ ff_isom_write_av1c(pb, track->vos_data, track->vos_len); return update_size(pb, pos); } @@ -1538,9 +1535,9 @@ static int mov_get_rawvideo_codec_tag(AVFormatContext *s, MOVTrack *track) return tag; } -static int mov_get_codec_tag(AVFormatContext *s, MOVTrack *track) +static unsigned int mov_get_codec_tag(AVFormatContext *s, MOVTrack *track) { - int tag = track->par->codec_tag; + unsigned int tag = track->par->codec_tag; if (!tag || (s->strict_std_compliance >= FF_COMPLIANCE_NORMAL && (track->par->codec_id == AV_CODEC_ID_DVVIDEO || @@ -1592,31 +1589,45 @@ static const AVCodecTag codec_cover_image_tags[] = { { AV_CODEC_ID_NONE, 0 }, }; -static int mov_find_codec_tag(AVFormatContext *s, MOVTrack *track) +static unsigned int validate_codec_tag(const AVCodecTag *const *tags, + unsigned int tag, int codec_id) { - int tag; + int i; + + /** + * Check that tag + id is in the table + */ + for (i = 0; tags && tags[i]; i++) { + const AVCodecTag *codec_tags = tags[i]; + while (codec_tags->id != AV_CODEC_ID_NONE) { + if (avpriv_toupper4(codec_tags->tag) == avpriv_toupper4(tag) && + codec_tags->id == codec_id) + return codec_tags->tag; + codec_tags++; + } + } + return 0; +} + +static unsigned int mov_find_codec_tag(AVFormatContext *s, MOVTrack *track) +{ + unsigned int tag; if (is_cover_image(track->st)) return ff_codec_get_tag(codec_cover_image_tags, track->par->codec_id); - if (track->mode == MODE_MP4 || track->mode == MODE_PSP) - tag = track->par->codec_tag; - else if (track->mode == MODE_ISM) - tag = track->par->codec_tag; - else if (track->mode == MODE_IPOD) { + if (track->mode == MODE_IPOD) if (!av_match_ext(s->url, "m4a") && !av_match_ext(s->url, "m4v") && !av_match_ext(s->url, "m4b")) av_log(s, AV_LOG_WARNING, "Warning, extension is not .m4a nor .m4v " "Quicktime/Ipod might not play the file\n"); - tag = track->par->codec_tag; - } else if (track->mode & MODE_3GP) - tag = track->par->codec_tag; - else if (track->mode == MODE_F4V) - tag = track->par->codec_tag; - else - tag = mov_get_codec_tag(s, track); + if (track->mode == MODE_MOV) + tag = mov_get_codec_tag(s, track); + else + tag = validate_codec_tag(s->oformat->codec_tag, track->par->codec_tag, + track->par->codec_id); return tag; } @@ -2368,9 +2379,9 @@ static int mov_preroll_write_stbl_atoms(AVIOContext *pb, MOVTrack *track) decoded. */ if (roll_samples_remaining > 0) distance = 0; - /* Verify distance is a minimum of 2 (60ms) packets and a maximum of - 32 (2.5ms) packets. */ - av_assert0(distance == 0 || (distance >= 2 && distance <= 32)); + /* Verify distance is a maximum of 32 (2.5ms) packets. */ + if (distance > 32) + return AVERROR_INVALIDDATA; if (i && distance == sgpd_entries[entries].roll_distance) { sgpd_entries[entries].count++; } else { @@ -6049,7 +6060,7 @@ static int mov_init(AVFormatContext *s) /* Set other implicit flags immediately */ if (mov->mode == MODE_ISM) mov->flags |= FF_MOV_FLAG_EMPTY_MOOV | FF_MOV_FLAG_SEPARATE_MOOF | - FF_MOV_FLAG_FRAGMENT; + FF_MOV_FLAG_FRAGMENT | FF_MOV_FLAG_NEGATIVE_CTS_OFFSETS; if (mov->flags & FF_MOV_FLAG_DASH) mov->flags |= FF_MOV_FLAG_FRAGMENT | FF_MOV_FLAG_EMPTY_MOOV | FF_MOV_FLAG_DEFAULT_BASE_MOOF; @@ -6244,14 +6255,6 @@ static int mov_init(AVFormatContext *s) av_log(s, AV_LOG_ERROR, "%s only supported in MP4.\n", avcodec_get_name(track->par->codec_id)); return AVERROR(EINVAL); } - if (track->par->codec_id == AV_CODEC_ID_AV1 && - s->strict_std_compliance > FF_COMPLIANCE_EXPERIMENTAL) { - av_log(s, AV_LOG_ERROR, - "av1 in MP4 support is experimental, add " - "'-strict %d' if you want to use it.\n", - FF_COMPLIANCE_EXPERIMENTAL); - return AVERROR_EXPERIMENTAL; - } } else if (track->par->codec_id == AV_CODEC_ID_VP8) { /* altref frames handling is not defined in the spec as of version v1.0, * so just forbid muxing VP8 streams altogether until a new version does */ @@ -6781,6 +6784,7 @@ const AVCodecTag codec_mp4_tags[] = { { AV_CODEC_ID_EVRC , MKTAG('m', 'p', '4', 'a') }, { AV_CODEC_ID_DVD_SUBTITLE, MKTAG('m', 'p', '4', 's') }, { AV_CODEC_ID_MOV_TEXT , MKTAG('t', 'x', '3', 'g') }, + { AV_CODEC_ID_BIN_DATA , MKTAG('g', 'p', 'm', 'd') }, { AV_CODEC_ID_NONE , 0 }, }; diff --git a/chromium/third_party/ffmpeg/libavformat/mpeg.c b/chromium/third_party/ffmpeg/libavformat/mpeg.c index 8ae4740920b..d4369b49c2c 100644 --- a/chromium/third_party/ffmpeg/libavformat/mpeg.c +++ b/chromium/third_party/ffmpeg/libavformat/mpeg.c @@ -544,6 +544,9 @@ redo: } else if (es_type == STREAM_TYPE_VIDEO_H264) { codec_id = AV_CODEC_ID_H264; type = AVMEDIA_TYPE_VIDEO; + } else if (es_type == STREAM_TYPE_VIDEO_HEVC) { + codec_id = AV_CODEC_ID_HEVC; + type = AVMEDIA_TYPE_VIDEO; } else if (es_type == STREAM_TYPE_AUDIO_AC3) { codec_id = AV_CODEC_ID_AC3; type = AVMEDIA_TYPE_AUDIO; @@ -647,7 +650,7 @@ found: pkt->stream_index = st->index; if (s->debug & FF_FDEBUG_TS) - av_log(s, AV_LOG_TRACE, "%d: pts=%0.3f dts=%0.3f size=%d\n", + av_log(s, AV_LOG_DEBUG, "%d: pts=%0.3f dts=%0.3f size=%d\n", pkt->stream_index, pkt->pts / 90000.0, pkt->dts / 90000.0, pkt->size); @@ -668,7 +671,7 @@ static int64_t mpegps_read_dts(AVFormatContext *s, int stream_index, len = mpegps_read_pes_header(s, &pos, &startcode, &pts, &dts); if (len < 0) { if (s->debug & FF_FDEBUG_TS) - av_log(s, AV_LOG_TRACE, "none (ret=%d)\n", len); + av_log(s, AV_LOG_DEBUG, "none (ret=%d)\n", len); return AV_NOPTS_VALUE; } if (startcode == s->streams[stream_index]->id && @@ -678,7 +681,7 @@ static int64_t mpegps_read_dts(AVFormatContext *s, int stream_index, avio_skip(s->pb, len); } if (s->debug & FF_FDEBUG_TS) - av_log(s, AV_LOG_TRACE, "pos=0x%"PRIx64" dts=0x%"PRIx64" %0.3f\n", + av_log(s, AV_LOG_DEBUG, "pos=0x%"PRIx64" dts=0x%"PRIx64" %0.3f\n", pos, dts, dts / 90000.0); *ppos = pos; return dts; diff --git a/chromium/third_party/ffmpeg/libavformat/mpeg.h b/chromium/third_party/ffmpeg/libavformat/mpeg.h index 617e36cba81..b6352957762 100644 --- a/chromium/third_party/ffmpeg/libavformat/mpeg.h +++ b/chromium/third_party/ffmpeg/libavformat/mpeg.h @@ -55,6 +55,7 @@ #define STREAM_TYPE_AUDIO_AAC 0x0f #define STREAM_TYPE_VIDEO_MPEG4 0x10 #define STREAM_TYPE_VIDEO_H264 0x1b +#define STREAM_TYPE_VIDEO_HEVC 0x24 #define STREAM_TYPE_VIDEO_CAVS 0x42 #define STREAM_TYPE_AUDIO_AC3 0x81 diff --git a/chromium/third_party/ffmpeg/libavformat/mpegts.c b/chromium/third_party/ffmpeg/libavformat/mpegts.c index a5cb17ac167..edf6b5701df 100644 --- a/chromium/third_party/ffmpeg/libavformat/mpegts.c +++ b/chromium/third_party/ffmpeg/libavformat/mpegts.c @@ -1983,7 +1983,7 @@ int ff_parse_mpeg2_descriptor(AVFormatContext *fc, AVStream *st, int stream_type int service_type = ((component_type & service_type_mask) >> 3); if (service_type == 0x02 /* 0b010 */) { st->disposition |= AV_DISPOSITION_DESCRIPTIONS; - av_log(ts->stream, AV_LOG_DEBUG, "New track disposition for id %u: %u\n", st->id, st->disposition); + av_log(ts ? ts->stream : fc, AV_LOG_DEBUG, "New track disposition for id %u: %u\n", st->id, st->disposition); } } } @@ -1997,7 +1997,7 @@ int ff_parse_mpeg2_descriptor(AVFormatContext *fc, AVStream *st, int stream_type int service_type = ((component_type & service_type_mask) >> 3); if (service_type == 0x02 /* 0b010 */) { st->disposition |= AV_DISPOSITION_DESCRIPTIONS; - av_log(ts->stream, AV_LOG_DEBUG, "New track disposition for id %u: %u\n", st->id, st->disposition); + av_log(ts ? ts->stream : fc, AV_LOG_DEBUG, "New track disposition for id %u: %u\n", st->id, st->disposition); } } } diff --git a/chromium/third_party/ffmpeg/libavformat/mux.c b/chromium/third_party/ffmpeg/libavformat/mux.c index a13f0e3a1b8..2847a02a19c 100644 --- a/chromium/third_party/ffmpeg/libavformat/mux.c +++ b/chromium/third_party/ffmpeg/libavformat/mux.c @@ -571,7 +571,7 @@ static int compute_muxer_pkt_fields(AVFormatContext *s, AVStream *st, AVPacket * } if (s->debug & FF_FDEBUG_TS) - av_log(s, AV_LOG_TRACE, "compute_muxer_pkt_fields: pts:%s dts:%s cur_dts:%s b:%d size:%d st:%d\n", + av_log(s, AV_LOG_DEBUG, "compute_muxer_pkt_fields: pts:%s dts:%s cur_dts:%s b:%d size:%d st:%d\n", av_ts2str(pkt->pts), av_ts2str(pkt->dts), av_ts2str(st->cur_dts), delay, pkt->size, pkt->stream_index); if (pkt->duration < 0 && st->codecpar->codec_type != AVMEDIA_TYPE_SUBTITLE) { @@ -633,7 +633,7 @@ static int compute_muxer_pkt_fields(AVFormatContext *s, AVStream *st, AVPacket * } if (s->debug & FF_FDEBUG_TS) - av_log(s, AV_LOG_TRACE, "av_write_frame: pts2:%s dts2:%s\n", + av_log(s, AV_LOG_DEBUG, "av_write_frame: pts2:%s dts2:%s\n", av_ts2str(pkt->pts), av_ts2str(pkt->dts)); st->cur_dts = pkt->dts; @@ -1200,7 +1200,7 @@ int av_interleaved_write_frame(AVFormatContext *s, AVPacket *pkt) goto fail; if (s->debug & FF_FDEBUG_TS) - av_log(s, AV_LOG_TRACE, "av_interleaved_write_frame size:%d dts:%s pts:%s\n", + av_log(s, AV_LOG_DEBUG, "av_interleaved_write_frame size:%d dts:%s pts:%s\n", pkt->size, av_ts2str(pkt->dts), av_ts2str(pkt->pts)); #if FF_API_COMPUTE_PKT_FIELDS2 && FF_API_LAVF_AVCTX diff --git a/chromium/third_party/ffmpeg/libavformat/mxfdec.c b/chromium/third_party/ffmpeg/libavformat/mxfdec.c index 8e1089620ff..134f27784bd 100644 --- a/chromium/third_party/ffmpeg/libavformat/mxfdec.c +++ b/chromium/third_party/ffmpeg/libavformat/mxfdec.c @@ -2390,7 +2390,6 @@ static int mxf_parse_structural_metadata(MXFContext *mxf) if (st->codecpar->codec_id == AV_CODEC_ID_NONE || (st->codecpar->codec_id == AV_CODEC_ID_PCM_ALAW && (enum AVCodecID)container_ul->id != AV_CODEC_ID_NONE)) st->codecpar->codec_id = (enum AVCodecID)container_ul->id; st->codecpar->channels = descriptor->channels; - st->codecpar->bits_per_coded_sample = descriptor->bits_per_sample; if (descriptor->sample_rate.den > 0) { st->codecpar->sample_rate = descriptor->sample_rate.num / descriptor->sample_rate.den; @@ -2423,6 +2422,7 @@ static int mxf_parse_structural_metadata(MXFContext *mxf) } else if (st->codecpar->codec_id == AV_CODEC_ID_MP2) { st->need_parsing = AVSTREAM_PARSE_FULL; } + st->codecpar->bits_per_coded_sample = av_get_bits_per_sample(st->codecpar->codec_id); } else if (st->codecpar->codec_type == AVMEDIA_TYPE_DATA) { enum AVMediaType type; container_ul = mxf_get_codec_ul(mxf_data_essence_container_uls, essence_container_ul); @@ -3269,7 +3269,8 @@ static int64_t mxf_set_current_edit_unit(MXFContext *mxf, AVStream *st, int64_t static int mxf_set_audio_pts(MXFContext *mxf, AVCodecParameters *par, AVPacket *pkt) { - MXFTrack *track = mxf->fc->streams[pkt->stream_index]->priv_data; + AVStream *st = mxf->fc->streams[pkt->stream_index]; + MXFTrack *track = st->priv_data; int64_t bits_per_sample = par->bits_per_coded_sample; if (!bits_per_sample) @@ -3280,8 +3281,10 @@ static int mxf_set_audio_pts(MXFContext *mxf, AVCodecParameters *par, if ( par->channels <= 0 || bits_per_sample <= 0 || par->channels * (int64_t)bits_per_sample < 8) - return AVERROR(EINVAL); - track->sample_count += pkt->size / (par->channels * (int64_t)bits_per_sample / 8); + track->sample_count = mxf_compute_sample_count(mxf, st, av_rescale_q(track->sample_count, st->time_base, av_inv_q(track->edit_rate)) + 1); + else + track->sample_count += pkt->size / (par->channels * (int64_t)bits_per_sample / 8); + return 0; } diff --git a/chromium/third_party/ffmpeg/libavformat/mxfenc.c b/chromium/third_party/ffmpeg/libavformat/mxfenc.c index 77f60f58744..65205740724 100644 --- a/chromium/third_party/ffmpeg/libavformat/mxfenc.c +++ b/chromium/third_party/ffmpeg/libavformat/mxfenc.c @@ -146,6 +146,11 @@ enum ULIndex { INDEX_DNXHD_720p_8bit_HIGH, INDEX_DNXHD_720p_8bit_MEDIUM, INDEX_DNXHD_720p_8bit_LOW, + INDEX_DNXHR_LB, + INDEX_DNXHR_SQ, + INDEX_DNXHR_HQ, + INDEX_DNXHR_HQX, + INDEX_DNXHR_444, INDEX_JPEG2000, INDEX_H264, }; @@ -345,6 +350,31 @@ static const MXFContainerEssenceEntry mxf_essence_container_uls[] = { { 0x06,0x0e,0x2b,0x34,0x01,0x02,0x01,0x01,0x0d,0x01,0x03,0x01,0x15,0x01,0x05,0x00 }, { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x0A,0x04,0x01,0x02,0x02,0x71,0x13,0x00,0x00 }, mxf_write_cdci_desc }, + // DNxHR LB - CID 1274 + { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x01,0x0d,0x01,0x03,0x01,0x02,0x11,0x01,0x00 }, + { 0x06,0x0e,0x2b,0x34,0x01,0x02,0x01,0x01,0x0d,0x01,0x03,0x01,0x15,0x01,0x05,0x00 }, + { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x0D,0x04,0x01,0x02,0x02,0x71,0x28,0x00,0x00 }, + mxf_write_cdci_desc }, + // DNxHR SQ - CID 1273 + { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x01,0x0d,0x01,0x03,0x01,0x02,0x11,0x01,0x00 }, + { 0x06,0x0e,0x2b,0x34,0x01,0x02,0x01,0x01,0x0d,0x01,0x03,0x01,0x15,0x01,0x05,0x00 }, + { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x0D,0x04,0x01,0x02,0x02,0x71,0x27,0x00,0x00 }, + mxf_write_cdci_desc }, + // DNxHR HQ - CID 1272 + { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x01,0x0d,0x01,0x03,0x01,0x02,0x11,0x01,0x00 }, + { 0x06,0x0e,0x2b,0x34,0x01,0x02,0x01,0x01,0x0d,0x01,0x03,0x01,0x15,0x01,0x05,0x00 }, + { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x0D,0x04,0x01,0x02,0x02,0x71,0x26,0x00,0x00 }, + mxf_write_cdci_desc }, + // DNxHR HQX - CID 1271 + { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x01,0x0d,0x01,0x03,0x01,0x02,0x11,0x01,0x00 }, + { 0x06,0x0e,0x2b,0x34,0x01,0x02,0x01,0x01,0x0d,0x01,0x03,0x01,0x15,0x01,0x05,0x00 }, + { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x0D,0x04,0x01,0x02,0x02,0x71,0x25,0x00,0x00 }, + mxf_write_cdci_desc }, + // DNxHR 444 - CID 1270 + { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x01,0x0d,0x01,0x03,0x01,0x02,0x11,0x01,0x00 }, + { 0x06,0x0e,0x2b,0x34,0x01,0x02,0x01,0x01,0x0d,0x01,0x03,0x01,0x15,0x01,0x05,0x00 }, + { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x0D,0x04,0x01,0x02,0x02,0x71,0x24,0x00,0x00 }, + mxf_write_cdci_desc }, // JPEG2000 { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x07,0x0d,0x01,0x03,0x01,0x02,0x0c,0x01,0x00 }, { 0x06,0x0e,0x2b,0x34,0x01,0x02,0x01,0x01,0x0d,0x01,0x03,0x01,0x15,0x01,0x08,0x00 }, @@ -1104,14 +1134,16 @@ static void mxf_write_multi_descriptor(AVFormatContext *s) mxf_write_uuid(pb, SubDescriptor, i); } -static void mxf_write_generic_desc(AVFormatContext *s, AVStream *st, const UID key, unsigned size) +static int64_t mxf_write_generic_desc(AVFormatContext *s, AVStream *st, const UID key) { MXFContext *mxf = s->priv_data; MXFStreamContext *sc = st->priv_data; AVIOContext *pb = s->pb; + int64_t pos; avio_write(pb, key, 16); - klv_encode_ber4_length(pb, size+20+8+12+20); + klv_encode_ber4_length(pb, 0); + pos = avio_tell(pb); mxf_write_local_tag(pb, 16, 0x3C0A); mxf_write_uuid(pb, SubDescriptor, st->index); @@ -1136,6 +1168,8 @@ static void mxf_write_generic_desc(AVFormatContext *s, AVStream *st, const UID k mxf_write_local_tag(pb, 16, 0x3004); avio_write(pb, mxf_essence_container_uls[sc->index].container_ul, 16); + + return pos; } static const UID mxf_mpegvideo_descriptor_key = { 0x06,0x0E,0x2B,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x01,0x01,0x01,0x01,0x51,0x00 }; @@ -1172,7 +1206,7 @@ static int get_trc(UID ul, enum AVColorTransferCharacteristic trc) } } -static void mxf_write_cdci_common(AVFormatContext *s, AVStream *st, const UID key, unsigned size) +static int64_t mxf_write_cdci_common(AVFormatContext *s, AVStream *st, const UID key) { MXFStreamContext *sc = st->priv_data; AVIOContext *pb = s->pb; @@ -1180,25 +1214,10 @@ static void mxf_write_cdci_common(AVFormatContext *s, AVStream *st, const UID ke int stored_height = (st->codecpar->height+15)/16*16; int display_height; int f1, f2; - unsigned desc_size = size+8+8+8+8+8+8+8+5+16+4+12+20+5 + 5*8 + 6; UID transfer_ul = {0}; + int64_t pos = mxf_write_generic_desc(s, st, key); - if (sc->interlaced && sc->field_dominance) - desc_size += 5; - if (sc->signal_standard) - desc_size += 5; - if (sc->interlaced) - desc_size += 8; - if (sc->v_chroma_sub_sample) - desc_size += 8; - if (st->codecpar->color_range != AVCOL_RANGE_UNSPECIFIED) - desc_size += 8 * 3; - if (s->oformat == &ff_mxf_d10_muxer) - desc_size += 8 + 8 + 8; - if (get_trc(transfer_ul, st->codecpar->color_trc) >= 0) - desc_size += 20; - - mxf_write_generic_desc(s, st, key, desc_size); + get_trc(transfer_ul, st->codecpar->color_trc); mxf_write_local_tag(pb, 4, 0x3203); avio_wb32(pb, stored_width); @@ -1352,11 +1371,22 @@ static void mxf_write_cdci_common(AVFormatContext *s, AVStream *st, const UID ke avio_w8(pb, sc->field_dominance); } + return pos; +} + +static void mxf_update_klv_size(AVIOContext *pb, int64_t pos) +{ + int64_t cur_pos = avio_tell(pb); + int size = cur_pos - pos; + avio_seek(pb, pos - 4, SEEK_SET); + klv_encode_ber4_length(pb, size); + avio_seek(pb, cur_pos, SEEK_SET); } static void mxf_write_cdci_desc(AVFormatContext *s, AVStream *st) { - mxf_write_cdci_common(s, st, mxf_cdci_descriptor_key, 0); + int64_t pos = mxf_write_cdci_common(s, st, mxf_cdci_descriptor_key); + mxf_update_klv_size(s->pb, pos); } static void mxf_write_mpegvideo_desc(AVFormatContext *s, AVStream *st) @@ -1364,10 +1394,9 @@ static void mxf_write_mpegvideo_desc(AVFormatContext *s, AVStream *st) AVIOContext *pb = s->pb; MXFStreamContext *sc = st->priv_data; int profile_and_level = (st->codecpar->profile<<4) | st->codecpar->level; + int64_t pos = mxf_write_cdci_common(s, st, mxf_mpegvideo_descriptor_key); if (st->codecpar->codec_id != AV_CODEC_ID_H264) { - mxf_write_cdci_common(s, st, mxf_mpegvideo_descriptor_key, 8+5); - // bit rate mxf_write_local_tag(pb, 4, 0x8000); avio_wb32(pb, sc->video_bit_rate); @@ -1377,26 +1406,19 @@ static void mxf_write_mpegvideo_desc(AVFormatContext *s, AVStream *st) if (!st->codecpar->profile) profile_and_level |= 0x80; // escape bit avio_w8(pb, profile_and_level); - } else { - mxf_write_cdci_common(s, st, mxf_mpegvideo_descriptor_key, 0); } + + mxf_update_klv_size(pb, pos); } -static void mxf_write_generic_sound_common(AVFormatContext *s, AVStream *st, const UID key, unsigned size) +static int64_t mxf_write_generic_sound_common(AVFormatContext *s, AVStream *st, const UID key) { AVIOContext *pb = s->pb; MXFContext *mxf = s->priv_data; int show_warnings = !mxf->footer_partition_offset; - int duration_size = 0; - - if (s->oformat == &ff_mxf_opatom_muxer) - duration_size = 12; - if (s->oformat == &ff_mxf_d10_muxer) - size += 5; + int64_t pos = mxf_write_generic_desc(s, st, key); - mxf_write_generic_desc(s, st, key, size+duration_size+5+12+8+8); - - if (duration_size > 0) { + if (s->oformat == &ff_mxf_opatom_muxer) { mxf_write_local_tag(pb, 8, 0x3002); avio_wb64(pb, mxf->body_offset / mxf->edit_unit_byte_count); } @@ -1432,13 +1454,14 @@ static void mxf_write_generic_sound_common(AVFormatContext *s, AVStream *st, con mxf_write_local_tag(pb, 4, 0x3D01); avio_wb32(pb, av_get_bits_per_sample(st->codecpar->codec_id)); + + return pos; } -static void mxf_write_wav_common(AVFormatContext *s, AVStream *st, const UID key, unsigned size) +static int64_t mxf_write_wav_common(AVFormatContext *s, AVStream *st, const UID key) { AVIOContext *pb = s->pb; - - mxf_write_generic_sound_common(s, st, key, size+6+8); + int64_t pos = mxf_write_generic_sound_common(s, st, key); mxf_write_local_tag(pb, 2, 0x3D0A); avio_wb16(pb, st->codecpar->block_align); @@ -1446,21 +1469,26 @@ static void mxf_write_wav_common(AVFormatContext *s, AVStream *st, const UID key // avg bytes per sec mxf_write_local_tag(pb, 4, 0x3D09); avio_wb32(pb, st->codecpar->block_align*st->codecpar->sample_rate); + + return pos; } static void mxf_write_wav_desc(AVFormatContext *s, AVStream *st) { - mxf_write_wav_common(s, st, mxf_wav_descriptor_key, 0); + int64_t pos = mxf_write_wav_common(s, st, mxf_wav_descriptor_key); + mxf_update_klv_size(s->pb, pos); } static void mxf_write_aes3_desc(AVFormatContext *s, AVStream *st) { - mxf_write_wav_common(s, st, mxf_aes3_descriptor_key, 0); + int64_t pos = mxf_write_wav_common(s, st, mxf_aes3_descriptor_key); + mxf_update_klv_size(s->pb, pos); } static void mxf_write_generic_sound_desc(AVFormatContext *s, AVStream *st) { - mxf_write_generic_sound_common(s, st, mxf_generic_sound_descriptor_key, 0); + int64_t pos = mxf_write_generic_sound_common(s, st, mxf_generic_sound_descriptor_key); + mxf_update_klv_size(s->pb, pos); } static const uint8_t mxf_indirect_value_utf16le[] = { 0x4c,0x00,0x02,0x10,0x01,0x00,0x00,0x00,0x00,0x06,0x0e,0x2b,0x34,0x01,0x04,0x01,0x01 }; @@ -1961,7 +1989,11 @@ AVPacket *pkt) header_cid = pkt->data + 0x28; cid = header_cid[0] << 24 | header_cid[1] << 16 | header_cid[2] << 8 | header_cid[3]; - if ((frame_size = avpriv_dnxhd_get_frame_size(cid)) < 0) + if ((frame_size = avpriv_dnxhd_get_frame_size(cid)) == DNXHD_VARIABLE) { + frame_size = avpriv_dnxhd_get_hr_frame_size(cid, st->codecpar->width, st->codecpar->height); + } + + if (frame_size < 0) return -1; if ((sc->interlaced = avpriv_dnxhd_get_interlaced(cid)) < 0) return AVERROR_INVALIDDATA; @@ -2000,6 +2032,23 @@ AVPacket *pkt) case 1253: sc->index = INDEX_DNXHD_720p_8bit_LOW; break; + case 1274: + sc->index = INDEX_DNXHR_LB; + break; + case 1273: + sc->index = INDEX_DNXHR_SQ; + break; + case 1272: + sc->index = INDEX_DNXHR_HQ; + break; + case 1271: + sc->index = INDEX_DNXHR_HQX; + sc->component_depth = st->codecpar->bits_per_raw_sample; + break; + case 1270: + sc->index = INDEX_DNXHR_444; + sc->component_depth = st->codecpar->bits_per_raw_sample; + break; default: return -1; } @@ -2914,6 +2963,9 @@ static int mxf_interleave_get_packet(AVFormatContext *s, AVPacket *out, AVPacket while (pktl) { if (!stream_count || pktl->pkt.stream_index == 0) break; + // update last packet in packet buffer + if (s->streams[pktl->pkt.stream_index]->last_in_packet_buffer != pktl) + s->streams[pktl->pkt.stream_index]->last_in_packet_buffer = pktl; last = pktl; pktl = pktl->next; stream_count--; @@ -2921,9 +2973,6 @@ static int mxf_interleave_get_packet(AVFormatContext *s, AVPacket *out, AVPacket // purge packet queue while (pktl) { AVPacketList *next = pktl->next; - - if(s->streams[pktl->pkt.stream_index]->last_in_packet_buffer == pktl) - s->streams[pktl->pkt.stream_index]->last_in_packet_buffer= NULL; av_packet_unref(&pktl->pkt); av_freep(&pktl); pktl = next; diff --git a/chromium/third_party/ffmpeg/libavformat/network.c b/chromium/third_party/ffmpeg/libavformat/network.c index d5c82e9ab9b..5664455d186 100644 --- a/chromium/third_party/ffmpeg/libavformat/network.c +++ b/chromium/third_party/ffmpeg/libavformat/network.c @@ -24,6 +24,7 @@ #include "url.h" #include "libavcodec/internal.h" #include "libavutil/avutil.h" +#include "libavutil/avassert.h" #include "libavutil/mem.h" #include "libavutil/time.h" @@ -165,14 +166,17 @@ static int ff_poll_interrupt(struct pollfd *p, nfds_t nfds, int timeout, if (ff_check_interrupt(cb)) return AVERROR_EXIT; ret = poll(p, nfds, POLLING_TIME); - if (ret != 0) + if (ret != 0) { + if (ret < 0) + ret = ff_neterrno(); + if (ret == AVERROR(EINTR)) + continue; break; + } } while (timeout <= 0 || runs-- > 0); if (!ret) return AVERROR(ETIMEDOUT); - if (ret < 0) - return ff_neterrno(); return ret; } @@ -194,8 +198,11 @@ int ff_socket(int af, int type, int proto) #endif } #ifdef SO_NOSIGPIPE - if (fd != -1) - setsockopt(fd, SOL_SOCKET, SO_NOSIGPIPE, &(int){1}, sizeof(int)); + if (fd != -1) { + if (setsockopt(fd, SOL_SOCKET, SO_NOSIGPIPE, &(int){1}, sizeof(int))) { + av_log(NULL, AV_LOG_WARNING, "setsockopt(SO_NOSIGPIPE) failed\n"); + } + } #endif return fd; } @@ -293,6 +300,230 @@ int ff_listen_connect(int fd, const struct sockaddr *addr, return ret; } +static void interleave_addrinfo(struct addrinfo *base) +{ + struct addrinfo **next = &base->ai_next; + while (*next) { + struct addrinfo *cur = *next; + // Iterate forward until we find an entry of a different family. + if (cur->ai_family == base->ai_family) { + next = &cur->ai_next; + continue; + } + if (cur == base->ai_next) { + // If the first one following base is of a different family, just + // move base forward one step and continue. + base = cur; + next = &base->ai_next; + continue; + } + // Unchain cur from the rest of the list from its current spot. + *next = cur->ai_next; + // Hook in cur directly after base. + cur->ai_next = base->ai_next; + base->ai_next = cur; + // Restart with a new base. We know that before moving the cur element, + // everything between the previous base and cur had the same family, + // different from cur->ai_family. Therefore, we can keep next pointing + // where it was, and continue from there with base at the one after + // cur. + base = cur->ai_next; + } +} + +static void print_address_list(void *ctx, const struct addrinfo *addr, + const char *title) +{ + char hostbuf[100], portbuf[20]; + av_log(ctx, AV_LOG_DEBUG, "%s:\n", title); + while (addr) { + getnameinfo(addr->ai_addr, addr->ai_addrlen, + hostbuf, sizeof(hostbuf), portbuf, sizeof(portbuf), + NI_NUMERICHOST | NI_NUMERICSERV); + av_log(ctx, AV_LOG_DEBUG, "Address %s port %s\n", hostbuf, portbuf); + addr = addr->ai_next; + } +} + +struct ConnectionAttempt { + int fd; + int64_t deadline_us; + struct addrinfo *addr; +}; + +// Returns < 0 on error, 0 on successfully started connection attempt, +// > 0 for a connection that succeeded already. +static int start_connect_attempt(struct ConnectionAttempt *attempt, + struct addrinfo **ptr, int timeout_ms, + URLContext *h, + void (*customize_fd)(void *, int), void *customize_ctx) +{ + struct addrinfo *ai = *ptr; + int ret; + + *ptr = ai->ai_next; + + attempt->fd = ff_socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol); + if (attempt->fd < 0) + return ff_neterrno(); + attempt->deadline_us = av_gettime_relative() + timeout_ms * 1000; + attempt->addr = ai; + + ff_socket_nonblock(attempt->fd, 1); + + if (customize_fd) + customize_fd(customize_ctx, attempt->fd); + + while ((ret = connect(attempt->fd, ai->ai_addr, ai->ai_addrlen))) { + ret = ff_neterrno(); + switch (ret) { + case AVERROR(EINTR): + if (ff_check_interrupt(&h->interrupt_callback)) { + closesocket(attempt->fd); + attempt->fd = -1; + return AVERROR_EXIT; + } + continue; + case AVERROR(EINPROGRESS): + case AVERROR(EAGAIN): + return 0; + default: + closesocket(attempt->fd); + attempt->fd = -1; + return ret; + } + } + return 1; +} + +// Try a new connection to another address after 200 ms, as suggested in +// RFC 8305 (or sooner if an earlier attempt fails). +#define NEXT_ATTEMPT_DELAY_MS 200 + +int ff_connect_parallel(struct addrinfo *addrs, int timeout_ms_per_address, + int parallel, URLContext *h, int *fd, + void (*customize_fd)(void *, int), void *customize_ctx) +{ + struct ConnectionAttempt attempts[3]; + struct pollfd pfd[3]; + int nb_attempts = 0, i, j; + int64_t next_attempt_us = av_gettime_relative(), next_deadline_us; + int last_err = AVERROR(EIO); + socklen_t optlen; + char errbuf[100], hostbuf[100], portbuf[20]; + + if (parallel > FF_ARRAY_ELEMS(attempts)) + parallel = FF_ARRAY_ELEMS(attempts); + + print_address_list(h, addrs, "Original list of addresses"); + // This mutates the list, but the head of the list is still the same + // element, so the caller, who owns the list, doesn't need to get + // an updated pointer. + interleave_addrinfo(addrs); + print_address_list(h, addrs, "Interleaved list of addresses"); + + while (nb_attempts > 0 || addrs) { + // Start a new connection attempt, if possible. + if (nb_attempts < parallel && addrs) { + getnameinfo(addrs->ai_addr, addrs->ai_addrlen, + hostbuf, sizeof(hostbuf), portbuf, sizeof(portbuf), + NI_NUMERICHOST | NI_NUMERICSERV); + av_log(h, AV_LOG_VERBOSE, "Starting connection attempt to %s port %s\n", + hostbuf, portbuf); + last_err = start_connect_attempt(&attempts[nb_attempts], &addrs, + timeout_ms_per_address, h, + customize_fd, customize_ctx); + if (last_err < 0) { + av_strerror(last_err, errbuf, sizeof(errbuf)); + av_log(h, AV_LOG_VERBOSE, "Connected attempt failed: %s\n", + errbuf); + continue; + } + if (last_err > 0) { + for (i = 0; i < nb_attempts; i++) + closesocket(attempts[i].fd); + *fd = attempts[nb_attempts].fd; + return 0; + } + pfd[nb_attempts].fd = attempts[nb_attempts].fd; + pfd[nb_attempts].events = POLLOUT; + next_attempt_us = av_gettime_relative() + NEXT_ATTEMPT_DELAY_MS * 1000; + nb_attempts++; + } + + av_assert0(nb_attempts > 0); + // The connection attempts are sorted from oldest to newest, so the + // first one will have the earliest deadline. + next_deadline_us = attempts[0].deadline_us; + // If we can start another attempt in parallel, wait until that time. + if (nb_attempts < parallel && addrs) + next_deadline_us = FFMIN(next_deadline_us, next_attempt_us); + last_err = ff_poll_interrupt(pfd, nb_attempts, + (next_deadline_us - av_gettime_relative())/1000, + &h->interrupt_callback); + if (last_err < 0 && last_err != AVERROR(ETIMEDOUT)) + break; + + // Check the status from the poll output. + for (i = 0; i < nb_attempts; i++) { + last_err = 0; + if (pfd[i].revents) { + // Some sort of action for this socket, check its status (either + // a successful connection or an error). + optlen = sizeof(last_err); + if (getsockopt(attempts[i].fd, SOL_SOCKET, SO_ERROR, &last_err, &optlen)) + last_err = ff_neterrno(); + else if (last_err != 0) + last_err = AVERROR(last_err); + if (last_err == 0) { + // Everything is ok, we seem to have a successful + // connection. Close other sockets and return this one. + for (j = 0; j < nb_attempts; j++) + if (j != i) + closesocket(attempts[j].fd); + *fd = attempts[i].fd; + getnameinfo(attempts[i].addr->ai_addr, attempts[i].addr->ai_addrlen, + hostbuf, sizeof(hostbuf), portbuf, sizeof(portbuf), + NI_NUMERICHOST | NI_NUMERICSERV); + av_log(h, AV_LOG_VERBOSE, "Successfully connected to %s port %s\n", + hostbuf, portbuf); + return 0; + } + } + if (attempts[i].deadline_us < av_gettime_relative() && !last_err) + last_err = AVERROR(ETIMEDOUT); + if (!last_err) + continue; + // Error (or timeout) for this socket; close the socket and remove + // it from the attempts/pfd arrays, to let a new attempt start + // directly. + getnameinfo(attempts[i].addr->ai_addr, attempts[i].addr->ai_addrlen, + hostbuf, sizeof(hostbuf), portbuf, sizeof(portbuf), + NI_NUMERICHOST | NI_NUMERICSERV); + av_strerror(last_err, errbuf, sizeof(errbuf)); + av_log(h, AV_LOG_VERBOSE, "Connection attempt to %s port %s " + "failed: %s\n", hostbuf, portbuf, errbuf); + closesocket(attempts[i].fd); + memmove(&attempts[i], &attempts[i + 1], + (nb_attempts - i - 1) * sizeof(*attempts)); + memmove(&pfd[i], &pfd[i + 1], + (nb_attempts - i - 1) * sizeof(*pfd)); + i--; + nb_attempts--; + } + } + for (i = 0; i < nb_attempts; i++) + closesocket(attempts[i].fd); + if (last_err >= 0) + last_err = AVERROR(ECONNREFUSED); + if (last_err != AVERROR_EXIT) { + av_strerror(last_err, errbuf, sizeof(errbuf)); + av_log(h, AV_LOG_ERROR, "Connection to %s failed: %s\n", + h->filename, errbuf); + } + return last_err; +} + static int match_host_pattern(const char *pattern, const char *hostname) { int len_p, len_h; @@ -346,3 +577,10 @@ int ff_http_match_no_proxy(const char *no_proxy, const char *hostname) av_free(buf); return ret; } + +void ff_log_net_error(void *ctx, int level, const char* prefix) +{ + char errbuf[100]; + av_strerror(ff_neterrno(), errbuf, sizeof(errbuf)); + av_log(ctx, level, "%s: %s\n", prefix, errbuf); +} diff --git a/chromium/third_party/ffmpeg/libavformat/network.h b/chromium/third_party/ffmpeg/libavformat/network.h index efaa7893a40..7f467304a80 100644 --- a/chromium/third_party/ffmpeg/libavformat/network.h +++ b/chromium/third_party/ffmpeg/libavformat/network.h @@ -304,4 +304,34 @@ int ff_http_match_no_proxy(const char *no_proxy, const char *hostname); int ff_socket(int domain, int type, int protocol); +void ff_log_net_error(void *ctx, int level, const char* prefix); + +/** + * Connect to any of the given addrinfo addresses, with multiple attempts + * running in parallel. + * + * @param addrs The list of addresses to try to connect to. + * This list will be mutated internally, but the list head + * will remain as such, so this doesn't affect the caller + * freeing the list afterwards. + * @param timeout_ms_per_address The number of milliseconds to wait for each + * connection attempt. Since multiple addresses are tried, + * some of them in parallel, the total run time will at most + * be timeout_ms_per_address*ceil(nb_addrs/parallel) + + * (parallel - 1) * NEXT_ATTEMPT_DELAY_MS. + * @param parallel The maximum number of connections to attempt in parallel. + * This is limited to an internal maximum capacity. + * @param h URLContext providing interrupt check + * callback and logging context. + * @param fd If successful, the connected socket is returned here. + * @param customize_fd Function that will be called for each socket created, + * to allow the caller to set socket options before calling + * connect() on it, may be NULL. + * @param customize_ctx Context parameter passed to customize_fd. + * @return 0 on success, AVERROR on failure. + */ +int ff_connect_parallel(struct addrinfo *addrs, int timeout_ms_per_address, + int parallel, URLContext *h, int *fd, + void (*customize_fd)(void *, int), void *customize_ctx); + #endif /* AVFORMAT_NETWORK_H */ diff --git a/chromium/third_party/ffmpeg/libavformat/nsvdec.c b/chromium/third_party/ffmpeg/libavformat/nsvdec.c index d8ce656817c..92f7d178f68 100644 --- a/chromium/third_party/ffmpeg/libavformat/nsvdec.c +++ b/chromium/third_party/ffmpeg/libavformat/nsvdec.c @@ -176,6 +176,7 @@ typedef struct NSVContext { int16_t avsync; AVRational framerate; uint32_t *nsvs_timestamps; + int nsvf; } NSVContext; static const AVCodecTag nsv_codec_video_tags[] = { @@ -266,6 +267,12 @@ static int nsv_parse_NSVf_header(AVFormatContext *s) nsv->state = NSV_UNSYNC; /* in case we fail */ + if (nsv->nsvf) { + av_log(s, AV_LOG_TRACE, "Multiple NSVf\n"); + return 0; + } + nsv->nsvf = 1; + size = avio_rl32(pb); if (size < 28) return -1; diff --git a/chromium/third_party/ffmpeg/libavformat/rawenc.c b/chromium/third_party/ffmpeg/libavformat/rawenc.c index 809ca23b1a5..993d232b70c 100644 --- a/chromium/third_party/ffmpeg/libavformat/rawenc.c +++ b/chromium/third_party/ffmpeg/libavformat/rawenc.c @@ -117,6 +117,19 @@ AVOutputFormat ff_aptx_hd_muxer = { }; #endif +#if CONFIG_AVS2_MUXER +AVOutputFormat ff_avs2_muxer = { + .name = "avs2", + .long_name = NULL_IF_CONFIG_SMALL("raw AVS2-P2/IEEE1857.4 video"), + .extensions = "avs,avs2", + .audio_codec = AV_CODEC_ID_NONE, + .video_codec = AV_CODEC_ID_AVS2, + .write_header = force_one_stream, + .write_packet = ff_raw_write_packet, + .flags = AVFMT_NOTIMESTAMPS, +}; +#endif + #if CONFIG_CAVSVIDEO_MUXER AVOutputFormat ff_cavsvideo_muxer = { .name = "cavsvideo", diff --git a/chromium/third_party/ffmpeg/libavformat/riff.c b/chromium/third_party/ffmpeg/libavformat/riff.c index 0950415c26f..3907e1a9f38 100644 --- a/chromium/third_party/ffmpeg/libavformat/riff.c +++ b/chromium/third_party/ffmpeg/libavformat/riff.c @@ -369,6 +369,7 @@ const AVCodecTag ff_codec_bmp_tags[] = { { AV_CODEC_ID_ZMBV, MKTAG('Z', 'M', 'B', 'V') }, { AV_CODEC_ID_KMVC, MKTAG('K', 'M', 'V', 'C') }, { AV_CODEC_ID_CAVS, MKTAG('C', 'A', 'V', 'S') }, + { AV_CODEC_ID_AVS2, MKTAG('A', 'V', 'S', '2') }, { AV_CODEC_ID_JPEG2000, MKTAG('m', 'j', 'p', '2') }, { AV_CODEC_ID_JPEG2000, MKTAG('M', 'J', '2', 'C') }, { AV_CODEC_ID_JPEG2000, MKTAG('L', 'J', '2', 'C') }, @@ -469,6 +470,11 @@ const AVCodecTag ff_codec_bmp_tags[] = { { AV_CODEC_ID_AV1, MKTAG('A', 'V', '0', '1') }, { AV_CODEC_ID_MSCC, MKTAG('M', 'S', 'C', 'C') }, { AV_CODEC_ID_SRGC, MKTAG('S', 'R', 'G', 'C') }, + { AV_CODEC_ID_IMM4, MKTAG('I', 'M', 'M', '4') }, + { AV_CODEC_ID_PROSUMER, MKTAG('B', 'T', '2', '0') }, + { AV_CODEC_ID_MWSC, MKTAG('M', 'W', 'S', 'C') }, + { AV_CODEC_ID_WCMV, MKTAG('W', 'C', 'M', 'V') }, + { AV_CODEC_ID_RASC, MKTAG('R', 'A', 'S', 'C') }, { AV_CODEC_ID_NONE, 0 } }; diff --git a/chromium/third_party/ffmpeg/libavformat/rmdec.c b/chromium/third_party/ffmpeg/libavformat/rmdec.c index 0216003e88e..f26c5b4d907 100644 --- a/chromium/third_party/ffmpeg/libavformat/rmdec.c +++ b/chromium/third_party/ffmpeg/libavformat/rmdec.c @@ -1269,6 +1269,8 @@ static int ivr_read_header(AVFormatContext *s) if (avio_rb32(pb) == MKBETAG('M', 'L', 'T', 'I')) { ret = rm_read_multi(s, pb, st, NULL); } else { + if (avio_feof(pb)) + return AVERROR_INVALIDDATA; avio_seek(pb, -4, SEEK_CUR); ret = ff_rm_read_mdpr_codecdata(s, pb, st, st->priv_data, len, NULL); } diff --git a/chromium/third_party/ffmpeg/libavformat/tcp.c b/chromium/third_party/ffmpeg/libavformat/tcp.c index b0289f854fc..2198e0f00e2 100644 --- a/chromium/third_party/ffmpeg/libavformat/tcp.c +++ b/chromium/third_party/ffmpeg/libavformat/tcp.c @@ -42,6 +42,9 @@ typedef struct TCPContext { int recv_buffer_size; int send_buffer_size; int tcp_nodelay; +#if !HAVE_WINSOCK2_H + int tcp_mss; +#endif /* !HAVE_WINSOCK2_H */ } TCPContext; #define OFFSET(x) offsetof(TCPContext, x) @@ -54,6 +57,9 @@ static const AVOption options[] = { { "send_buffer_size", "Socket send buffer size (in bytes)", OFFSET(send_buffer_size), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, INT_MAX, .flags = D|E }, { "recv_buffer_size", "Socket receive buffer size (in bytes)", OFFSET(recv_buffer_size), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, INT_MAX, .flags = D|E }, { "tcp_nodelay", "Use TCP_NODELAY to disable nagle's algorithm", OFFSET(tcp_nodelay), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, .flags = D|E }, +#if !HAVE_WINSOCK2_H + { "tcp_mss", "Maximum segment size for outgoing TCP packets", OFFSET(tcp_mss), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, INT_MAX, .flags = D|E }, +#endif /* !HAVE_WINSOCK2_H */ { NULL } }; @@ -64,6 +70,35 @@ static const AVClass tcp_class = { .version = LIBAVUTIL_VERSION_INT, }; +static void customize_fd(void *ctx, int fd) +{ + TCPContext *s = ctx; + /* Set the socket's send or receive buffer sizes, if specified. + If unspecified or setting fails, system default is used. */ + if (s->recv_buffer_size > 0) { + if (setsockopt (fd, SOL_SOCKET, SO_RCVBUF, &s->recv_buffer_size, sizeof (s->recv_buffer_size))) { + ff_log_net_error(ctx, AV_LOG_WARNING, "setsockopt(SO_RCVBUF)"); + } + } + if (s->send_buffer_size > 0) { + if (setsockopt (fd, SOL_SOCKET, SO_SNDBUF, &s->send_buffer_size, sizeof (s->send_buffer_size))) { + ff_log_net_error(ctx, AV_LOG_WARNING, "setsockopt(SO_SNDBUF)"); + } + } + if (s->tcp_nodelay > 0) { + if (setsockopt (fd, IPPROTO_TCP, TCP_NODELAY, &s->tcp_nodelay, sizeof (s->tcp_nodelay))) { + ff_log_net_error(ctx, AV_LOG_WARNING, "setsockopt(TCP_NODELAY)"); + } + } +#if !HAVE_WINSOCK2_H + if (s->tcp_mss > 0) { + if (setsockopt (fd, IPPROTO_TCP, TCP_MAXSEG, &s->tcp_mss, sizeof (s->tcp_mss))) { + ff_log_net_error(ctx, AV_LOG_WARNING, "setsockopt(TCP_MAXSEG)"); + } + } +#endif /* !HAVE_WINSOCK2_H */ +} + /* return non zero if error */ static int tcp_open(URLContext *h, const char *uri, int flags) { @@ -123,7 +158,6 @@ static int tcp_open(URLContext *h, const char *uri, int flags) cur_ai = ai; - restart: #if HAVE_STRUCT_SOCKADDR_IN6 // workaround for IOS9 getaddrinfo in IPv6 only network use hardcode IPv4 address can not resolve port number. if (cur_ai->ai_family == AF_INET6){ @@ -134,24 +168,19 @@ static int tcp_open(URLContext *h, const char *uri, int flags) } #endif - fd = ff_socket(cur_ai->ai_family, - cur_ai->ai_socktype, - cur_ai->ai_protocol); - if (fd < 0) { - ret = ff_neterrno(); - goto fail; - } - - /* Set the socket's send or receive buffer sizes, if specified. - If unspecified or setting fails, system default is used. */ - if (s->recv_buffer_size > 0) { - setsockopt (fd, SOL_SOCKET, SO_RCVBUF, &s->recv_buffer_size, sizeof (s->recv_buffer_size)); - } - if (s->send_buffer_size > 0) { - setsockopt (fd, SOL_SOCKET, SO_SNDBUF, &s->send_buffer_size, sizeof (s->send_buffer_size)); - } - if (s->tcp_nodelay > 0) { - setsockopt (fd, IPPROTO_TCP, TCP_NODELAY, &s->tcp_nodelay, sizeof (s->tcp_nodelay)); + if (s->listen > 0) { + while (cur_ai && fd < 0) { + fd = ff_socket(cur_ai->ai_family, + cur_ai->ai_socktype, + cur_ai->ai_protocol); + if (fd < 0) { + ret = ff_neterrno(); + cur_ai = cur_ai->ai_next; + } + } + if (fd < 0) + goto fail1; + customize_fd(s, fd); } if (s->listen == 2) { @@ -166,14 +195,9 @@ static int tcp_open(URLContext *h, const char *uri, int flags) // Socket descriptor already closed here. Safe to overwrite to client one. fd = ret; } else { - if ((ret = ff_listen_connect(fd, cur_ai->ai_addr, cur_ai->ai_addrlen, - s->open_timeout / 1000, h, !!cur_ai->ai_next)) < 0) { - - if (ret == AVERROR_EXIT) - goto fail1; - else - goto fail; - } + ret = ff_connect_parallel(ai, s->open_timeout / 1000, 3, h, &fd, customize_fd, s); + if (ret < 0) + goto fail1; } h->is_streamed = 1; @@ -182,15 +206,6 @@ static int tcp_open(URLContext *h, const char *uri, int flags) freeaddrinfo(ai); return 0; - fail: - if (cur_ai->ai_next) { - /* Retry with the next sockaddr */ - cur_ai = cur_ai->ai_next; - if (fd >= 0) - closesocket(fd); - ret = 0; - goto restart; - } fail1: if (fd >= 0) closesocket(fd); diff --git a/chromium/third_party/ffmpeg/libavformat/tls_mbedtls.c b/chromium/third_party/ffmpeg/libavformat/tls_mbedtls.c index b42b76f8dbc..9b80a1e3c74 100644 --- a/chromium/third_party/ffmpeg/libavformat/tls_mbedtls.c +++ b/chromium/third_party/ffmpeg/libavformat/tls_mbedtls.c @@ -23,7 +23,7 @@ #include <mbedtls/config.h> #include <mbedtls/ctr_drbg.h> #include <mbedtls/entropy.h> -#include <mbedtls/net.h> +#include <mbedtls/net_sockets.h> #include <mbedtls/platform.h> #include <mbedtls/ssl.h> #include <mbedtls/x509_crt.h> diff --git a/chromium/third_party/ffmpeg/libavformat/tls_openssl.c b/chromium/third_party/ffmpeg/libavformat/tls_openssl.c index 59a86150a79..7ae71bdaf36 100644 --- a/chromium/third_party/ffmpeg/libavformat/tls_openssl.c +++ b/chromium/third_party/ffmpeg/libavformat/tls_openssl.c @@ -119,7 +119,7 @@ static int print_tls_error(URLContext *h, int ret) TLSContext *c = h->priv_data; if (h->flags & AVIO_FLAG_NONBLOCK) { int err = SSL_get_error(c->ssl, ret); - if (err == SSL_ERROR_WANT_READ || err == SSL_ERROR_WANT_READ) + if (err == SSL_ERROR_WANT_READ || err == SSL_ERROR_WANT_WRITE) return AVERROR(EAGAIN); } av_log(h, AV_LOG_ERROR, "%s\n", ERR_error_string(ERR_get_error(), NULL)); diff --git a/chromium/third_party/ffmpeg/libavformat/tls_schannel.c b/chromium/third_party/ffmpeg/libavformat/tls_schannel.c index f41b007773f..4f0badcb8dd 100644 --- a/chromium/third_party/ffmpeg/libavformat/tls_schannel.c +++ b/chromium/third_party/ffmpeg/libavformat/tls_schannel.c @@ -148,7 +148,7 @@ static int tls_client_handshake_loop(URLContext *h, int initial) TLSContext *c = h->priv_data; TLSShared *s = &c->tls_shared; SECURITY_STATUS sspi_ret; - SecBuffer outbuf[3]; + SecBuffer outbuf[3] = { 0 }; SecBufferDesc outbuf_desc; SecBuffer inbuf[2]; SecBufferDesc inbuf_desc; diff --git a/chromium/third_party/ffmpeg/libavformat/udp.c b/chromium/third_party/ffmpeg/libavformat/udp.c index 0dde0353fbe..bbdeda05fe1 100644 --- a/chromium/third_party/ffmpeg/libavformat/udp.c +++ b/chromium/third_party/ffmpeg/libavformat/udp.c @@ -150,20 +150,13 @@ static const AVClass udplite_context_class = { .version = LIBAVUTIL_VERSION_INT, }; -static void log_net_error(void *ctx, int level, const char* prefix) -{ - char errbuf[100]; - av_strerror(ff_neterrno(), errbuf, sizeof(errbuf)); - av_log(ctx, level, "%s: %s\n", prefix, errbuf); -} - static int udp_set_multicast_ttl(int sockfd, int mcastTTL, struct sockaddr *addr) { #ifdef IP_MULTICAST_TTL if (addr->sa_family == AF_INET) { if (setsockopt(sockfd, IPPROTO_IP, IP_MULTICAST_TTL, &mcastTTL, sizeof(mcastTTL)) < 0) { - log_net_error(NULL, AV_LOG_ERROR, "setsockopt(IP_MULTICAST_TTL)"); + ff_log_net_error(NULL, AV_LOG_ERROR, "setsockopt(IP_MULTICAST_TTL)"); return -1; } } @@ -171,7 +164,7 @@ static int udp_set_multicast_ttl(int sockfd, int mcastTTL, #if defined(IPPROTO_IPV6) && defined(IPV6_MULTICAST_HOPS) if (addr->sa_family == AF_INET6) { if (setsockopt(sockfd, IPPROTO_IPV6, IPV6_MULTICAST_HOPS, &mcastTTL, sizeof(mcastTTL)) < 0) { - log_net_error(NULL, AV_LOG_ERROR, "setsockopt(IPV6_MULTICAST_HOPS)"); + ff_log_net_error(NULL, AV_LOG_ERROR, "setsockopt(IPV6_MULTICAST_HOPS)"); return -1; } } @@ -191,7 +184,7 @@ static int udp_join_multicast_group(int sockfd, struct sockaddr *addr,struct soc else mreq.imr_interface.s_addr= INADDR_ANY; if (setsockopt(sockfd, IPPROTO_IP, IP_ADD_MEMBERSHIP, (const void *)&mreq, sizeof(mreq)) < 0) { - log_net_error(NULL, AV_LOG_ERROR, "setsockopt(IP_ADD_MEMBERSHIP)"); + ff_log_net_error(NULL, AV_LOG_ERROR, "setsockopt(IP_ADD_MEMBERSHIP)"); return -1; } } @@ -203,7 +196,7 @@ static int udp_join_multicast_group(int sockfd, struct sockaddr *addr,struct soc memcpy(&mreq6.ipv6mr_multiaddr, &(((struct sockaddr_in6 *)addr)->sin6_addr), sizeof(struct in6_addr)); mreq6.ipv6mr_interface= 0; if (setsockopt(sockfd, IPPROTO_IPV6, IPV6_ADD_MEMBERSHIP, &mreq6, sizeof(mreq6)) < 0) { - log_net_error(NULL, AV_LOG_ERROR, "setsockopt(IPV6_ADD_MEMBERSHIP)"); + ff_log_net_error(NULL, AV_LOG_ERROR, "setsockopt(IPV6_ADD_MEMBERSHIP)"); return -1; } } @@ -223,7 +216,7 @@ static int udp_leave_multicast_group(int sockfd, struct sockaddr *addr,struct so else mreq.imr_interface.s_addr= INADDR_ANY; if (setsockopt(sockfd, IPPROTO_IP, IP_DROP_MEMBERSHIP, (const void *)&mreq, sizeof(mreq)) < 0) { - log_net_error(NULL, AV_LOG_ERROR, "setsockopt(IP_DROP_MEMBERSHIP)"); + ff_log_net_error(NULL, AV_LOG_ERROR, "setsockopt(IP_DROP_MEMBERSHIP)"); return -1; } } @@ -235,7 +228,7 @@ static int udp_leave_multicast_group(int sockfd, struct sockaddr *addr,struct so memcpy(&mreq6.ipv6mr_multiaddr, &(((struct sockaddr_in6 *)addr)->sin6_addr), sizeof(struct in6_addr)); mreq6.ipv6mr_interface= 0; if (setsockopt(sockfd, IPPROTO_IPV6, IPV6_DROP_MEMBERSHIP, &mreq6, sizeof(mreq6)) < 0) { - log_net_error(NULL, AV_LOG_ERROR, "setsockopt(IPV6_DROP_MEMBERSHIP)"); + ff_log_net_error(NULL, AV_LOG_ERROR, "setsockopt(IPV6_DROP_MEMBERSHIP)"); return -1; } } @@ -300,9 +293,9 @@ static int udp_set_multicast_sources(URLContext *h, include ? MCAST_JOIN_SOURCE_GROUP : MCAST_BLOCK_SOURCE, (const void *)&mreqs, sizeof(mreqs)) < 0) { if (include) - log_net_error(NULL, AV_LOG_ERROR, "setsockopt(MCAST_JOIN_SOURCE_GROUP)"); + ff_log_net_error(NULL, AV_LOG_ERROR, "setsockopt(MCAST_JOIN_SOURCE_GROUP)"); else - log_net_error(NULL, AV_LOG_ERROR, "setsockopt(MCAST_BLOCK_SOURCE)"); + ff_log_net_error(NULL, AV_LOG_ERROR, "setsockopt(MCAST_BLOCK_SOURCE)"); return ff_neterrno(); } } @@ -336,9 +329,9 @@ static int udp_set_multicast_sources(URLContext *h, include ? IP_ADD_SOURCE_MEMBERSHIP : IP_BLOCK_SOURCE, (const void *)&mreqs, sizeof(mreqs)) < 0) { if (include) - log_net_error(NULL, AV_LOG_ERROR, "setsockopt(IP_ADD_SOURCE_MEMBERSHIP)"); + ff_log_net_error(NULL, AV_LOG_ERROR, "setsockopt(IP_ADD_SOURCE_MEMBERSHIP)"); else - log_net_error(NULL, AV_LOG_ERROR, "setsockopt(IP_BLOCK_SOURCE)"); + ff_log_net_error(NULL, AV_LOG_ERROR, "setsockopt(IP_BLOCK_SOURCE)"); return ff_neterrno(); } } @@ -384,7 +377,7 @@ static int udp_socket_create(URLContext *h, struct sockaddr_storage *addr, else udp_fd = ff_socket(res->ai_family, SOCK_DGRAM, 0); if (udp_fd != -1) break; - log_net_error(NULL, AV_LOG_ERROR, "socket"); + ff_log_net_error(NULL, AV_LOG_ERROR, "socket"); } if (udp_fd < 0) @@ -459,7 +452,7 @@ int ff_udp_set_remote_url(URLContext *h, const char *uri) if (connect(s->udp_fd, (struct sockaddr *) &s->dest_addr, s->dest_addr_len)) { s->is_connected = 0; - log_net_error(h, AV_LOG_ERROR, "connect"); + ff_log_net_error(h, AV_LOG_ERROR, "connect"); return AVERROR(EIO); } } @@ -866,7 +859,7 @@ static int udp_open(URLContext *h, const char *uri, int flags) * bind failed */ /* the bind is needed to give a port to the socket now */ if (bind_ret < 0 && bind(udp_fd,(struct sockaddr *)&my_addr, len) < 0) { - log_net_error(h, AV_LOG_ERROR, "bind failed"); + ff_log_net_error(h, AV_LOG_ERROR, "bind failed"); goto fail; } @@ -912,18 +905,18 @@ static int udp_open(URLContext *h, const char *uri, int flags) /* limit the tx buf size to limit latency */ tmp = s->buffer_size; if (setsockopt(udp_fd, SOL_SOCKET, SO_SNDBUF, &tmp, sizeof(tmp)) < 0) { - log_net_error(h, AV_LOG_ERROR, "setsockopt(SO_SNDBUF)"); + ff_log_net_error(h, AV_LOG_ERROR, "setsockopt(SO_SNDBUF)"); goto fail; } } else { /* set udp recv buffer size to the requested value (default 64K) */ tmp = s->buffer_size; if (setsockopt(udp_fd, SOL_SOCKET, SO_RCVBUF, &tmp, sizeof(tmp)) < 0) { - log_net_error(h, AV_LOG_WARNING, "setsockopt(SO_RECVBUF)"); + ff_log_net_error(h, AV_LOG_WARNING, "setsockopt(SO_RECVBUF)"); } len = sizeof(tmp); if (getsockopt(udp_fd, SOL_SOCKET, SO_RCVBUF, &tmp, &len) < 0) { - log_net_error(h, AV_LOG_WARNING, "getsockopt(SO_RCVBUF)"); + ff_log_net_error(h, AV_LOG_WARNING, "getsockopt(SO_RCVBUF)"); } else { av_log(h, AV_LOG_DEBUG, "end receive buffer size reported is %d\n", tmp); if(tmp < s->buffer_size) @@ -935,7 +928,7 @@ static int udp_open(URLContext *h, const char *uri, int flags) } if (s->is_connected) { if (connect(udp_fd, (struct sockaddr *) &s->dest_addr, s->dest_addr_len)) { - log_net_error(h, AV_LOG_ERROR, "connect"); + ff_log_net_error(h, AV_LOG_ERROR, "connect"); goto fail; } } diff --git a/chromium/third_party/ffmpeg/libavformat/utils.c b/chromium/third_party/ffmpeg/libavformat/utils.c index 15c0c4bddca..c6901174432 100644 --- a/chromium/third_party/ffmpeg/libavformat/utils.c +++ b/chromium/third_party/ffmpeg/libavformat/utils.c @@ -1332,7 +1332,7 @@ static void compute_pkt_fields(AVFormatContext *s, AVStream *st, presentation_delayed = 1; if (s->debug & FF_FDEBUG_TS) - av_log(s, AV_LOG_TRACE, + av_log(s, AV_LOG_DEBUG, "IN delayed:%d pts:%s, dts:%s cur_dts:%s st:%d pc:%p duration:%"PRId64" delay:%d onein_oneout:%d\n", presentation_delayed, av_ts2str(pkt->pts), av_ts2str(pkt->dts), av_ts2str(st->cur_dts), pkt->stream_index, pc, pkt->duration, delay, onein_oneout); @@ -1401,11 +1401,11 @@ static void compute_pkt_fields(AVFormatContext *s, AVStream *st, st->cur_dts = pkt->dts; if (s->debug & FF_FDEBUG_TS) - av_log(s, AV_LOG_TRACE, "OUTdelayed:%d/%d pts:%s, dts:%s cur_dts:%s\n", + av_log(s, AV_LOG_DEBUG, "OUTdelayed:%d/%d pts:%s, dts:%s cur_dts:%s\n", presentation_delayed, delay, av_ts2str(pkt->pts), av_ts2str(pkt->dts), av_ts2str(st->cur_dts)); /* update flags */ - if (is_intra_only(st->codecpar->codec_id)) + if (st->codecpar->codec_type == AVMEDIA_TYPE_DATA || is_intra_only(st->codecpar->codec_id)) pkt->flags |= AV_PKT_FLAG_KEY; #if FF_API_CONVERGENCE_DURATION FF_DISABLE_DEPRECATION_WARNINGS @@ -2666,7 +2666,7 @@ static void update_stream_timings(AVFormatContext *ic) duration = FFMAX(duration, duration1); } } - if (start_time == INT64_MAX || (start_time > start_time_text && start_time - start_time_text < AV_TIME_BASE)) + if (start_time == INT64_MAX || (start_time > start_time_text && start_time - (uint64_t)start_time_text < AV_TIME_BASE)) start_time = start_time_text; else if (start_time > start_time_text) av_log(ic, AV_LOG_VERBOSE, "Ignoring outlier non primary stream starttime %f\n", start_time_text / (float)AV_TIME_BASE); @@ -3869,7 +3869,7 @@ FF_ENABLE_DEPRECATION_WARNINGS break; } if (pkt->duration) { - if (avctx->codec_type == AVMEDIA_TYPE_SUBTITLE && pkt->pts != AV_NOPTS_VALUE && pkt->pts >= st->start_time) { + if (avctx->codec_type == AVMEDIA_TYPE_SUBTITLE && pkt->pts != AV_NOPTS_VALUE && st->start_time != AV_NOPTS_VALUE && pkt->pts >= st->start_time) { st->info->codec_info_duration = FFMIN(pkt->pts - st->start_time, st->info->codec_info_duration + pkt->duration); } else st->info->codec_info_duration += pkt->duration; @@ -4797,6 +4797,40 @@ void av_url_split(char *proto, int proto_size, } } +int ff_mkdir_p(const char *path) +{ + int ret = 0; + char *temp = av_strdup(path); + char *pos = temp; + char tmp_ch = '\0'; + + if (!path || !temp) { + return -1; + } + + if (!av_strncasecmp(temp, "/", 1) || !av_strncasecmp(temp, "\\", 1)) { + pos++; + } else if (!av_strncasecmp(temp, "./", 2) || !av_strncasecmp(temp, ".\\", 2)) { + pos += 2; + } + + for ( ; *pos != '\0'; ++pos) { + if (*pos == '/' || *pos == '\\') { + tmp_ch = *pos; + *pos = '\0'; + ret = mkdir(temp, 0755); + *pos = tmp_ch; + } + } + + if ((*(pos - 1) != '/') || (*(pos - 1) != '\\')) { + ret = mkdir(temp, 0755); + } + + av_free(temp); + return ret; +} + char *ff_data_to_hex(char *buff, const uint8_t *src, int s, int lowercase) { int i; diff --git a/chromium/third_party/ffmpeg/libavformat/version.h b/chromium/third_party/ffmpeg/libavformat/version.h index 57b6599e71b..7032e21adcd 100644 --- a/chromium/third_party/ffmpeg/libavformat/version.h +++ b/chromium/third_party/ffmpeg/libavformat/version.h @@ -32,8 +32,8 @@ // Major bumping may affect Ticket5467, 5421, 5451(compatibility with Chromium) // Also please add any ticket numbers that you believe might be affected here #define LIBAVFORMAT_VERSION_MAJOR 58 -#define LIBAVFORMAT_VERSION_MINOR 17 -#define LIBAVFORMAT_VERSION_MICRO 101 +#define LIBAVFORMAT_VERSION_MINOR 18 +#define LIBAVFORMAT_VERSION_MICRO 103 #define LIBAVFORMAT_VERSION_INT AV_VERSION_INT(LIBAVFORMAT_VERSION_MAJOR, \ LIBAVFORMAT_VERSION_MINOR, \ @@ -70,6 +70,9 @@ #ifndef FF_API_HLS_WRAP #define FF_API_HLS_WRAP (LIBAVFORMAT_VERSION_MAJOR < 59) #endif +#ifndef FF_API_HLS_USE_LOCALTIME +#define FF_API_HLS_USE_LOCALTIME (LIBAVFORMAT_VERSION_MAJOR < 59) +#endif #ifndef FF_API_LAVF_KEEPSIDE_FLAG #define FF_API_LAVF_KEEPSIDE_FLAG (LIBAVFORMAT_VERSION_MAJOR < 59) #endif diff --git a/chromium/third_party/ffmpeg/libavformat/vpcc.c b/chromium/third_party/ffmpeg/libavformat/vpcc.c index 79514483af4..e0b7f288a65 100644 --- a/chromium/third_party/ffmpeg/libavformat/vpcc.c +++ b/chromium/third_party/ffmpeg/libavformat/vpcc.c @@ -81,33 +81,33 @@ static int get_vp9_level(AVCodecParameters *par, AVRational *frame_rate) { if (picture_size <= 0) { return 0; } else if (sample_rate <= 829440 && picture_size <= 36864) { - return 0x10; + return 10; } else if (sample_rate <= 2764800 && picture_size <= 73728) { - return 0x11; + return 11; } else if (sample_rate <= 4608000 && picture_size <= 122880) { - return 0x20; + return 20; } else if (sample_rate <= 9216000 && picture_size <= 245760) { - return 0x21; + return 21; } else if (sample_rate <= 20736000 && picture_size <= 552960) { - return 0x30; + return 30; } else if (sample_rate <= 36864000 && picture_size <= 983040) { - return 0x31; + return 31; } else if (sample_rate <= 83558400 && picture_size <= 2228224) { - return 0x40; + return 40; } else if (sample_rate <= 160432128 && picture_size <= 2228224) { - return 0x41; + return 41; } else if (sample_rate <= 311951360 && picture_size <= 8912896) { - return 0x50; + return 50; } else if (sample_rate <= 588251136 && picture_size <= 8912896) { - return 0x51; + return 51; } else if (sample_rate <= 1176502272 && picture_size <= 8912896) { - return 0x52; + return 52; } else if (sample_rate <= 1176502272 && picture_size <= 35651584) { - return 0x60; + return 60; } else if (sample_rate <= 2353004544 && picture_size <= 35651584) { - return 0x61; + return 61; } else if (sample_rate <= 4706009088 && picture_size <= 35651584) { - return 0x62; + return 62; } else { return 0; } diff --git a/chromium/third_party/ffmpeg/libavformat/webvttenc.c b/chromium/third_party/ffmpeg/libavformat/webvttenc.c index 4827de05d5a..61b7f546229 100644 --- a/chromium/third_party/ffmpeg/libavformat/webvttenc.c +++ b/chromium/third_party/ffmpeg/libavformat/webvttenc.c @@ -38,7 +38,7 @@ static void webvtt_write_time(AVIOContext *pb, int64_t millisec) min -= 60 * hour; if (hour > 0) - avio_printf(pb, "%"PRId64":", hour); + avio_printf(pb, "%02"PRId64":", hour); avio_printf(pb, "%02"PRId64":%02"PRId64".%03"PRId64"", min, sec, millisec); } |