[FFmpeg-cvslog] ffmpeg: make sure packets put into the muxing FIFO are refcounted
ffmpeg | branch: master | wm4 | Wed Feb 8 09:53:26 2017 +0100| [33580a8625c77591919b6155a48da04dccc8d398] | committer: wm4 ffmpeg: make sure packets put into the muxing FIFO are refcounted Some callers (like do_subtitle_out()) call this with an AVPacket that is not refcounted. This can cause undefined behavior. Calling av_packet_move_ref() does not make a packet refcounted if it isn't yet. (And it can't be made to, because it always succeeds, and can't return ENOMEM.) Call av_packet_ref() instead to make sure it's refcounted. I couldn't find a case that is fixed by this with the current code. But it will fix the fate-pva-demux test with the later patches applied. Signed-off-by: wm4 > http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=33580a8625c77591919b6155a48da04dccc8d398 --- ffmpeg.c | 7 +-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/ffmpeg.c b/ffmpeg.c index 38395e7..5adec2b 100644 --- a/ffmpeg.c +++ b/ffmpeg.c @@ -654,7 +654,7 @@ static void write_packet(OutputFile *of, AVPacket *pkt, OutputStream *ost) int ret; if (!of->header_written) { -AVPacket tmp_pkt; +AVPacket tmp_pkt = {0}; /* the muxer is not initialized yet, buffer the packet */ if (!av_fifo_space(ost->muxing_queue)) { int new_size = FFMIN(2 * av_fifo_size(ost->muxing_queue), @@ -669,8 +669,11 @@ static void write_packet(OutputFile *of, AVPacket *pkt, OutputStream *ost) if (ret < 0) exit_program(1); } -av_packet_move_ref(&tmp_pkt, pkt); +ret = av_packet_ref(&tmp_pkt, pkt); +if (ret < 0) +exit_program(1); av_fifo_generic_write(ost->muxing_queue, &tmp_pkt, sizeof(tmp_pkt), NULL); +av_packet_unref(pkt); return; } ___ ffmpeg-cvslog mailing list ffmpeg-cvslog@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-cvslog
[FFmpeg-cvslog] ffmpeg: init filtergraphs only after we have a frame on each input
ffmpeg | branch: master | Anton Khirnov | Fri May 27 12:14:33 2016 +0200| [af1761f7b5b1b72197dc40934953b775c2d951cc] | committer: wm4 ffmpeg: init filtergraphs only after we have a frame on each input This makes sure the actual stream parameters are used, which is important mainly for hardware decoding+filtering cases, which would previously require various weird workarounds to handle the fact that a fake software graph has to be constructed, but never used. This should also improve behaviour in rare cases where avformat_find_stream_info() does not provide accurate information. This merges Libav commit a3a0230. It was previously skipped. The code in flush_encoders() which sets up a "fake" format wasn't in Libav. I'm not sure if it's a good idea, but it tends to give behavior closer to the old one in certain corner cases. The vp8-size-change gives different result, because now the size of the first frame is used. libavformat reported the size of the largest frame for some reason. The exr tests now use the sample aspect ratio of the first frame. For some reason libavformat determines 0/1 as aspect ratio, while the decoder returns the correct one. The ffm and mxf tests change the field_order values. I'm assuming another libavformat/decoding mismatch. Signed-off-by: wm4 > http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=af1761f7b5b1b72197dc40934953b775c2d951cc --- ffmpeg.c | 338 + ffmpeg.h | 17 +- ffmpeg_cuvid.c | 1 - ffmpeg_filter.c| 48 +-- ffmpeg_opt.c | 44 --- ffmpeg_qsv.c | 82 - .../fate/exr-rgb-scanline-pxr24-half-uint32-13x9 | 2 +- .../fate/exr-rgba-scanline-float-half-b44-12x8-l1 | 2 +- .../fate/exr-rgba-scanline-float-half-b44-12x8-l2 | 2 +- .../fate/exr-rgba-scanline-float-half-b44-13x9-l1 | 2 +- .../fate/exr-rgba-scanline-float-half-b44-13x9-l2 | 2 +- .../fate/exr-rgba-scanline-float-half-b44a-12x8-l1 | 2 +- .../fate/exr-rgba-scanline-float-half-b44a-12x8-l2 | 2 +- .../fate/exr-rgba-scanline-float-half-b44a-13x9-l1 | 2 +- .../fate/exr-rgba-scanline-float-half-b44a-13x9-l2 | 2 +- tests/ref/fate/vp8-size-change | 62 ++-- tests/ref/lavf/ffm | 2 +- tests/ref/lavf/mxf | 6 +- 18 files changed, 281 insertions(+), 337 deletions(-) diff --git a/ffmpeg.c b/ffmpeg.c index 983e2fb..88f6834 100644 --- a/ffmpeg.c +++ b/ffmpeg.c @@ -123,6 +123,7 @@ const char *const forced_keyframes_const_names[] = { static void do_video_stats(OutputStream *ost, int frame_size); static int64_t getutime(void); static int64_t getmaxrss(void); +static int ifilter_has_all_input_formats(FilterGraph *fg); static int run_as_daemon = 0; static int nb_frames_dup = 0; @@ -472,6 +473,13 @@ static void ffmpeg_cleanup(int ret) FilterGraph *fg = filtergraphs[i]; avfilter_graph_free(&fg->graph); for (j = 0; j < fg->nb_inputs; j++) { +while (av_fifo_size(fg->inputs[j]->frame_queue)) { +AVFrame *frame; +av_fifo_generic_read(fg->inputs[j]->frame_queue, &frame, + sizeof(frame), NULL); +av_frame_free(&frame); +} +av_fifo_free(fg->inputs[j]->frame_queue); av_buffer_unref(&fg->inputs[j]->hw_frames_ctx); av_freep(&fg->inputs[j]->name); av_freep(&fg->inputs[j]); @@ -1377,6 +1385,8 @@ static void do_video_stats(OutputStream *ost, int frame_size) } } +static int init_output_stream(OutputStream *ost, char *error, int error_len); + static void finish_output_stream(OutputStream *ost) { OutputFile *of = output_files[ost->file_index]; @@ -1409,10 +1419,20 @@ static int reap_filters(int flush) AVCodecContext *enc = ost->enc_ctx; int ret = 0; -if (!ost->filter) +if (!ost->filter || !ost->filter->graph->graph) continue; filter = ost->filter->filter; +if (!ost->initialized) { +char error[1024]; +ret = init_output_stream(ost, error, sizeof(error)); +if (ret < 0) { +av_log(NULL, AV_LOG_ERROR, "Error initializing output stream %d:%d -- %s\n", + ost->file_index, ost->index, error); +exit_program(1); +} +} + if (!ost->filtered_frame && !(ost->filtered_frame = av_frame_alloc())) { return AVERROR(ENOMEM); } @@ -1813,6 +1833,54 @@ static void flush_encoders(void) if (!ost->encoding_needed) continue; +// Try to enable encoding with no input frames. +// Maybe we should just let encoding fail instead. +if (!
[FFmpeg-cvslog] ffmpeg: restructure sending EOF to filters
ffmpeg | branch: master | Anton Khirnov | Mon Jun 27 19:03:42 2016 +0200| [76e13bdeaabc7ec49322b3a118dc4805153e0401] | committer: wm4 ffmpeg: restructure sending EOF to filters Be more careful when an input stream encounters EOF when its filtergraph has not been configured yet. The current code would immediately mark the corresponding output streams as finished, while there may still be buffered frames waiting for frames to appear on other filtergraph inputs. This should fix the random FATE failures for complex filtergraph tests after a3a0230a9870b9018dc7415ae5872784d524cfe5 This merges Libav commit 94ebf55. It was previously skipped. This is the last filter init related Libav commit that was skipped, so this also removes the commits from doc/libav-merge.txt. Signed-off-by: wm4 > http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=76e13bdeaabc7ec49322b3a118dc4805153e0401 --- doc/libav-merge.txt | 1 - ffmpeg.c| 43 --- ffmpeg.h| 2 ++ ffmpeg_filter.c | 9 + 4 files changed, 43 insertions(+), 12 deletions(-) diff --git a/doc/libav-merge.txt b/doc/libav-merge.txt index 23b48d1..39d846f 100644 --- a/doc/libav-merge.txt +++ b/doc/libav-merge.txt @@ -95,7 +95,6 @@ Stuff that didn't reach the codebase: - 0cef06df0 checkasm: add HEVC MC tests - e7078e842 hevcdsp: add x86 SIMD for MC - QSV scaling filter (62c58c5) -- ffmpeg.c filter init decoupling (3e265ca,a3a0230,d2e56cf,94ebf55) Collateral damage that needs work locally: -- diff --git a/ffmpeg.c b/ffmpeg.c index f52d3e2..275894d 100644 --- a/ffmpeg.c +++ b/ffmpeg.c @@ -2197,6 +2197,34 @@ static int ifilter_send_frame(InputFilter *ifilter, AVFrame *frame) return 0; } +static int ifilter_send_eof(InputFilter *ifilter) +{ +int i, j, ret; + +ifilter->eof = 1; + +if (ifilter->filter) { +ret = av_buffersrc_add_frame_flags(ifilter->filter, NULL, AV_BUFFERSRC_FLAG_PUSH); +if (ret < 0) +return ret; +} else { +// the filtergraph was never configured +FilterGraph *fg = ifilter->graph; +for (i = 0; i < fg->nb_inputs; i++) +if (!fg->inputs[i]->eof) +break; +if (i == fg->nb_inputs) { +// All the input streams have finished without the filtergraph +// ever being configured. +// Mark the output streams as finished. +for (j = 0; j < fg->nb_outputs; j++) +finish_output_stream(fg->outputs[j]->ost); +} +} + +return 0; +} + // This does not quite work like avcodec_decode_audio4/avcodec_decode_video2. // There is the following difference: if you got a frame, you must call // it again with pkt=NULL. pkt==NULL is treated differently from pkt.size==0 @@ -2498,18 +2526,11 @@ out: static int send_filter_eof(InputStream *ist) { -int i, j, ret; +int i, ret; for (i = 0; i < ist->nb_filters; i++) { -if (ist->filters[i]->filter) { -ret = av_buffersrc_add_frame(ist->filters[i]->filter, NULL); -if (ret < 0) -return ret; -} else { -// the filtergraph was never configured -FilterGraph *fg = ist->filters[i]->graph; -for (j = 0; j < fg->nb_outputs; j++) -finish_output_stream(fg->outputs[j]->ost); -} +ret = ifilter_send_eof(ist->filters[i]); +if (ret < 0) +return ret; } return 0; } diff --git a/ffmpeg.h b/ffmpeg.h index 56e35eb..5d20d45 100644 --- a/ffmpeg.h +++ b/ffmpeg.h @@ -248,6 +248,8 @@ typedef struct InputFilter { uint64_t channel_layout; AVBufferRef *hw_frames_ctx; + +int eof; } InputFilter; typedef struct OutputFilter { diff --git a/ffmpeg_filter.c b/ffmpeg_filter.c index 4d9a4e2..816c906 100644 --- a/ffmpeg_filter.c +++ b/ffmpeg_filter.c @@ -1128,6 +1128,15 @@ int configure_filtergraph(FilterGraph *fg) } } +/* send the EOFs for the finished inputs */ +for (i = 0; i < fg->nb_inputs; i++) { +if (fg->inputs[i]->eof) { +ret = av_buffersrc_add_frame(fg->inputs[i]->filter, NULL); +if (ret < 0) +return ret; +} +} + return 0; } ___ ffmpeg-cvslog mailing list ffmpeg-cvslog@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-cvslog
[FFmpeg-cvslog] ffmpeg: move flushing the queued frames to configure_filtergraph()
ffmpeg | branch: master | Anton Khirnov | Mon Jun 27 18:59:23 2016 +0200| [cb884f8d7e3b55cddf8a4568bddb1e5f5f86b811] | committer: wm4 ffmpeg: move flushing the queued frames to configure_filtergraph() This is a more appropriate place for it, and will also be useful in the following commit. This merges Libav commit d2e56cf. It was previously skipped. Signed-off-by: wm4 > http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=cb884f8d7e3b55cddf8a4568bddb1e5f5f86b811 --- ffmpeg.c| 11 --- ffmpeg_filter.c | 11 +++ 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/ffmpeg.c b/ffmpeg.c index 88f6834..f52d3e2 100644 --- a/ffmpeg.c +++ b/ffmpeg.c @@ -2186,17 +2186,6 @@ static int ifilter_send_frame(InputFilter *ifilter, AVFrame *frame) av_log(NULL, AV_LOG_ERROR, "Error reinitializing filters!\n"); return ret; } - -for (i = 0; i < fg->nb_inputs; i++) { -while (av_fifo_size(fg->inputs[i]->frame_queue)) { -AVFrame *tmp; -av_fifo_generic_read(fg->inputs[i]->frame_queue, &tmp, sizeof(tmp), NULL); -ret = av_buffersrc_add_frame(fg->inputs[i]->filter, tmp); -av_frame_free(&tmp); -if (ret < 0) -return ret; -} -} } ret = av_buffersrc_add_frame_flags(ifilter->filter, frame, AV_BUFFERSRC_FLAG_PUSH); diff --git a/ffmpeg_filter.c b/ffmpeg_filter.c index f21a8c8..4d9a4e2 100644 --- a/ffmpeg_filter.c +++ b/ffmpeg_filter.c @@ -1117,6 +1117,17 @@ int configure_filtergraph(FilterGraph *fg) ost->enc_ctx->frame_size); } +for (i = 0; i < fg->nb_inputs; i++) { +while (av_fifo_size(fg->inputs[i]->frame_queue)) { +AVFrame *tmp; +av_fifo_generic_read(fg->inputs[i]->frame_queue, &tmp, sizeof(tmp), NULL); +ret = av_buffersrc_add_frame(fg->inputs[i]->filter, tmp); +av_frame_free(&tmp); +if (ret < 0) +return ret; +} +} + return 0; } ___ ffmpeg-cvslog mailing list ffmpeg-cvslog@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-cvslog
[FFmpeg-cvslog] ffmpeg: do packet ts rescaling in write_packet()
ffmpeg | branch: master | Anton Khirnov | Fri May 27 12:04:29 2016 +0200| [4ee5aed122ba7d289c1686eca6eba161d5d62304] | committer: wm4 ffmpeg: do packet ts rescaling in write_packet() This will be useful in the following commit, after which the muxer timebase is not always available when encoding. This merges Libav commit 3e265ca. It was previously skipped. There are some changes with how/when the mux_timebase field is set, because the Libav approach often causes a too imprecise time base to be set. This is hard, because the muxer's write_header function can readjust the timebase, at which point we might already have encoded packets buffered. (It might be better to buffer them after the encoder, instead of after all the timestamp handling logic before muxing.) The two FATE tests change because the output time base is raised for subtitles. (Needed to avoid certain rounding issues in other cases.) Includes a minor merge fix by Mark Thompson, and avconv: Move rescale to stream timebase before monotonisation also by Mark Thompson . Signed-off-by: wm4 > http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=4ee5aed122ba7d289c1686eca6eba161d5d62304 --- ffmpeg.c | 51 ++- ffmpeg.h | 2 + tests/ref/fate/binsub-movtextenc | 2 +- tests/ref/fate/sub2video | 88 4 files changed, 78 insertions(+), 65 deletions(-) diff --git a/ffmpeg.c b/ffmpeg.c index 5adec2b..983e2fb 100644 --- a/ffmpeg.c +++ b/ffmpeg.c @@ -713,10 +713,12 @@ static void write_packet(OutputFile *of, AVPacket *pkt, OutputStream *ost) if (pkt->duration > 0) av_log(NULL, AV_LOG_WARNING, "Overriding packet duration by frame rate, this should not happen\n"); pkt->duration = av_rescale_q(1, av_inv_q(ost->frame_rate), - ost->st->time_base); + ost->mux_timebase); } } +av_packet_rescale_ts(pkt, ost->mux_timebase, ost->st->time_base); + if (!(s->oformat->flags & AVFMT_NOTIMESTAMPS)) { if (pkt->dts != AV_NOPTS_VALUE && pkt->pts != AV_NOPTS_VALUE && @@ -907,13 +909,13 @@ static void do_audio_out(OutputFile *of, OutputStream *ost, update_benchmark("encode_audio %d.%d", ost->file_index, ost->index); -av_packet_rescale_ts(&pkt, enc->time_base, ost->st->time_base); +av_packet_rescale_ts(&pkt, enc->time_base, ost->mux_timebase); if (debug_ts) { av_log(NULL, AV_LOG_INFO, "encoder -> type:audio " "pkt_pts:%s pkt_pts_time:%s pkt_dts:%s pkt_dts_time:%s\n", - av_ts2str(pkt.pts), av_ts2timestr(pkt.pts, &ost->st->time_base), - av_ts2str(pkt.dts), av_ts2timestr(pkt.dts, &ost->st->time_base)); + av_ts2str(pkt.pts), av_ts2timestr(pkt.pts, &enc->time_base), + av_ts2str(pkt.dts), av_ts2timestr(pkt.dts, &enc->time_base)); } output_packet(of, &pkt, ost); @@ -993,15 +995,15 @@ static void do_subtitle_out(OutputFile *of, av_init_packet(&pkt); pkt.data = subtitle_out; pkt.size = subtitle_out_size; -pkt.pts = av_rescale_q(sub->pts, AV_TIME_BASE_Q, ost->st->time_base); -pkt.duration = av_rescale_q(sub->end_display_time, (AVRational){ 1, 1000 }, ost->st->time_base); +pkt.pts = av_rescale_q(sub->pts, AV_TIME_BASE_Q, ost->mux_timebase); +pkt.duration = av_rescale_q(sub->end_display_time, (AVRational){ 1, 1000 }, ost->mux_timebase); if (enc->codec_id == AV_CODEC_ID_DVB_SUBTITLE) { /* XXX: the pts correction is handled here. Maybe handling it in the codec would be better */ if (i == 0) -pkt.pts += 90 * sub->start_display_time; +pkt.pts += av_rescale_q(sub->start_display_time, (AVRational){ 1, 1000 }, ost->mux_timebase); else -pkt.pts += 90 * sub->end_display_time; +pkt.pts += av_rescale_q(sub->end_display_time, (AVRational){ 1, 1000 }, ost->mux_timebase); } pkt.dts = pkt.pts; output_packet(of, &pkt, ost); @@ -1187,7 +1189,7 @@ static void do_video_out(OutputFile *of, mux_par->field_order = AV_FIELD_PROGRESSIVE; pkt.data = (uint8_t *)in_picture; pkt.size = sizeof(AVPicture); -pkt.pts= av_rescale_q(in_picture->pts, enc->time_base, ost->st->time_base); +pkt.pts= av_rescale_q(in_picture->pts, enc->time_base, ost->mux_timebase); pkt.flags |= AV_PKT_FLAG_KEY; output_packet(of, &pkt, ost); @@ -1283,13 +1285,13 @@ static void do_video_out(OutputFile *of, if (pkt.pts == AV_NOPTS_VALUE && !(enc->codec->capabilities & AV_CODEC_CAP_DELAY)) pkt.pts = ost->sync_opts; -av_packet_rescale_ts(&pk
[FFmpeg-cvslog] ffmpeg: delay processing of subtitles before filters are initialized
ffmpeg | branch: master | wm4 | Thu Mar 2 16:01:01 2017 +0100| [7dd44cde2abb156710f26a08b6cd6c8dd9a9793d] | committer: wm4 ffmpeg: delay processing of subtitles before filters are initialized If a subtitle packet came before the first video frame could be fully decoded, the subtitle packet would get discarded. This puts the subtitle into a queue instead, and processes it once the attached filter graph is initialized. > http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=7dd44cde2abb156710f26a08b6cd6c8dd9a9793d --- ffmpeg.c| 31 --- ffmpeg.h| 3 +++ ffmpeg_filter.c | 13 + 3 files changed, 44 insertions(+), 3 deletions(-) diff --git a/ffmpeg.c b/ffmpeg.c index 6e57524..db7e8cd 100644 --- a/ffmpeg.c +++ b/ffmpeg.c @@ -226,7 +226,7 @@ static void sub2video_push_ref(InputStream *ist, int64_t pts) AV_BUFFERSRC_FLAG_PUSH); } -static void sub2video_update(InputStream *ist, AVSubtitle *sub) +void sub2video_update(InputStream *ist, AVSubtitle *sub) { AVFrame *frame = ist->sub2video.frame; int8_t *dst; @@ -480,6 +480,15 @@ static void ffmpeg_cleanup(int ret) av_frame_free(&frame); } av_fifo_free(fg->inputs[j]->frame_queue); +if (fg->inputs[j]->ist->sub2video.sub_queue) { +while (av_fifo_size(fg->inputs[j]->ist->sub2video.sub_queue)) { +AVSubtitle sub; + av_fifo_generic_read(fg->inputs[j]->ist->sub2video.sub_queue, + &sub, sizeof(sub), NULL); +avsubtitle_free(&sub); +} +av_fifo_free(fg->inputs[j]->ist->sub2video.sub_queue); +} av_buffer_unref(&fg->inputs[j]->hw_frames_ctx); av_freep(&fg->inputs[j]->name); av_freep(&fg->inputs[j]); @@ -2468,6 +2477,7 @@ fail: static int transcode_subtitles(InputStream *ist, AVPacket *pkt, int *got_output) { AVSubtitle subtitle; +int free_sub = 1; int i, ret = avcodec_decode_subtitle2(ist->dec_ctx, &subtitle, got_output, pkt); @@ -2502,7 +2512,21 @@ static int transcode_subtitles(InputStream *ist, AVPacket *pkt, int *got_output) if (!*got_output) return ret; -sub2video_update(ist, &subtitle); +if (ist->sub2video.frame) { +sub2video_update(ist, &subtitle); +} else if (ist->nb_filters) { +if (!ist->sub2video.sub_queue) +ist->sub2video.sub_queue = av_fifo_alloc(8 * sizeof(AVSubtitle)); +if (!ist->sub2video.sub_queue) +exit_program(1); +if (!av_fifo_space(ist->sub2video.sub_queue)) { +ret = av_fifo_realloc2(ist->sub2video.sub_queue, 2 * av_fifo_size(ist->sub2video.sub_queue)); +if (ret < 0) +exit_program(1); +} +av_fifo_generic_write(ist->sub2video.sub_queue, &subtitle, sizeof(subtitle), NULL); +free_sub = 0; +} if (!subtitle.num_rects) goto out; @@ -2520,7 +2544,8 @@ static int transcode_subtitles(InputStream *ist, AVPacket *pkt, int *got_output) } out: -avsubtitle_free(&subtitle); +if (free_sub) +avsubtitle_free(&subtitle); return ret; } diff --git a/ffmpeg.h b/ffmpeg.h index 59f6cb3..06a1251 100644 --- a/ffmpeg.h +++ b/ffmpeg.h @@ -337,6 +337,7 @@ typedef struct InputStream { struct sub2video { int64_t last_pts; int64_t end_pts; +AVFifoBuffer *sub_queue;///< queue of AVSubtitle* before filter init AVFrame *frame; int w, h; } sub2video; @@ -636,6 +637,8 @@ int filtergraph_is_simple(FilterGraph *fg); int init_simple_filtergraph(InputStream *ist, OutputStream *ost); int init_complex_filtergraph(FilterGraph *fg); +void sub2video_update(InputStream *ist, AVSubtitle *sub); + int ifilter_parameters_from_frame(InputFilter *ifilter, const AVFrame *frame); int ffmpeg_parse_options(int argc, char **argv); diff --git a/ffmpeg_filter.c b/ffmpeg_filter.c index 816c906..da2a46d 100644 --- a/ffmpeg_filter.c +++ b/ffmpeg_filter.c @@ -1137,6 +1137,19 @@ int configure_filtergraph(FilterGraph *fg) } } +/* process queued up subtitle packets */ +for (i = 0; i < fg->nb_inputs; i++) { +InputStream *ist = fg->inputs[i]->ist; +if (ist->sub2video.sub_queue && ist->sub2video.frame) { +while (av_fifo_size(ist->sub2video.sub_queue)) { +AVSubtitle tmp; +av_fifo_generic_read(ist->sub2video.sub_queue, &tmp, sizeof(tmp), NULL); +sub2video_update(ist, &tmp); +avsubtitle_free(&tmp); +} +} +} + return 0; } ___ ffmpeg-cvslog mailing list ffmpeg-cvslog@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-cvslog
[FFmpeg-cvslog] ffmpeg: properly cleanup filter graph on init failure
ffmpeg | branch: master | wm4 | Thu Mar 2 19:14:58 2017 +0100| [16abc10b0997c76cbb0c0ebedc49f6bc21452f9d] | committer: wm4 ffmpeg: properly cleanup filter graph on init failure The filter field is often used to check whether a filter is configured. If configuring the filter actually fails somewhere in the middle of it, these fields could still be set to non-NULL, which lead to other code accessing the half-configured filter graph, which in turn could lead to crashes within libavfilter. Solve this by properly resetting all fields. This was triggered by a fuzzed sample after the recent changes. It's unknown whether this behavior could be triggered before that. > http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=16abc10b0997c76cbb0c0ebedc49f6bc21452f9d --- ffmpeg_filter.c | 32 1 file changed, 24 insertions(+), 8 deletions(-) diff --git a/ffmpeg_filter.c b/ffmpeg_filter.c index da2a46d..7f249c2 100644 --- a/ffmpeg_filter.c +++ b/ffmpeg_filter.c @@ -984,6 +984,16 @@ static int configure_input_filter(FilterGraph *fg, InputFilter *ifilter, } } +static void cleanup_filtergraph(FilterGraph *fg) +{ +int i; +for (i = 0; i < fg->nb_outputs; i++) +fg->outputs[i]->filter = (AVFilterContext *)NULL; +for (i = 0; i < fg->nb_inputs; i++) +fg->inputs[i]->filter = (AVFilterContext *)NULL; +avfilter_graph_free(&fg->graph); +} + int configure_filtergraph(FilterGraph *fg) { AVFilterInOut *inputs, *outputs, *cur; @@ -991,7 +1001,7 @@ int configure_filtergraph(FilterGraph *fg) const char *graph_desc = simple ? fg->outputs[0]->ost->avfilter : fg->graph_desc; -avfilter_graph_free(&fg->graph); +cleanup_filtergraph(fg); if (!(fg->graph = avfilter_graph_alloc())) return AVERROR(ENOMEM); @@ -1037,7 +1047,7 @@ int configure_filtergraph(FilterGraph *fg) } if ((ret = avfilter_graph_parse2(fg->graph, graph_desc, &inputs, &outputs)) < 0) -return ret; +goto fail; if (hw_device_ctx) { for (i = 0; i < fg->graph->nb_filters; i++) { @@ -1067,14 +1077,15 @@ int configure_filtergraph(FilterGraph *fg) " However, it had %s input(s) and %s output(s)." " Please adjust, or use a complex filtergraph (-filter_complex) instead.\n", graph_desc, num_inputs, num_outputs); -return AVERROR(EINVAL); +ret = AVERROR(EINVAL); +goto fail; } for (cur = inputs, i = 0; cur; cur = cur->next, i++) if ((ret = configure_input_filter(fg, fg->inputs[i], cur)) < 0) { avfilter_inout_free(&inputs); avfilter_inout_free(&outputs); -return ret; +goto fail; } avfilter_inout_free(&inputs); @@ -1083,7 +1094,7 @@ int configure_filtergraph(FilterGraph *fg) avfilter_inout_free(&outputs); if ((ret = avfilter_graph_config(fg->graph, NULL)) < 0) -return ret; +goto fail; /* limit the lists of allowed formats to the ones selected, to * make sure they stay the same if the filtergraph is reconfigured later */ @@ -1109,7 +1120,8 @@ int configure_filtergraph(FilterGraph *fg) complex filter graphs are initialized earlier */ av_log(NULL, AV_LOG_ERROR, "Encoder (codec %s) not found for output stream #%d:%d\n", avcodec_get_name(ost->st->codecpar->codec_id), ost->file_index, ost->index); -return AVERROR(EINVAL); +ret = AVERROR(EINVAL); +goto fail; } if (ost->enc->type == AVMEDIA_TYPE_AUDIO && !(ost->enc->capabilities & AV_CODEC_CAP_VARIABLE_FRAME_SIZE)) @@ -1124,7 +1136,7 @@ int configure_filtergraph(FilterGraph *fg) ret = av_buffersrc_add_frame(fg->inputs[i]->filter, tmp); av_frame_free(&tmp); if (ret < 0) -return ret; +goto fail; } } @@ -1133,7 +1145,7 @@ int configure_filtergraph(FilterGraph *fg) if (fg->inputs[i]->eof) { ret = av_buffersrc_add_frame(fg->inputs[i]->filter, NULL); if (ret < 0) -return ret; +goto fail; } } @@ -1151,6 +1163,10 @@ int configure_filtergraph(FilterGraph *fg) } return 0; + +fail: +cleanup_filtergraph(fg); +return ret; } int ifilter_parameters_from_frame(InputFilter *ifilter, const AVFrame *frame) ___ ffmpeg-cvslog mailing list ffmpeg-cvslog@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-cvslog
[FFmpeg-cvslog] ffmpeg_cuvid: adapt for recent filter graph initialization changes
ffmpeg | branch: master | Timo Rothenpieler | Thu Feb 9 21:33:51 2017 +0100| [736f4af4fea44d15c5d08558d3fe6f1a0fc98173] | committer: wm4 ffmpeg_cuvid: adapt for recent filter graph initialization changes > http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=736f4af4fea44d15c5d08558d3fe6f1a0fc98173 --- ffmpeg.c | 13 -- ffmpeg.h | 1 - ffmpeg_cuvid.c | 141 - 3 files changed, 30 insertions(+), 125 deletions(-) diff --git a/ffmpeg.c b/ffmpeg.c index 275894d..6e57524 100644 --- a/ffmpeg.c +++ b/ffmpeg.c @@ -3546,19 +3546,6 @@ static int transcode_init(void) input_streams[j + ifile->ist_index]->start = av_gettime_relative(); } -/* hwaccel transcoding */ -for (i = 0; i < nb_output_streams; i++) { -ost = output_streams[i]; - -if (!ost->stream_copy) { - -#if CONFIG_CUVID -if (cuvid_transcode_init(ost)) -exit_program(1); -#endif -} -} - /* init input streams */ for (i = 0; i < nb_input_streams; i++) if ((ret = init_input_stream(i, error, sizeof(error))) < 0) { diff --git a/ffmpeg.h b/ffmpeg.h index 5d20d45..59f6cb3 100644 --- a/ffmpeg.h +++ b/ffmpeg.h @@ -648,6 +648,5 @@ int qsv_init(AVCodecContext *s); int vaapi_decode_init(AVCodecContext *avctx); int vaapi_device_init(const char *device); int cuvid_init(AVCodecContext *s); -int cuvid_transcode_init(OutputStream *ost); #endif /* FFMPEG_H */ diff --git a/ffmpeg_cuvid.c b/ffmpeg_cuvid.c index 4654079..3ff3b40 100644 --- a/ffmpeg_cuvid.c +++ b/ffmpeg_cuvid.c @@ -17,138 +17,57 @@ */ #include "libavutil/hwcontext.h" +#include "libavutil/pixdesc.h" #include "ffmpeg.h" -typedef struct CUVIDContext { -AVBufferRef *hw_frames_ctx; -} CUVIDContext; - static void cuvid_uninit(AVCodecContext *avctx) { -InputStream *ist = avctx->opaque; -CUVIDContext *ctx = ist->hwaccel_ctx; - -if (ctx) { -av_buffer_unref(&ctx->hw_frames_ctx); -av_freep(&ctx); -} - +InputStream *ist = avctx->opaque; av_buffer_unref(&ist->hw_frames_ctx); - -ist->hwaccel_ctx = 0; -ist->hwaccel_uninit = 0; } int cuvid_init(AVCodecContext *avctx) { -InputStream *ist = avctx->opaque; -CUVIDContext *ctx = ist->hwaccel_ctx; - -av_log(NULL, AV_LOG_TRACE, "Initializing cuvid hwaccel\n"); - -if (!ctx) { -av_log(NULL, AV_LOG_ERROR, "CUVID transcoding is not initialized. " - "-hwaccel cuvid should only be used for one-to-one CUVID transcoding " - "with no (software) filters.\n"); -return AVERROR(EINVAL); -} - -return 0; -} - -int cuvid_transcode_init(OutputStream *ost) -{ -InputStream *ist; -const enum AVPixelFormat *pix_fmt; -AVHWFramesContext *hwframe_ctx; -AVBufferRef *device_ref = NULL; -CUVIDContext *ctx = NULL; -int ret = 0; - -av_log(NULL, AV_LOG_TRACE, "Initializing cuvid transcoding\n"); +InputStream *ist = avctx->opaque; +AVHWFramesContext *frames_ctx; +int ret; -if (ost->source_index < 0) -return 0; +av_log(avctx, AV_LOG_VERBOSE, "Initializing cuvid hwaccel\n"); -ist = input_streams[ost->source_index]; - -/* check if the encoder supports CUVID */ -if (!ost->enc->pix_fmts) -goto cancel; -for (pix_fmt = ost->enc->pix_fmts; *pix_fmt != AV_PIX_FMT_NONE; pix_fmt++) -if (*pix_fmt == AV_PIX_FMT_CUDA) -break; -if (*pix_fmt == AV_PIX_FMT_NONE) -goto cancel; - -/* check if the decoder supports CUVID */ -if (ist->hwaccel_id != HWACCEL_CUVID || !ist->dec || !ist->dec->pix_fmts) -goto cancel; -for (pix_fmt = ist->dec->pix_fmts; *pix_fmt != AV_PIX_FMT_NONE; pix_fmt++) -if (*pix_fmt == AV_PIX_FMT_CUDA) -break; -if (*pix_fmt == AV_PIX_FMT_NONE) -goto cancel; - -av_log(NULL, AV_LOG_VERBOSE, "Setting up CUVID transcoding\n"); - -if (ist->hwaccel_ctx) { -ctx = ist->hwaccel_ctx; -} else { -ctx = av_mallocz(sizeof(*ctx)); -if (!ctx) { -ret = AVERROR(ENOMEM); -goto error; +if (!hw_device_ctx) { +ret = av_hwdevice_ctx_create(&hw_device_ctx, AV_HWDEVICE_TYPE_CUDA, + ist->hwaccel_device, NULL, 0); +if (ret < 0) { +av_log(avctx, AV_LOG_ERROR, "Error creating a CUDA device\n"); +return ret; } } -if (!ctx->hw_frames_ctx) { -ret = av_hwdevice_ctx_create(&device_ref, AV_HWDEVICE_TYPE_CUDA, - ist->hwaccel_device, NULL, 0); -if (ret < 0) -goto error; +av_buffer_unref(&ist->hw_frames_ctx); +ist->hw_frames_ctx = av_hwframe_ctx_alloc(hw_device_ctx); +if (!ist->hw_frames_ctx) { +av_log(avctx, AV_LOG_ERROR, "Error creating a CUDA frames context\n"); +return AVERROR(ENOMEM); +} -ctx->
[FFmpeg-cvslog] ffmpeg: fix printing of filter input/output names
ffmpeg | branch: master | wm4 | Wed Feb 8 12:55:58 2017 +0100| [97614a68e474062b46f6fae92bf34976f3436c6a] | committer: wm4 ffmpeg: fix printing of filter input/output names Broken by the previous Libav commit (even in Libav, thus a separate commit). Signed-off-by: wm4 > http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=97614a68e474062b46f6fae92bf34976f3436c6a --- ffmpeg_filter.c | 44 +--- 1 file changed, 21 insertions(+), 23 deletions(-) diff --git a/ffmpeg_filter.c b/ffmpeg_filter.c index 8490f4a..f21a8c8 100644 --- a/ffmpeg_filter.c +++ b/ffmpeg_filter.c @@ -230,6 +230,25 @@ int init_simple_filtergraph(InputStream *ist, OutputStream *ost) return 0; } +static char *describe_filter_link(FilterGraph *fg, AVFilterInOut *inout, int in) +{ +AVFilterContext *ctx = inout->filter_ctx; +AVFilterPad *pads = in ? ctx->input_pads : ctx->output_pads; +int nb_pads = in ? ctx->nb_inputs : ctx->nb_outputs; +AVIOContext *pb; +uint8_t *res = NULL; + +if (avio_open_dyn_buf(&pb) < 0) +exit_program(1); + +avio_printf(pb, "%s", ctx->filter->name); +if (nb_pads > 1) +avio_printf(pb, ":%s", avfilter_pad_get_name(pads, inout->pad_idx)); +avio_w8(pb, 0); +avio_close_dyn_buf(pb, &res); +return res; +} + static void init_input_filter(FilterGraph *fg, AVFilterInOut *in) { InputStream *ist = NULL; @@ -300,6 +319,7 @@ static void init_input_filter(FilterGraph *fg, AVFilterInOut *in) fg->inputs[fg->nb_inputs - 1]->graph = fg; fg->inputs[fg->nb_inputs - 1]->format = -1; fg->inputs[fg->nb_inputs - 1]->type = ist->st->codecpar->codec_type; +fg->inputs[fg->nb_inputs - 1]->name = describe_filter_link(fg, in, 1); fg->inputs[fg->nb_inputs - 1]->frame_queue = av_fifo_alloc(8 * sizeof(AVFrame*)); if (!fg->inputs[fg->nb_inputs - 1]->frame_queue) @@ -338,6 +358,7 @@ int init_complex_filtergraph(FilterGraph *fg) fg->outputs[fg->nb_outputs - 1]->out_tmp = cur; fg->outputs[fg->nb_outputs - 1]->type= avfilter_pad_get_type(cur->filter_ctx->output_pads, cur->pad_idx); +fg->outputs[fg->nb_outputs - 1]->name = describe_filter_link(fg, cur, 0); cur = cur->next; fg->outputs[fg->nb_outputs - 1]->out_tmp->next = NULL; } @@ -643,28 +664,8 @@ static int configure_output_audio_filter(FilterGraph *fg, OutputFilter *ofilter, return 0; } -#define DESCRIBE_FILTER_LINK(f, inout, in) \ -{ \ -AVFilterContext *ctx = inout->filter_ctx; \ -AVFilterPad *pads = in ? ctx->input_pads : ctx->output_pads; \ -int nb_pads = in ? ctx->nb_inputs : ctx->nb_outputs; \ -AVIOContext *pb; \ - \ -if (avio_open_dyn_buf(&pb) < 0)\ -exit_program(1); \ - \ -avio_printf(pb, "%s", ctx->filter->name); \ -if (nb_pads > 1) \ -avio_printf(pb, ":%s", avfilter_pad_get_name(pads, inout->pad_idx));\ -avio_w8(pb, 0);\ -avio_close_dyn_buf(pb, &f->name); \ -} - int configure_output_filter(FilterGraph *fg, OutputFilter *ofilter, AVFilterInOut *out) { -av_freep(&ofilter->name); -DESCRIBE_FILTER_LINK(ofilter, out, 0); - if (!ofilter->ost) { av_log(NULL, AV_LOG_FATAL, "Filter %s has an unconnected output\n", ofilter->name); exit_program(1); @@ -970,9 +971,6 @@ static int configure_input_audio_filter(FilterGraph *fg, InputFilter *ifilter, static int configure_input_filter(FilterGraph *fg, InputFilter *ifilter, AVFilterInOut *in) { -av_freep(&ifilter->name); -DESCRIBE_FILTER_LINK(ifilter, in, 1); - if (!ifilter->ist->dec) { av_log(NULL, AV_LOG_ERROR, "No decoder for stream #%d:%d, filtering impossible\n", ___ ffmpeg-cvslog mailing list ffmpeg-cvslog@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-cvslog
[FFmpeg-cvslog] avcodec/scpr: fix top left prediction for special case when x is 0 for keyframes
ffmpeg | branch: master | Paul B Mahol | Fri Mar 3 12:17:46 2017 +0100| [6d93e7d1a3e607d001141784e66cc73ba1f061c6] | committer: Paul B Mahol avcodec/scpr: fix top left prediction for special case when x is 0 for keyframes Signed-off-by: Paul B Mahol > http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=6d93e7d1a3e607d001141784e66cc73ba1f061c6 --- libavcodec/scpr.c | 35 +-- 1 file changed, 25 insertions(+), 10 deletions(-) diff --git a/libavcodec/scpr.c b/libavcodec/scpr.c index 031ce51..1fc0593 100644 --- a/libavcodec/scpr.c +++ b/libavcodec/scpr.c @@ -295,7 +295,8 @@ static int decompress_i(AVCodecContext *avctx, uint32_t *dst, int linesize) SCPRContext *s = avctx->priv_data; GetByteContext *gb = &s->gb; int cx = 0, cx1 = 0, k = 0, clr = 0; -int run, r, g, b, off, y = 0, x = 0, ret; +int run, r, g, b, off, y = 0, x = 0, z, ret; +unsigned backstep = linesize - avctx->width; const int cxshift = s->cxshift; unsigned lx, ly, ptype; @@ -424,18 +425,25 @@ static int decompress_i(AVCodecContext *avctx, uint32_t *dst, int linesize) while (run-- > 0) { uint8_t *odst = (uint8_t *)dst; -if (y < 1 || y >= avctx->height) +if (y < 1 || y >= avctx->height || +(y == 1 && x == 0)) return AVERROR_INVALIDDATA; +if (x == 0) { +z = backstep; +} else { +z = 0; +} + r = odst[(ly * linesize + lx) * 4] + -odst[((y * linesize + x) + off) * 4 + 4] - -odst[((y * linesize + x) + off) * 4]; +odst[((y * linesize + x) + off - z) * 4 + 4] - +odst[((y * linesize + x) + off - z) * 4]; g = odst[(ly * linesize + lx) * 4 + 1] + -odst[((y * linesize + x) + off) * 4 + 5] - -odst[((y * linesize + x) + off) * 4 + 1]; +odst[((y * linesize + x) + off - z) * 4 + 5] - +odst[((y * linesize + x) + off - z) * 4 + 1]; b = odst[(ly * linesize + lx) * 4 + 2] + -odst[((y * linesize + x) + off) * 4 + 6] - -odst[((y * linesize + x) + off) * 4 + 2]; +odst[((y * linesize + x) + off - z) * 4 + 6] - +odst[((y * linesize + x) + off - z) * 4 + 2]; clr = ((b & 0xFF) << 16) + ((g & 0xFF) << 8) + (r & 0xFF); dst[y * linesize + x] = clr; lx = x; @@ -449,10 +457,17 @@ static int decompress_i(AVCodecContext *avctx, uint32_t *dst, int linesize) break; case 5: while (run-- > 0) { -if (y < 1 || y >= avctx->height) +if (y < 1 || y >= avctx->height || +(y == 1 && x == 0)) return AVERROR_INVALIDDATA; -clr = dst[y * linesize + x + off]; +if (x == 0) { +z = backstep; +} else { +z = 0; +} + +clr = dst[y * linesize + x + off - z]; dst[y * linesize + x] = clr; lx = x; ly = y; ___ ffmpeg-cvslog mailing list ffmpeg-cvslog@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-cvslog
[FFmpeg-cvslog] avcodec/vp3: Do not return random positive values but the buf size
ffmpeg | branch: master | Michael Niedermayer | Thu Dec 15 21:08:48 2016 +0100| [d8094a303ba36344015a44d629bafc6d7094b4ac] | committer: Michael Niedermayer avcodec/vp3: Do not return random positive values but the buf size Signed-off-by: Michael Niedermayer > http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=d8094a303ba36344015a44d629bafc6d7094b4ac --- libavcodec/vp3.c | 6 -- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/libavcodec/vp3.c b/libavcodec/vp3.c index fa749be..86e5852 100644 --- a/libavcodec/vp3.c +++ b/libavcodec/vp3.c @@ -2022,8 +2022,9 @@ static int vp3_decode_frame(AVCodecContext *avctx, ret = vp3_decode_init(avctx); if (ret < 0) { vp3_decode_end(avctx); +return ret; } -return ret; +return buf_size; } else if (type == 2) { vp3_decode_end(avctx); ret = theora_decode_tables(avctx, &gb); @@ -2031,8 +2032,9 @@ static int vp3_decode_frame(AVCodecContext *avctx, ret = vp3_decode_init(avctx); if (ret < 0) { vp3_decode_end(avctx); +return ret; } -return ret; +return buf_size; } av_log(avctx, AV_LOG_ERROR, ___ ffmpeg-cvslog mailing list ffmpeg-cvslog@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-cvslog
[FFmpeg-cvslog] omx: Add support for specifying H.264 profile [v5']
ffmpeg | branch: master | Takayuki 'January June' Suwa | Fri Mar 3 15:17:37 2017 +0900| [13332504c98918447159da2a1a34e377dca360e2] | committer: Michael Niedermayer omx: Add support for specifying H.264 profile [v5'] This adds "-profile[:v] profile_name"-style option. Signed-off-by: Michael Niedermayer > http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=13332504c98918447159da2a1a34e377dca360e2 --- libavcodec/omx.c | 18 ++ 1 file changed, 18 insertions(+) diff --git a/libavcodec/omx.c b/libavcodec/omx.c index 16df50e..19b4f33 100644 --- a/libavcodec/omx.c +++ b/libavcodec/omx.c @@ -226,6 +226,7 @@ typedef struct OMXCodecContext { int output_buf_size; int input_zerocopy; +int profile; } OMXCodecContext; static void append_buffer(pthread_mutex_t *mutex, pthread_cond_t *cond, @@ -523,6 +524,19 @@ static av_cold int omx_component_init(AVCodecContext *avctx, const char *role) CHECK(err); avc.nBFrames = 0; avc.nPFrames = avctx->gop_size - 1; +switch (s->profile == FF_PROFILE_UNKNOWN ? avctx->profile : s->profile) { +case FF_PROFILE_H264_BASELINE: +avc.eProfile = OMX_VIDEO_AVCProfileBaseline; +break; +case FF_PROFILE_H264_MAIN: +avc.eProfile = OMX_VIDEO_AVCProfileMain; +break; +case FF_PROFILE_H264_HIGH: +avc.eProfile = OMX_VIDEO_AVCProfileHigh; +break; +default: +break; +} err = OMX_SetParameter(s->handle, OMX_IndexParamVideoAvc, &avc); CHECK(err); } @@ -884,6 +898,10 @@ static const AVOption options[] = { { "omx_libname", "OpenMAX library name", OFFSET(libname), AV_OPT_TYPE_STRING, { 0 }, 0, 0, VDE }, { "omx_libprefix", "OpenMAX library prefix", OFFSET(libprefix), AV_OPT_TYPE_STRING, { 0 }, 0, 0, VDE }, { "zerocopy", "Try to avoid copying input frames if possible", OFFSET(input_zerocopy), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 1, VE }, +{ "profile", "Set the encoding profile", OFFSET(profile), AV_OPT_TYPE_INT, { .i64 = FF_PROFILE_UNKNOWN }, FF_PROFILE_UNKNOWN, FF_PROFILE_H264_HIGH, VE, "profile" }, +{ "baseline", "", 0, AV_OPT_TYPE_CONST, { .i64 = FF_PROFILE_H264_BASELINE }, 0, 0, VE, "profile" }, +{ "main", "", 0, AV_OPT_TYPE_CONST, { .i64 = FF_PROFILE_H264_MAIN }, 0, 0, VE, "profile" }, +{ "high", "", 0, AV_OPT_TYPE_CONST, { .i64 = FF_PROFILE_H264_HIGH }, 0, 0, VE, "profile" }, { NULL } }; ___ ffmpeg-cvslog mailing list ffmpeg-cvslog@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-cvslog
[FFmpeg-cvslog] avutil/md5: fix misaligned reads
ffmpeg | branch: master | James Almer | Fri Mar 3 00:25:54 2017 -0300| [e2b7ae4b198c1dc001b3b28476608eaf4daf726c] | committer: James Almer avutil/md5: fix misaligned reads This makes ubsan happy and also considerably increases performance on big endian systems. Tested on an IBM POWER7 3.55 GHz Before: 2.24user 0.14system 0:02.39elapsed 99%CPU (0avgtext+0avgdata 2624maxresident)k 2.26user 0.11system 0:02.38elapsed 99%CPU (0avgtext+0avgdata 2688maxresident)k 2.23user 0.15system 0:02.38elapsed 99%CPU (0avgtext+0avgdata 2624maxresident)k 2.25user 0.12system 0:02.38elapsed 100%CPU (0avgtext+0avgdata 2624maxresident)k 2.20user 0.15system 0:02.36elapsed 99%CPU (0avgtext+0avgdata 2624maxresident)k After: 1.86user 0.13system 0:02.00elapsed 99%CPU (0avgtext+0avgdata 2624maxresident)k 1.89user 0.11system 0:02.01elapsed 99%CPU (0avgtext+0avgdata 2624maxresident)k 1.85user 0.14system 0:02.00elapsed 99%CPU (0avgtext+0avgdata 2624maxresident)k 1.84user 0.15system 0:01.99elapsed 99%CPU (0avgtext+0avgdata 2624maxresident)k 1.89user 0.13system 0:02.02elapsed 99%CPU (0avgtext+0avgdata 2688maxresident)k Tested-by: Nicolas George Reviewed-by: Michael Niedermayer Signed-off-by: James Almer > http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=e2b7ae4b198c1dc001b3b28476608eaf4daf726c --- libavutil/md5.c | 15 +-- 1 file changed, 5 insertions(+), 10 deletions(-) diff --git a/libavutil/md5.c b/libavutil/md5.c index 8c36aa8..d3698dc 100644 --- a/libavutil/md5.c +++ b/libavutil/md5.c @@ -86,14 +86,14 @@ static const uint32_t T[64] = { // T[i]= fabs(sin(i+1)<<32) \ if (i < 32) { \ if (i < 16) \ -a += (d ^ (b & (c ^ d))) + X[ i & 15]; \ +a += (d ^ (b & (c ^ d))) + AV_RL32(X+( i & 15));\ else\ -a += ((d & b) | (~d & c)) + X[(1 + 5*i) & 15]; \ +a += ((d & b) | (~d & c)) + AV_RL32(X+((1 + 5*i) & 15));\ } else {\ if (i < 48) \ -a += (b ^ c ^ d) + X[(5 + 3*i) & 15]; \ +a += (b ^ c ^ d) + AV_RL32(X+((5 + 3*i) & 15));\ else\ -a += (c ^ (b | ~d)) + X[(7*i) & 15]; \ +a += (c ^ (b | ~d)) + AV_RL32(X+((7*i) & 15));\ } \ a = b + (a << t | a >> (32 - t)); \ } while (0) @@ -112,11 +112,6 @@ static void body(uint32_t ABCD[4], uint32_t *src, int nblocks) X = src + n * 16; -#if HAVE_BIGENDIAN -for (i = 0; i < 16; i++) -X[i] = av_bswap32(X[i]); -#endif - #if CONFIG_SMALL for (i = 0; i < 64; i++) { CORE(i, a, b, c, d); @@ -173,7 +168,7 @@ void av_md5_update(AVMD5 *ctx, const uint8_t *src, int len) } end = src + (len & ~63); -if (HAVE_BIGENDIAN || (!HAVE_FAST_UNALIGNED && ((intptr_t)src & 3))) { +if (!HAVE_FAST_UNALIGNED && ((intptr_t)src & 3)) { while (src < end) { memcpy(ctx->block, src, 64); body(ctx->ABCD, (uint32_t *) ctx->block, 1); ___ ffmpeg-cvslog mailing list ffmpeg-cvslog@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-cvslog
[FFmpeg-cvslog] avutil/md5: stop discarding the const qualifier for the src pointer
ffmpeg | branch: master | James Almer | Fri Mar 3 00:27:52 2017 -0300| [a43389547c51b857451cd47d0a1484382c78af37] | committer: James Almer avutil/md5: stop discarding the const qualifier for the src pointer The code modifying the buffer on big endian systems was removed. Reviewed-by: Michael Niedermayer Signed-off-by: James Almer > http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=a43389547c51b857451cd47d0a1484382c78af37 --- libavutil/md5.c | 13 +++-- 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/libavutil/md5.c b/libavutil/md5.c index d3698dc..1069ef1 100644 --- a/libavutil/md5.c +++ b/libavutil/md5.c @@ -98,11 +98,12 @@ static const uint32_t T[64] = { // T[i]= fabs(sin(i+1)<<32) a = b + (a << t | a >> (32 - t)); \ } while (0) -static void body(uint32_t ABCD[4], uint32_t *src, int nblocks) +static void body(uint32_t ABCD[4], const uint8_t *src, int nblocks) { int i av_unused; int n; -uint32_t a, b, c, d, t, *X; +const uint32_t *X; +uint32_t a, b, c, d, t; for (n = 0; n < nblocks; n++) { a = ABCD[3]; @@ -110,7 +111,7 @@ static void body(uint32_t ABCD[4], uint32_t *src, int nblocks) c = ABCD[1]; d = ABCD[0]; -X = src + n * 16; +X = (const uint32_t *)src + n * 16; #if CONFIG_SMALL for (i = 0; i < 64; i++) { @@ -164,19 +165,19 @@ void av_md5_update(AVMD5 *ctx, const uint8_t *src, int len) len -= cnt; if (j + cnt < 64) return; -body(ctx->ABCD, (uint32_t *)ctx->block, 1); +body(ctx->ABCD, ctx->block, 1); } end = src + (len & ~63); if (!HAVE_FAST_UNALIGNED && ((intptr_t)src & 3)) { while (src < end) { memcpy(ctx->block, src, 64); - body(ctx->ABCD, (uint32_t *) ctx->block, 1); + body(ctx->ABCD, ctx->block, 1); src += 64; } } else { int nblocks = len / 64; -body(ctx->ABCD, (uint32_t *)src, nblocks); +body(ctx->ABCD, src, nblocks); src = end; } len &= 63; ___ ffmpeg-cvslog mailing list ffmpeg-cvslog@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-cvslog
[FFmpeg-cvslog] doc/encoders: mention valid values for compression_level when using FLAC encoder
ffmpeg | branch: master | James Almer | Fri Mar 3 13:49:14 2017 -0300| [68ee800a9dd9808d6b5c8b52963cd19cfdd4753e] | committer: James Almer doc/encoders: mention valid values for compression_level when using FLAC encoder Found-by: Miles Signed-off-by: James Almer > http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=68ee800a9dd9808d6b5c8b52963cd19cfdd4753e --- doc/encoders.texi | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/doc/encoders.texi b/doc/encoders.texi index 430f9f8..594c612 100644 --- a/doc/encoders.texi +++ b/doc/encoders.texi @@ -549,7 +549,8 @@ The following options are supported by FFmpeg's flac encoder. @table @option @item compression_level Sets the compression level, which chooses defaults for many other options -if they are not set explicitly. +if they are not set explicitly. Valid values are from 0 to 12, 5 is the +default. @item frame_size Sets the size of the frames in samples per channel. ___ ffmpeg-cvslog mailing list ffmpeg-cvslog@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-cvslog
[FFmpeg-cvslog] avformat/hlsenc: move the segment files handler close to before temp flags process
ffmpeg | branch: master | Steven Liu | Sat Mar 4 09:27:56 2017 +0800| [4507f29e4a6a4363e0179c02bdb78d55e4d9a12c] | committer: Steven Liu avformat/hlsenc: move the segment files handler close to before temp flags process fix ticket: #6204 Signed-off-by: Steven Liu > http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=4507f29e4a6a4363e0179c02bdb78d55e4d9a12c --- libavformat/hlsenc.c | 7 --- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/libavformat/hlsenc.c b/libavformat/hlsenc.c index 9cf6211..b8122f1 100644 --- a/libavformat/hlsenc.c +++ b/libavformat/hlsenc.c @@ -1329,13 +1329,14 @@ static int hls_write_packet(AVFormatContext *s, AVPacket *pkt) new_start_pos = avio_tell(hls->avf->pb); hls->size = new_start_pos - hls->start_pos; +ff_format_io_close(s, &oc->pb); +if (hls->vtt_avf) { +ff_format_io_close(s, &hls->vtt_avf->pb); +} if ((hls->flags & HLS_TEMP_FILE) && oc->filename[0]) { if (!(hls->flags & HLS_SINGLE_FILE) || (hls->max_seg_size <= 0)) if (hls->avf->oformat->priv_class && hls->avf->priv_data) av_opt_set(hls->avf->priv_data, "mpegts_flags", "resend_headers", 0); -ff_format_io_close(s, &oc->pb); -if (hls->vtt_avf) -ff_format_io_close(s, &hls->vtt_avf->pb); hls_rename_temp_file(s, oc); } ___ ffmpeg-cvslog mailing list ffmpeg-cvslog@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-cvslog
[FFmpeg-cvslog] avcodec/mpeg4videodec: Improve the overflow checks in mpeg4_decode_sprite_trajectory()
ffmpeg | branch: master | Michael Niedermayer | Thu Mar 2 03:02:07 2017 +0100| [eb41956636fc264fe2077b78ef00591d83bbbace] | committer: Michael Niedermayer avcodec/mpeg4videodec: Improve the overflow checks in mpeg4_decode_sprite_trajectory() Also clear the state on errors Fixes integer overflows in 701/clusterfuzz-testcase-6594719951880192 Found-by: continuous fuzzing process https://github.com/google/oss-fuzz/tree/master/targets/ffmpeg Signed-off-by: Michael Niedermayer > http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=eb41956636fc264fe2077b78ef00591d83bbbace --- libavcodec/mpeg4videodec.c | 16 +++- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/libavcodec/mpeg4videodec.c b/libavcodec/mpeg4videodec.c index 9f9374d..568263e 100644 --- a/libavcodec/mpeg4videodec.c +++ b/libavcodec/mpeg4videodec.c @@ -375,7 +375,7 @@ static int mpeg4_decode_sprite_trajectory(Mpeg4DecContext *ctx, GetBitContext *g FFABS(s->sprite_offset[1][1]) >= INT_MAX >> shift_c ) { avpriv_request_sample(s->avctx, "Too large sprite shift or offset"); -return AVERROR_PATCHWELCOME; +goto overflow; } for (i = 0; i < 2; i++) { @@ -385,17 +385,23 @@ static int mpeg4_decode_sprite_trajectory(Mpeg4DecContext *ctx, GetBitContext *g s->sprite_delta[1][i] *= 1 << shift_y; ctx->sprite_shift[i] = 16; -if (llabs(s->sprite_offset[i][0] + s->sprite_delta[i][0] * (int64_t)w) >= INT_MAX || -llabs(s->sprite_offset[i][0] + s->sprite_delta[i][1] * (int64_t)h) >= INT_MAX || -llabs(s->sprite_offset[i][0] + s->sprite_delta[i][0] * (int64_t)w + s->sprite_delta[i][1] * (int64_t)h) >= INT_MAX) { +} +for (i = 0; i < 2; i++) { +if (llabs(s->sprite_offset[0][i] + s->sprite_delta[i][0] * (w+16LL)) >= INT_MAX || +llabs(s->sprite_offset[0][i] + s->sprite_delta[i][1] * (h+16LL)) >= INT_MAX || +llabs(s->sprite_offset[0][i] + s->sprite_delta[i][0] * (w+16LL) + s->sprite_delta[i][1] * (h+16LL)) >= INT_MAX) { avpriv_request_sample(s->avctx, "Overflow on sprite points"); -return AVERROR_PATCHWELCOME; +goto overflow; } } s->real_sprite_warping_points = ctx->num_sprite_warping_points; } return 0; +overflow: +memset(s->sprite_offset, 0, sizeof(s->sprite_offset)); +memset(s->sprite_delta, 0, sizeof(s->sprite_delta)); +return AVERROR_PATCHWELCOME; } static int decode_new_pred(Mpeg4DecContext *ctx, GetBitContext *gb) { ___ ffmpeg-cvslog mailing list ffmpeg-cvslog@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-cvslog
[FFmpeg-cvslog] avcodec/vp56: Require a correctly decoded frame before using vp56_conceal_mb()
ffmpeg | branch: master | Michael Niedermayer | Thu Mar 2 03:02:06 2017 +0100| [2ce4f28431623cdde4aa496fd10430f6c7bdef63] | committer: Michael Niedermayer avcodec/vp56: Require a correctly decoded frame before using vp56_conceal_mb() Fixes timeout with 700/clusterfuzz-testcase-5660909504561152 Fixes timeout with 702/clusterfuzz-testcase-4553541576294400 Found-by: continuous fuzzing process https://github.com/google/oss-fuzz/tree/master/targets/ffmpeg Signed-off-by: Michael Niedermayer > http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=2ce4f28431623cdde4aa496fd10430f6c7bdef63 --- libavcodec/vp56.c | 14 +- libavcodec/vp56.h | 3 +++ 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/libavcodec/vp56.c b/libavcodec/vp56.c index 5ea3653..0010408 100644 --- a/libavcodec/vp56.c +++ b/libavcodec/vp56.c @@ -617,8 +617,12 @@ int ff_vp56_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, } } +s->discard_frame = 0; avctx->execute2(avctx, ff_vp56_decode_mbs, 0, 0, (avctx->pix_fmt == AV_PIX_FMT_YUVA420P) + 1); +if (s->discard_frame) +return AVERROR_INVALIDDATA; + if ((res = av_frame_ref(data, p)) < 0) return res; *got_frame = 1; @@ -704,8 +708,13 @@ static int ff_vp56_decode_mbs(AVCodecContext *avctx, void *data, for (mb_col=0; mb_colmb_width; mb_col++) { if (!damaged) { int ret = vp56_decode_mb(s, mb_row, mb_col, is_alpha); -if (ret < 0) +if (ret < 0) { damaged = 1; +if (!s->have_undamaged_frame) { +s->discard_frame = 1; +return AVERROR_INVALIDDATA; +} +} } if (damaged) vp56_conceal_mb(s, mb_row, mb_col, is_alpha); @@ -722,6 +731,9 @@ static int ff_vp56_decode_mbs(AVCodecContext *avctx, void *data, } } +if (!damaged) +s->have_undamaged_frame = 1; + next: if (p->key_frame || s->golden_frame) { av_frame_unref(s->frames[VP56_FRAME_GOLDEN]); diff --git a/libavcodec/vp56.h b/libavcodec/vp56.h index 34d4822..e5c5bea 100644 --- a/libavcodec/vp56.h +++ b/libavcodec/vp56.h @@ -203,6 +203,9 @@ struct vp56_context { VLC runv_vlc[2]; VLC ract_vlc[2][3][6]; unsigned int nb_null[2][2]; /* number of consecutive NULL DC/AC */ + +int have_undamaged_frame; +int discard_frame; }; ___ ffmpeg-cvslog mailing list ffmpeg-cvslog@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-cvslog