[FFmpeg-cvslog] avcodec/cuvid: set width and height before calling get_format
ffmpeg | branch: master | Timo Rothenpieler | Tue Feb 14 11:47:08 2017 +0100| [ce79410bba776d4121685654056f2b4e39bbd3f7] | committer: Timo Rothenpieler avcodec/cuvid: set width and height before calling get_format The external hw_frames_ctx is initialized in that callback, and needs that information to be accurate. > http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=ce79410bba776d4121685654056f2b4e39bbd3f7 --- libavcodec/cuvid.c | 7 --- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/libavcodec/cuvid.c b/libavcodec/cuvid.c index 2a305ab..5e6e716 100644 --- a/libavcodec/cuvid.c +++ b/libavcodec/cuvid.c @@ -113,6 +113,10 @@ static int CUDAAPI cuvid_handle_video_sequence(void *opaque, CUVIDEOFORMAT* form ctx->internal_error = 0; +// width and height need to be set before calling ff_get_format +avctx->width = format->display_area.right; +avctx->height = format->display_area.bottom; + switch (format->bit_depth_luma_minus8) { case 0: // 8-bit pix_fmts[1] = AV_PIX_FMT_NV12; @@ -156,9 +160,6 @@ static int CUDAAPI cuvid_handle_video_sequence(void *opaque, CUVIDEOFORMAT* form hwframe_ctx = (AVHWFramesContext*)ctx->hwframe->data; } -avctx->width = format->display_area.right; -avctx->height = format->display_area.bottom; - ff_set_sar(avctx, av_div_q( (AVRational){ format->display_aspect_ratio.x, format->display_aspect_ratio.y }, (AVRational){ avctx->width, avctx->height })); ___ ffmpeg-cvslog mailing list ffmpeg-cvslog@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-cvslog
[FFmpeg-cvslog] avcodec/cuvid: add format mismatch debug logs
ffmpeg | branch: master | Timo Rothenpieler | Thu Feb 9 22:19:59 2017 +0100| [b6f4f0b14b0f8c00d7d1dec1d1f03d82b85dd617] | committer: Timo Rothenpieler avcodec/cuvid: add format mismatch debug logs > http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=b6f4f0b14b0f8c00d7d1dec1d1f03d82b85dd617 --- libavcodec/cuvid.c | 5 + 1 file changed, 5 insertions(+) diff --git a/libavcodec/cuvid.c b/libavcodec/cuvid.c index 5e6e716..f5a49ce 100644 --- a/libavcodec/cuvid.c +++ b/libavcodec/cuvid.c @@ -207,6 +207,11 @@ static int CUDAAPI cuvid_handle_video_sequence(void *opaque, CUVIDEOFORMAT* form hwframe_ctx->format != AV_PIX_FMT_CUDA || hwframe_ctx->sw_format != avctx->sw_pix_fmt)) { av_log(avctx, AV_LOG_ERROR, "AVHWFramesContext is already initialized with incompatible parameters\n"); +av_log(avctx, AV_LOG_DEBUG, "width: %d <-> %d\n", hwframe_ctx->width, avctx->width); +av_log(avctx, AV_LOG_DEBUG, "height: %d <-> %d\n", hwframe_ctx->height, avctx->height); +av_log(avctx, AV_LOG_DEBUG, "format: %s <-> cuda\n", av_get_pix_fmt_name(hwframe_ctx->format)); +av_log(avctx, AV_LOG_DEBUG, "sw_format: %s <-> %s\n", + av_get_pix_fmt_name(hwframe_ctx->sw_format), av_get_pix_fmt_name(avctx->sw_pix_fmt)); ctx->internal_error = AVERROR(EINVAL); return 0; } ___ ffmpeg-cvslog mailing list ffmpeg-cvslog@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-cvslog
[FFmpeg-cvslog] avcodec/cuvid: update hw_frames_ctx reference after get_format call
ffmpeg | branch: master | Timo Rothenpieler | Thu Feb 9 22:29:47 2017 +0100| [b7d480f4312c5ce7d8ce2f6eb7189f0d96ad5bde] | committer: Timo Rothenpieler avcodec/cuvid: update hw_frames_ctx reference after get_format call > http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=b7d480f4312c5ce7d8ce2f6eb7189f0d96ad5bde --- libavcodec/cuvid.c | 13 + 1 file changed, 13 insertions(+) diff --git a/libavcodec/cuvid.c b/libavcodec/cuvid.c index 9b35476..2a305ab 100644 --- a/libavcodec/cuvid.c +++ b/libavcodec/cuvid.c @@ -143,6 +143,19 @@ static int CUDAAPI cuvid_handle_video_sequence(void *opaque, CUVIDEOFORMAT* form avctx->pix_fmt = surface_fmt; +// Update our hwframe ctx, as the get_format callback might have refreshed it! +if (avctx->hw_frames_ctx) { +av_buffer_unref(&ctx->hwframe); + +ctx->hwframe = av_buffer_ref(avctx->hw_frames_ctx); +if (!ctx->hwframe) { +ctx->internal_error = AVERROR(ENOMEM); +return 0; +} + +hwframe_ctx = (AVHWFramesContext*)ctx->hwframe->data; +} + avctx->width = format->display_area.right; avctx->height = format->display_area.bottom; ___ ffmpeg-cvslog mailing list ffmpeg-cvslog@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-cvslog
[FFmpeg-cvslog] avcodec/nvenc: push cuda context before encoding a frame
ffmpeg | branch: master | Timo Rothenpieler | Mon Feb 13 22:59:46 2017 +0100| [be74ba648cf4063c9805ebe95ee83fd7299f7fd5] | committer: Timo Rothenpieler avcodec/nvenc: push cuda context before encoding a frame Thanks to Miroslav Slugeň for figuring out what was going on here. > http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=be74ba648cf4063c9805ebe95ee83fd7299f7fd5 --- libavcodec/nvenc.c | 28 1 file changed, 28 insertions(+) diff --git a/libavcodec/nvenc.c b/libavcodec/nvenc.c index 51e794e..ba2647b 100644 --- a/libavcodec/nvenc.c +++ b/libavcodec/nvenc.c @@ -1649,6 +1649,8 @@ int ff_nvenc_encode_frame(AVCodecContext *avctx, AVPacket *pkt, const AVFrame *frame, int *got_packet) { NVENCSTATUS nv_status; +CUresult cu_res; +CUcontext dummy; NvencSurface *tmpoutsurf, *inSurf; int res; @@ -1666,7 +1668,20 @@ int ff_nvenc_encode_frame(AVCodecContext *avctx, AVPacket *pkt, return AVERROR_BUG; } +cu_res = dl_fn->cuda_dl->cuCtxPushCurrent(ctx->cu_context); +if (cu_res != CUDA_SUCCESS) { +av_log(avctx, AV_LOG_ERROR, "cuCtxPushCurrent failed\n"); +return AVERROR_EXTERNAL; +} + res = nvenc_upload_frame(avctx, frame, inSurf); + +cu_res = dl_fn->cuda_dl->cuCtxPopCurrent(&dummy); +if (cu_res != CUDA_SUCCESS) { +av_log(avctx, AV_LOG_ERROR, "cuCtxPopCurrent failed\n"); +return AVERROR_EXTERNAL; +} + if (res) { inSurf->lockCount = 0; return res; @@ -1702,7 +1717,20 @@ int ff_nvenc_encode_frame(AVCodecContext *avctx, AVPacket *pkt, pic_params.encodePicFlags = NV_ENC_PIC_FLAG_EOS; } +cu_res = dl_fn->cuda_dl->cuCtxPushCurrent(ctx->cu_context); +if (cu_res != CUDA_SUCCESS) { +av_log(avctx, AV_LOG_ERROR, "cuCtxPushCurrent failed\n"); +return AVERROR_EXTERNAL; +} + nv_status = p_nvenc->nvEncEncodePicture(ctx->nvencoder, &pic_params); + +cu_res = dl_fn->cuda_dl->cuCtxPopCurrent(&dummy); +if (cu_res != CUDA_SUCCESS) { +av_log(avctx, AV_LOG_ERROR, "cuCtxPopCurrent failed\n"); +return AVERROR_EXTERNAL; +} + if (nv_status != NV_ENC_SUCCESS && nv_status != NV_ENC_ERR_NEED_MORE_INPUT) return nvenc_print_error(avctx, nv_status, "EncodePicture failed!"); ___ ffmpeg-cvslog mailing list ffmpeg-cvslog@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-cvslog
[FFmpeg-cvslog] HTTP: improve performance by reducing forward seeks
ffmpeg | branch: master | Joel Cunningham | Mon Jan 30 10:00:44 2017 -0600| [8c8e5d5286bf598a89ef9993a2cf6ea409d03a32] | committer: Michael Niedermayer HTTP: improve performance by reducing forward seeks This commit optimizes HTTP performance by reducing forward seeks, instead favoring a read-ahead and discard on the current connection (referred to as a short seek) for seeks that are within a TCP window's worth of data. This improves performance because with TCP flow control, a window's worth of data will be in the local socket buffer already or in-flight from the sender once congestion control on the sender is fully utilizing the window. Note: this approach doesn't attempt to differentiate from a newly opened connection which may not be fully utilizing the window due to congestion control vs one that is. The receiver can't get at this information, so we assume worst case; that full window is in use (we did advertise it after all) and that data could be in-flight The previous behavior of closing the connection, then opening a new with a new HTTP range value results in a massive amounts of discarded and re-sent data when large TCP windows are used. This has been observed on MacOS/iOS which starts with an initial window of 256KB and grows up to 1MB depending on the bandwidth-product delay. When seeking within a window's worth of data and we close the connection, then open a new one within the same window's worth of data, we discard from the current offset till the end of the window. Then on the new connection the server ends up re-sending the previous data from new offset till the end of old window. Example (assumes full window utilization): TCP window size: 64KB Position: 32KB Forward seek position: 40KB * (Next window) 32KB |--| 96KB |---| 160KB * 40KB |---| 104KB Re-sent amount: 96KB - 40KB = 56KB For a real world test example, I have MP4 file of ~25MB, which ffplay only reads ~16MB and performs 177 seeks. With current ffmpeg, this results in 177 HTTP GETs and ~73MB worth of TCP data communication. With this patch, ffmpeg issues 4 HTTP GETs and 3 seeks for a total of ~22MB of TCP data communication. To support this feature, the short seek logic in avio_seek() has been extended to call a function to get the short seek threshold value. This callback has been plumbed to the URLProtocol structure, which now has infrastructure in HTTP and TCP to get the underlying receiver window size via SO_RCVBUF. If the underlying URL and protocol don't support returning a short seek threshold, the default s->short_seek_threshold is used This feature has been tested on Windows 7 and MacOS/iOS. Windows support is slightly complicated by the fact that when TCP window auto-tuning is enabled, SO_RCVBUF doesn't report the real window size, but it does if SO_RCVBUF was manually set (disabling auto-tuning). So we can only use this optimization on Windows in the later case Signed-off-by: Joel Cunningham Signed-off-by: Michael Niedermayer > http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=8c8e5d5286bf598a89ef9993a2cf6ea409d03a32 --- libavformat/avio.c| 7 +++ libavformat/avio.h| 6 ++ libavformat/aviobuf.c | 19 ++- libavformat/http.c| 8 libavformat/tcp.c | 21 + libavformat/url.h | 8 6 files changed, 68 insertions(+), 1 deletion(-) diff --git a/libavformat/avio.c b/libavformat/avio.c index 3606eb0..62233a6 100644 --- a/libavformat/avio.c +++ b/libavformat/avio.c @@ -645,6 +645,13 @@ int ffurl_get_multi_file_handle(URLContext *h, int **handles, int *numhandles) return h->prot->url_get_multi_file_handle(h, handles, numhandles); } +int ffurl_get_short_seek(URLContext *h) +{ +if (!h->prot->url_get_short_seek) +return AVERROR(ENOSYS); +return h->prot->url_get_short_seek(h); +} + int ffurl_shutdown(URLContext *h, int flags) { if (!h->prot->url_shutdown) diff --git a/libavformat/avio.h b/libavformat/avio.h index e2cb4af..8040094 100644 --- a/libavformat/avio.h +++ b/libavformat/avio.h @@ -313,6 +313,12 @@ typedef struct AVIOContext { */ enum AVIODataMarkerType current_type; int64_t last_time; + +/** + * A callback that is used instead of short_seek_threshold. + * This is current internal only, do not use from outside. + */ +int (*short_seek_get)(void *opaque); } AVIOContext; /** diff --git a/libavformat/aviobuf.c b/libavformat/aviobuf.c index bf7e5f8..4ade4d0 100644 --- a/libavformat/aviobuf.c +++ b/libavformat/aviobuf.c @@ -119,6 +119,7 @@ int ffio_init_context(AVIOContext *s, s->ignore_boundary_point = 0; s->current_type = AVIO_DATA_MARKER_UNKNOWN; s->last_time = AV_NOPTS_VALUE; +s->short_seek_get= NULL; return 0; } @@ -233,6 +234,7 @@ int64_t avio_seek(AVIOContext *s, int64_t offset, int whence) int64_t pos;
[FFmpeg-cvslog] avcodec/hevc_parser: export framerate, remove one dependency on the decoder
ffmpeg | branch: master | Michael Niedermayer | Tue Feb 14 16:33:53 2017 +0100| [db3507a670aec46fd5ed58c90d2927eb7f72d8ed] | committer: Michael Niedermayer avcodec/hevc_parser: export framerate, remove one dependency on the decoder Fixes Ticket6090 Signed-off-by: Michael Niedermayer > http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=db3507a670aec46fd5ed58c90d2927eb7f72d8ed --- libavcodec/hevc_parser.c | 13 + 1 file changed, 13 insertions(+) diff --git a/libavcodec/hevc_parser.c b/libavcodec/hevc_parser.c index 508f22f..3546048 100644 --- a/libavcodec/hevc_parser.c +++ b/libavcodec/hevc_parser.c @@ -230,6 +230,7 @@ static inline int parse_nal_units(AVCodecParserContext *s, const uint8_t *buf, for (;;) { int src_length, consumed; int ret; +int num = 0, den = 0; buf = avpriv_find_start_code(buf, buf_end, &state); if (--buf + 2 >= buf_end) break; @@ -320,6 +321,18 @@ static inline int parse_nal_units(AVCodecParserContext *s, const uint8_t *buf, avctx->profile = ps->sps->ptl.general_ptl.profile_idc; avctx->level= ps->sps->ptl.general_ptl.level_idc; +if (ps->vps->vps_timing_info_present_flag) { +num = ps->vps->vps_num_units_in_tick; +den = ps->vps->vps_time_scale; +} else if (ps->sps->vui.vui_timing_info_present_flag) { +num = ps->sps->vui.vui_num_units_in_tick; +den = ps->sps->vui.vui_time_scale; +} + +if (num != 0 && den != 0) +av_reduce(&avctx->framerate.den, &avctx->framerate.num, + num, den, 1 << 30); + if (!sh->first_slice_in_pic_flag) { int slice_address_length; ___ ffmpeg-cvslog mailing list ffmpeg-cvslog@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-cvslog
[FFmpeg-cvslog] avformat/dashenc: Only use temporary files when outputting to file protocol
ffmpeg | branch: master | Thomas Stephens | Tue Feb 7 14:20:32 2017 -0600| [5fe2b437023f46394dfd4a4c991aa4a3ac3d8e72] | committer: Michael Niedermayer avformat/dashenc: Only use temporary files when outputting to file protocol Skips using temporary files when outputting to a protocol other than "file", which enables dash to output content over network protocols. The logic has been copied from the HLS format. Reviewed-by: Steven Liu Signed-off-by: Michael Niedermayer > http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=5fe2b437023f46394dfd4a4c991aa4a3ac3d8e72 --- libavformat/dashenc.c | 29 +++-- 1 file changed, 23 insertions(+), 6 deletions(-) diff --git a/libavformat/dashenc.c b/libavformat/dashenc.c index 534fa75..fa56505 100644 --- a/libavformat/dashenc.c +++ b/libavformat/dashenc.c @@ -444,9 +444,15 @@ static int write_manifest(AVFormatContext *s, int final) AVIOContext *out; char temp_filename[1024]; int ret, i; +const char *proto = avio_find_protocol_name(s->filename); +int use_rename = proto && !strcmp(proto, "file"); +static unsigned int warned_non_file = 0; AVDictionaryEntry *title = av_dict_get(s->metadata, "title", NULL, 0); -snprintf(temp_filename, sizeof(temp_filename), "%s.tmp", s->filename); +if (!use_rename && !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"); + +snprintf(temp_filename, sizeof(temp_filename), use_rename ? "%s.tmp" : "%s", s->filename); ret = s->io_open(s, &out, temp_filename, AVIO_FLAG_WRITE, NULL); if (ret < 0) { av_log(s, AV_LOG_ERROR, "Unable to open %s for writing\n", temp_filename); @@ -548,7 +554,11 @@ static int write_manifest(AVFormatContext *s, int final) avio_printf(out, "\n"); avio_flush(out); ff_format_io_close(s, &out); -return avpriv_io_move(temp_filename, s->filename); + +if (use_rename) +return avpriv_io_move(temp_filename, s->filename); + +return 0; } static int dash_init(AVFormatContext *s) @@ -796,6 +806,10 @@ static int dash_flush(AVFormatContext *s, int final, int stream) { DASHContext *c = s->priv_data; int i, ret = 0; + +const char *proto = avio_find_protocol_name(s->filename); +int use_rename = proto && !strcmp(proto, "file"); + int cur_flush_segment_index = 0; if (stream >= 0) cur_flush_segment_index = c->streams[stream].segment_index; @@ -833,7 +847,7 @@ static int dash_flush(AVFormatContext *s, int final, int stream) if (!c->single_file) { dash_fill_tmpl_params(filename, sizeof(filename), c->media_seg_name, i, os->segment_index, os->bit_rate, os->start_pts); snprintf(full_path, sizeof(full_path), "%s%s", c->dirname, filename); -snprintf(temp_path, sizeof(temp_path), "%s.tmp", full_path); +snprintf(temp_path, sizeof(temp_path), use_rename ? "%s.tmp" : "%s", full_path); ret = s->io_open(s, &os->out, temp_path, AVIO_FLAG_WRITE, NULL); if (ret < 0) break; @@ -851,9 +865,12 @@ static int dash_flush(AVFormatContext *s, int final, int stream) find_index_range(s, full_path, start_pos, &index_length); } else { ff_format_io_close(s, &os->out); -ret = avpriv_io_move(temp_path, full_path); -if (ret < 0) -break; + +if (use_rename) { +ret = avpriv_io_move(temp_path, full_path); +if (ret < 0) +break; +} } add_segment(os, filename, os->start_pts, os->max_pts - os->start_pts, start_pos, range_length, index_length); av_log(s, AV_LOG_VERBOSE, "Representation %d media segment %d written to: %s\n", i, os->segment_index, full_path); ___ ffmpeg-cvslog mailing list ffmpeg-cvslog@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-cvslog
[FFmpeg-cvslog] avcodec/h264_sei: Check actual presence of SEI picture timing instead of implying it
ffmpeg | branch: master | Michael Niedermayer | Tue Feb 14 23:45:01 2017 +0100| [6a37abc59af4d87d4c55f7d812ac62d4d6a7464b] | committer: Michael Niedermayer avcodec/h264_sei: Check actual presence of SEI picture timing instead of implying it Signed-off-by: Michael Niedermayer > http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=6a37abc59af4d87d4c55f7d812ac62d4d6a7464b --- libavcodec/h264_parser.c | 4 ++-- libavcodec/h264_sei.c| 3 +++ libavcodec/h264_sei.h| 1 + libavcodec/h264_slice.c | 4 ++-- 4 files changed, 8 insertions(+), 4 deletions(-) diff --git a/libavcodec/h264_parser.c b/libavcodec/h264_parser.c index bca0071..bc35a61 100644 --- a/libavcodec/h264_parser.c +++ b/libavcodec/h264_parser.c @@ -471,7 +471,7 @@ static inline int parse_nal_units(AVCodecParserContext *s, } } -if (sps->pic_struct_present_flag) { +if (sps->pic_struct_present_flag && p->sei.picture_timing.present) { switch (p->sei.picture_timing.pic_struct) { case SEI_PIC_STRUCT_TOP_FIELD: case SEI_PIC_STRUCT_BOTTOM_FIELD: @@ -502,7 +502,7 @@ static inline int parse_nal_units(AVCodecParserContext *s, if (p->picture_structure == PICT_FRAME) { s->picture_structure = AV_PICTURE_STRUCTURE_FRAME; -if (sps->pic_struct_present_flag) { +if (sps->pic_struct_present_flag && p->sei.picture_timing.present) { switch (p->sei.picture_timing.pic_struct) { case SEI_PIC_STRUCT_TOP_BOTTOM: case SEI_PIC_STRUCT_TOP_BOTTOM_TOP: diff --git a/libavcodec/h264_sei.c b/libavcodec/h264_sei.c index 5053962..a7e627e 100644 --- a/libavcodec/h264_sei.c +++ b/libavcodec/h264_sei.c @@ -45,6 +45,7 @@ void ff_h264_sei_uninit(H264SEIContext *h) h->picture_timing.dpb_output_delay = 0; h->picture_timing.cpb_removal_delay = -1; +h->picture_timing.present = 0; h->buffering_period.present= 0; h->frame_packing.present = 0; h->display_orientation.present = 0; @@ -119,6 +120,8 @@ static int decode_picture_timing(H264SEIPictureTiming *h, GetBitContext *gb, av_log(logctx, AV_LOG_DEBUG, "ct_type:%X pic_struct:%d\n", h->ct_type, h->pic_struct); } + +h->present = 1; return 0; } diff --git a/libavcodec/h264_sei.h b/libavcodec/h264_sei.h index 9197795..da3b391 100644 --- a/libavcodec/h264_sei.h +++ b/libavcodec/h264_sei.h @@ -64,6 +64,7 @@ typedef enum { } SEI_FpaType; typedef struct H264SEIPictureTiming { +int present; SEI_PicStructType pic_struct; /** diff --git a/libavcodec/h264_slice.c b/libavcodec/h264_slice.c index 91a3b25..a703853 100644 --- a/libavcodec/h264_slice.c +++ b/libavcodec/h264_slice.c @@ -1131,7 +1131,7 @@ static int h264_export_frame_props(H264Context *h) /* Prioritize picture timing SEI information over used * decoding process if it exists. */ -if (sps->pic_struct_present_flag) { +if (sps->pic_struct_present_flag && h->sei.picture_timing.present) { H264SEIPictureTiming *pt = &h->sei.picture_timing; switch (pt->pic_struct) { case SEI_PIC_STRUCT_FRAME: @@ -1176,7 +1176,7 @@ static int h264_export_frame_props(H264Context *h) /* Derive top_field_first from field pocs. */ cur->f->top_field_first = cur->field_poc[0] < cur->field_poc[1]; } else { -if (sps->pic_struct_present_flag) { +if (sps->pic_struct_present_flag && h->sei.picture_timing.present) { /* Use picture timing SEI information. Even if it is a * information of a past frame, better than nothing. */ if (h->sei.picture_timing.pic_struct == SEI_PIC_STRUCT_TOP_BOTTOM || ___ ffmpeg-cvslog mailing list ffmpeg-cvslog@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-cvslog